USART硬件及接收驱动的详细说明
来源:互联网 发布:上网记录查询软件 编辑:程序博客网 时间:2024/05/29 13:21
USART硬件及接收驱动的详细说明
杨晔 2003-2-16 ver0.1
2003-2-19 ver0.2
notice:以下的说明都是针对skyeye中的UART模拟部份,并不是真实的硬件,两者还是有区别的,所以如果要把skyeye的程序移植到真实的硬件上,请参考硬件手册作修改!
一、skyeye对USART所作的模拟为:
目前仅模拟了UART0(当然加上UART1也是很容易的,只要去掉一个注释),UART0的基址为0xfffd0000,下面是偏移量。
US_RPR:0x30 存放指向接收缓冲区地址的指针(注意本寄存器是只写的!!)
注意本寄存器的工作原理!:每接收一个字符,rpr会加1,即指向缓冲区的下一个位置。所以为清晰安全起见,一般在UART ISR的最后会把rpr重新设置为指向缓冲区头部。
US_RCR:0x34 存放接收缓冲区大小(1-65535),如果设为0就是停止USART的接收。
注意本寄存器的工作原理!:每接收一个字符,rcr会减1。所以在ISR中要看实际rpr指向的缓冲区中收了多少字符,就应该用rcr的预设值(如256)减去rcr的当前值得到字符个数。然后从接收缓冲读取字符。一般在UART ISR的最后会把rcr重新设为预设值如256。
US_TPR:0x38 存放指向发送缓冲区地址的指针
US_TCR:0x3c 存放发送缓冲区大小(1-65535),如果设为0就是停止USART的发送。此寄存器被写入后立即开始发送US_TPR指向的buf中的tcr个字符。(skyeye里发送就是打印)
只读寄存器:
US_CSR:0x14
USART状态寄存器。目前读该寄存器的返回值为 0B100000x01x。其中的前两个1(9位和2位上)表示USART可以发送(TXRDY),这两位在skyeye中始终为1。最后一位是接收状态,根据是否接收到数据决定。如果没有输入,最低位为0,CSR=0B1000000010;如果rcr不为0 ,则3位和0位(RXRDY)上都为1,表明接收到输入字符,也就是CSR=0B1000001011。总结起来CSR只有以上两种状态值。
但是这里引入了问题:
如果用户设置了rcr寄存器等待接收字符,但还没有输入,此时的rcr>0,那么如果读csr寄存器会发现RxRdy位也为1,即还没有输入csr的状态就成了有输入;
或者用户设置rcr寄存器为10,skyeye又接收了10个字符,此时rcr寄存器为0,读出的csr寄存器的RxRdy为0,明明有输入了但csr的状态确是无输入。
以上两个问题,说明目前不能用csr寄存器来判断UART的输入状态。
只写寄存器:
US_THR:0x1c
USART发送寄存器,写入此寄存器的字符被立即发送(在skyeye中就是打印)。
二、skyeye内部机制:
在io_do_cycle中,如果rcr>0,就会检查键盘当前有没有输入,没有立即返回。如果有输入,则根据输入字符的个数从键盘读取n个字符存放到rpr指向的内存中,rcr=rcr-n,然后raise usart 的输入中断。
三、本接收驱动的说明:
目前本驱动仅处理USART的接收部份,发送部份依然用liming原来的at91_usart.c和skyeye_printf。
驱动分为下层硬件部份serial.c和上层serialucos.c两部份。
1、下层硬件部份有三个模块:
void UART0ISR(void);
//uart0 的接收isr,负责从硬件接收缓冲区receive_buf(设定为256个字节的深度)读出接收到的字符,并放入上层的ucos环形缓冲区中。
void CommRxIntDis(INT8U ch);
//关闭usart0的接收中断
void CommRxIntEn(INT8U ch);
//初始化usart0,并打开接收中断。这里的初始化就是写rcr=256,rpr=&receive_buf[0]。
打开和关闭中断是处理的AIC中断控制器的imr寄存器,见aic部份。参数ch是指明控制usart0还是usart1,目前只处理usart0,但为了将来的扩展还是保留了一个参数。
2、上层ucos部份主要是建立了环形接收缓冲区,并使用信号量来控制接收,如下:
void CommPutRxChar (INT8U ch, INT8U c);
//由ISR调用,负责把从硬件接收到的字符放入环形缓冲区,并发出信号量唤醒等待uart输入的任务。
BOOLEAN CommIsEmpty (INT8U ch)
//检查环形缓冲区是否为空,使用这个函数可以实现轮询式uart输入。ch依然是指明控制usart0还是usart1。
void CommInit (void)
//初始化环形缓冲队列,主要是对COMM_RING_BUF结构定义的UART0BUF进行初始化。
INT8U CommGetChar (INT8U ch, INT16U time_out, INT8U *err)
//这是整个接收驱动对外界的接口。任务调用此函数,如果环形缓冲队列中有字符,立即返回该字符,如果没有,任务休眠(有timeout时间,time_out为0则永远等待),直到有字符输入发出信号量唤醒任务,或者timeout到期返回NULL。
环形缓冲区结构:
typedef struct {
INT16U RingBufRxCtr; /* Number of characters in the Rx ring buffer */
OS_EVENT *RingBufRxSem; /* Pointer to Rx semaphore */
INT8U *RingBufRxInPtr; /* Pointer to where next character will be inserted */
INT8U *RingBufRxOutPtr; /* Pointer from where next character will be extracted */
INT8U RingBufRx[COMM_RX_BUF_SIZE]; /* Ring buffer character storage (Rx) */
} COMM_RING_BUF;
杨晔 2003-2-16 ver0.1
2003-2-19 ver0.2
notice:以下的说明都是针对skyeye中的UART模拟部份,并不是真实的硬件,两者还是有区别的,所以如果要把skyeye的程序移植到真实的硬件上,请参考硬件手册作修改!
一、skyeye对USART所作的模拟为:
目前仅模拟了UART0(当然加上UART1也是很容易的,只要去掉一个注释),UART0的基址为0xfffd0000,下面是偏移量。
US_RPR:0x30 存放指向接收缓冲区地址的指针(注意本寄存器是只写的!!)
注意本寄存器的工作原理!:每接收一个字符,rpr会加1,即指向缓冲区的下一个位置。所以为清晰安全起见,一般在UART ISR的最后会把rpr重新设置为指向缓冲区头部。
US_RCR:0x34 存放接收缓冲区大小(1-65535),如果设为0就是停止USART的接收。
注意本寄存器的工作原理!:每接收一个字符,rcr会减1。所以在ISR中要看实际rpr指向的缓冲区中收了多少字符,就应该用rcr的预设值(如256)减去rcr的当前值得到字符个数。然后从接收缓冲读取字符。一般在UART ISR的最后会把rcr重新设为预设值如256。
US_TPR:0x38 存放指向发送缓冲区地址的指针
US_TCR:0x3c 存放发送缓冲区大小(1-65535),如果设为0就是停止USART的发送。此寄存器被写入后立即开始发送US_TPR指向的buf中的tcr个字符。(skyeye里发送就是打印)
只读寄存器:
US_CSR:0x14
USART状态寄存器。目前读该寄存器的返回值为 0B100000x01x。其中的前两个1(9位和2位上)表示USART可以发送(TXRDY),这两位在skyeye中始终为1。最后一位是接收状态,根据是否接收到数据决定。如果没有输入,最低位为0,CSR=0B1000000010;如果rcr不为0 ,则3位和0位(RXRDY)上都为1,表明接收到输入字符,也就是CSR=0B1000001011。总结起来CSR只有以上两种状态值。
但是这里引入了问题:
如果用户设置了rcr寄存器等待接收字符,但还没有输入,此时的rcr>0,那么如果读csr寄存器会发现RxRdy位也为1,即还没有输入csr的状态就成了有输入;
或者用户设置rcr寄存器为10,skyeye又接收了10个字符,此时rcr寄存器为0,读出的csr寄存器的RxRdy为0,明明有输入了但csr的状态确是无输入。
以上两个问题,说明目前不能用csr寄存器来判断UART的输入状态。
只写寄存器:
US_THR:0x1c
USART发送寄存器,写入此寄存器的字符被立即发送(在skyeye中就是打印)。
二、skyeye内部机制:
在io_do_cycle中,如果rcr>0,就会检查键盘当前有没有输入,没有立即返回。如果有输入,则根据输入字符的个数从键盘读取n个字符存放到rpr指向的内存中,rcr=rcr-n,然后raise usart 的输入中断。
三、本接收驱动的说明:
目前本驱动仅处理USART的接收部份,发送部份依然用liming原来的at91_usart.c和skyeye_printf。
驱动分为下层硬件部份serial.c和上层serialucos.c两部份。
1、下层硬件部份有三个模块:
void UART0ISR(void);
//uart0 的接收isr,负责从硬件接收缓冲区receive_buf(设定为256个字节的深度)读出接收到的字符,并放入上层的ucos环形缓冲区中。
void CommRxIntDis(INT8U ch);
//关闭usart0的接收中断
void CommRxIntEn(INT8U ch);
//初始化usart0,并打开接收中断。这里的初始化就是写rcr=256,rpr=&receive_buf[0]。
打开和关闭中断是处理的AIC中断控制器的imr寄存器,见aic部份。参数ch是指明控制usart0还是usart1,目前只处理usart0,但为了将来的扩展还是保留了一个参数。
2、上层ucos部份主要是建立了环形接收缓冲区,并使用信号量来控制接收,如下:
void CommPutRxChar (INT8U ch, INT8U c);
//由ISR调用,负责把从硬件接收到的字符放入环形缓冲区,并发出信号量唤醒等待uart输入的任务。
BOOLEAN CommIsEmpty (INT8U ch)
//检查环形缓冲区是否为空,使用这个函数可以实现轮询式uart输入。ch依然是指明控制usart0还是usart1。
void CommInit (void)
//初始化环形缓冲队列,主要是对COMM_RING_BUF结构定义的UART0BUF进行初始化。
INT8U CommGetChar (INT8U ch, INT16U time_out, INT8U *err)
//这是整个接收驱动对外界的接口。任务调用此函数,如果环形缓冲队列中有字符,立即返回该字符,如果没有,任务休眠(有timeout时间,time_out为0则永远等待),直到有字符输入发出信号量唤醒任务,或者timeout到期返回NULL。
环形缓冲区结构:
typedef struct {
INT16U RingBufRxCtr; /* Number of characters in the Rx ring buffer */
OS_EVENT *RingBufRxSem; /* Pointer to Rx semaphore */
INT8U *RingBufRxInPtr; /* Pointer to where next character will be inserted */
INT8U *RingBufRxOutPtr; /* Pointer from where next character will be extracted */
INT8U RingBufRx[COMM_RX_BUF_SIZE]; /* Ring buffer character storage (Rx) */
} COMM_RING_BUF;
- USART硬件及接收驱动的详细说明
- wifi模块详细说明及linux驱动
- STM32L152 USART HAL库接收任意长度数据详细解析
- Linux驱动的地址空间和硬件地址空间说明
- Linux驱动的地址空间和硬件地址空间说明
- Linux驱动的地址空间和硬件地址空间说明
- DM9000网络芯片详细说明及linux驱动
- strut2接收参数的三种方式(属性驱动\对象驱动\模型驱动)说明
- USART接收中断
- 关于stm32的usart的接收中断使能问题
- 关于USART接收中断的BUG和注意事项
- [STM32] 关于USART接收中断的BUG和注意事项
- 关于USART接收中断的BUG和注意事项
- 关于USART接收中断的BUG和注意事项
- 关于USART接收中断的BUG和注意事项
- STM32 USART 串口 DMA 接收和发送的源码详解!
- usart 串口的发送-接收数据(正点改编)
- STM32 USART 串口 DMA 接收和发送的源码详解!
- server.CreateObject( "scripting.Dictionary ") 用法
- 第10章 组合模式(Composite Pattern)
- Camparable与Comparator的区别
- 第11章 外观模式(Façade Pattern)
- hadoop总结2
- USART硬件及接收驱动的详细说明
- 第12章 享元模式(Flyweight Pattern)
- 易语言下载
- SIM卡读卡器的研究与设计
- Android JNINativeMethod详解
- Java通过反射设置私有变量
- mysql基础语句(少部分)(No.9)
- 高效率嵌入式程序开发
- Counter Strike 1.5 on WinXP 64 or Windows 2008 Server 64: available memory less than xx MB