ARM 串口驱动本质
1.LPC2000 系列芯片的串口的接收模块包括接收缓冲寄存器和移位寄存器。接收的数据进入移位寄存器后经移位处理并行传入缓冲寄存器,事实上,UART的FIFO是一个硬件环形的缓冲队列,物理上不可寻址,不可见,仅U0RBR这个FIFO出口可见。U0RBR就是接收FIFO的第一位。FIFO的长度是可设的,也叫触发点,低于这个长度的字符串不会引起中断,但在实际应用中,不可能串口读入的数据长度总为触发点值的整数倍,为此,引入了CTI即字符接收超时中断,当有不足触发点值规定的字符串读入时,将引起中断,其与串口的RDA中断具有相同的优先级,并会同时被使能。
2.那么,LPC2000的UART机制是如何判断串口读入数据的一次性容量呢?如果接收FIFO里已经有了1个字符,它可在一定的时间内等待下一个字符的读入,也就是说,不超过一定的时间就不会触发CTI中断,这个时间是在本次通讯协议设置的前提下,接收3.5到4.5个字符所用的时间。比如,需串口接收GPRS数传状态成功建立后的返回值“Ok_Info_WaitingForData”22个字符组成的字符串,FIFO触发点设置为14,在前14个字符读入之后,立即触发RDA中断,跳转至RDA中断服务子程序将这14个字符放入我所预设的缓冲区内,接着,后8个字符读入,这时CPU并不立刻中断,它需等待在本次通讯协议设置的前提下,接收3.5到4.5个字符所用的时间(需具体计算),这个时间一到,立刻触发CTI中断,换句话说,超过这个时间的等待,CPU就认为一个完整的字符串已经结束了,这才是字符串超时的真正含义。
U0RBR:接收器缓存寄存器
访问时,先要设定 U0LCR 的除数锁存访问位(DLAB)为 0。因为,U0DLL 与U0RBR/U0THR 在同一地址上。
DLAB = 1 时,选择 U0DLL 和 U0DLM (U0DLM 和 U0IER 在同一个地址上);
DLAB = 0 时,选择 U0RBR/U0THR 和 U0IER。
U0DLL 和 U0DLM:
构成一个 16 位的除数。
VPB时钟(pclk) 是产生波特率的时钟源,波特率时钟源必须是波特率的16倍,于是有:
baud_rate = pclk/(16*设定的除数)
UART0 的中断:
有 4 个中断,分别是:
RBR 中断; THRE 中断; Rx 线中断;
其中 RBR 中断里面包含有2个中断:数据可用RDA中断 和 接收超时 CTI 中断。
FAQ一:
1、什么是 RDA 中断?
当接收的有效数据到达接收FIFO设置寄存器(U0FCR)中设置的触发点时,RDA中断被激活。
U0FCR[7:6]=00 触发点 0(1字节); U0FCR[7:6]=01 触发点 1(4字节);
U0FCR[7:6]=01 触发点 2(8字节);U0FCR[7:6]=01 触发点 1(14字节);
发生中断后,U0IIR[3:0] 内容为:0100。
如果发生中断后,读一下 U0RAR 寄存器,那么就会得到最早到达的数据。这时,FIFO 中的有效数据小于预定触发点,清零 RDA 中断。
该中断的优先级为 2 。
2、什么是 CTI 中断?
在接收 FIFO 中,有效的数据少于触发个数时,但至少有一个时,如果长时间没有数据到达,将触发 CTI 中断。这里所说的“长时间”是指在 接收 3.5~4.5 个字节所需要的时间。发生中断,则U0IIR[3:0] 内容为:1100。在中断后,若从 U0RBR 中读取接收FIFO中的数据,或者有新的数据送入接收FIFO中,这都将清零 CTI 中断。
该中断的优先级为 2。
3、什么是 THRE 中断?
THRE中断是发送中断。发生 THRE 中断的前提条件是FIFO 必须为空。
假设刚刚发生了一次 THRE 中断,也就是说这时 FIFO 中为空。那么现在往 FIFO 中写入 1 个字节的数据,因为FIFO本来是空的,那这个字节的数据就会被直接写到移位寄存器 U0TSR中,这时 FIFO 肯定又是空的。此后,如果在发送完之前那个字节和停止位后,若还没有数据进来,就会触发 THRE 中断了。那为什么要等这段时间呢?因为如果立即产生中断,而同时又有数据要进来,则中断就会打断数据的传送。
假设,原本 FIFO 中已经有2个或2个以上的数据,那么FIFO送出这两个数据后就空掉了,那就会立即触发中断。
当 THRE 中断为当前有效的最高优先级中断时,往 U0THR 写数据,或者对 U0IIR 的读操作,将使 HTRE中断复位。
在U0IIR 中,THRE的中断代码为:0110。
该中断的优先级为 3 。
4、什么是 RLS 中断。
RLS中断优先级最高。它发生在 UART0 产生了四个错误中的任何一个时。这四个错误是:
溢出错误(OE)、 奇偶错误(PE)、 帧错误(FE)、间隔中断(BI)
发生RLS中断时,通过查看 线状态寄存器 U0LSR[4:1] 就可以知道是由于那个错误触发了 RLS 中断。读取 U0LSR 时清除该中断。
FAQ二:
1、什么是 OE 溢出?
接收时,在 U0RBR 寄存器中已经有新的字符就绪,而此时接收 FIFO 正好满了,就产生了溢出。这时 U0LSR[1]
= 1,另
ARM串口驱 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)