新年第一谈,祝EDN的各位版主、博主和网友们在新的一年快马加鞭,马到成功!也祝本命年的自己能够在这一年有所突破!
入正题……
通用异步收发器(UART),也就是我们常说的串口,通过操作串口,可以实现单片机之间以及单片机与外部芯片之间的串行异步通讯。
串行异步通讯的概念学过单片机的应该都不会很陌生。首先就是器件之间各自的时钟独立,互不影响,然后就是以相同的波特率和数据格式实现器件之间的数据传递。一般地,数据大都以字节为单位(8个二进制位为1字节)进行传输。
LPC2364内部集成了4个异步收发器,其中UART1和UART0、2、3特性基本相同,只是UART1相比另三个增加了Modem接口功能。使用lpc2364来简单实现串口数据的收发,有下面三点需要了解:
首先就是收发缓存。Lpc2364串口的收、发数据缓存寄存器都是占有16个字节空间的FIFO(先入先出寄存器),而且在串口中断使能时,可以设置在收到多少个字节时触发中断,该触发中断字节数固定为1、4、8和14个字节可选。与收发缓存对应的两个寄存器就是接收缓存寄存器(UxRBR)和发送保持寄存器(UxTHR),他们是各自16字节收发FIFO的最高字节。
其次就是波特率,即串口每秒传送二进制位的位数。Lpc2364串口的波特率计算公式在我附上的lpc23xx.pdf第14章有详细介绍,需要配置除数锁存LSB寄存器(UxDLL)和除数锁存MSB寄存器(UxDLM),波特率配置代码如下:
最后要注意的就是串口收发器模块结构和实现串口通信的几个必要寄存器的配置了。常用的就是串口中断使能寄存器(UxIER)、串口中断标示寄存器(UxIIR)、串口FIFO控制寄存器(UxFCR)、串口线控制寄存器(UxLCR)和串口线状态寄存器(UxLSR),其功能还是看pdf比较直观,这里就不赘述了。
下面以UART0为例,简单介绍下查询收发和中断收发这两种方式的操作。
查询方式的串口通信:
即禁止UART0向CPU产生中断,CPU不断地查询线状态寄存器(U0LSR)的几个标志位,在确认接收缓存寄存器(U0RBR)收到数据后,通过将此数据转存发送保持寄存器(U0THR)来实现收发。其实现过程比较简单,因此在编程中利用好线状态寄存器(U0LSR)的几个标志位就行了。
附上的例程有详细注释。程序的流程大致如下(从main函数开始执行):
①:初始化UART0:参考附上代码。需要注意的就是在设置通信波特率时,一定要记得在这之前先置位U0LCR的D7位,这样才能实现除数锁存寄存器的有效写入,在波特率设置完成后U0LCR的D7位应立即清零。
②进入while循环,判断U0LSR的D0位,确定U0RBR是否收到有效数据。若未收到有效数据,则一直循环;若收到数据,则将其转存入中间寄存器。
③将中间寄存器中的数据转存U0THR,然后查询U0LSR的D6位(也可通过D5位判断,但个人觉得最好用D6位,详见pdf)直到U0THR和U0TSR为空,从而实现发送,之后返回②。
中断方式的串口通信:
即CPU不需要不停地查询相应的标志位,只在收到有效数据和发送有效数据时才转去处理,从而在一定程度上缩短了串口处理时间,提高了CPU的处理效率。
用中断方式实现串口数据收发,首先要了解的就是串口收发中断的触发条件。Lpc2364的接收中断又称接收数据可用中断,顾名思义,在串口正确接收到有效数据后便立即向CPU发出中断请求,从而告诉CPU串口缓存有有效数据需要处理;其发送中断又称发送保持寄存器空中断,即在向串口发送缓存写完数据并使能发送中断后,一旦发送保持寄存器变空,串口就会立即向CPU产生发送中断请求。
再者就是中断服务程序(ISR)的编写了。在这之前需要提一点,51的中断请求依据型号不同只有5到6个,中断优先级和中断管理相对简单;lpc2364具有多达32个中断请求,通过自带的向量中断控制器(VIC)来编程分配中断的优先级和中断入口地址,因此,要实现中断方式的串口通信还需要对VIC的几个寄存器进行操作(由于这里主要是对串口通信作介绍,VIC的操作还是在以后单独拿出来介绍吧,具体配置请参考附上的源码)。
最后就是编程环节(请参考附上的代码,内有详细注释)。程序流程大致如下:(main开始)
①:初始化UART0:比查询方式多一点就是VIC的设置以及U0IER对各类中断的使能控制。
②:进入while循环,判断接收数据是否完成。一旦收到数据触发接收中断,
CPU转去执行接收ISR,把数据存入中间缓存。在这中间用了一个全局接收标志位进行判断,具体参看代码。
③将中间寄存器的数据转存U0THR,并使能发送中断。待数据发完产生THRE
中断后,在THRE中断ISR中关发送中断使能。
在这里要提一下的是,为了便于观察,我在代码里设置了一个指示灯用来判断中断到底进没进去,后面提到的一些测试结果都是基于这个来的。串口初始化时,设置完串口VIC通道后需要用U0IER使能中断,程序中我只使能了接收中断,在接收ISR中转存完收到的数据后,U0RBR为空,此时接收中断会自动清除,不需要再去清接收中断标志了,这一点pdf中有提到。
还有就是自己在实际测试过程中发现,程序开始在串口初始化时,如果THRE
中断中使能,之后U0THR尽管是空的但不会直接产生THRE中断;RDA中断和THRE中断同时使能时,用串口助手连续发数据,只有RDA中断触发,THRE
中断不会触发;只使能THRE中断,接收采用查询方式时,用串口助手仅仅第一次发送能进THRE中断,之后就进不去了,最后查到是程序THRE中断设置的问题。如果U0THR写操作完成后再使能THRE中断,最后测试可以每次进THRE
中断了。
以上就是我自己对lpc2364串口操作的一些个人见解,作为新手,肯定有理解错误的地方,期待高手指导……
文章评论(0条评论)
登录后参与讨论