串口通信与裸机程序

来源:互联网 发布:mac 桌面上多了个磁盘 编辑:程序博客网 时间:2024/06/04 20:02

    串口,实在是一个历史悠久的通信方式。如今许多电脑笔记本都不再支持串口,但在嵌入式中,串口却起着举足轻重的作用。嵌入式的控制器,一般都是在arm, sparc, powerpc等处理器外围添加控制单元形成的,其中必然有控制串口的部分。串口的通信,可以简化为两根线Tx, Rx,Tx负责发送,Rx负责接收,当然一端的Tx引脚自然是接到另一端的Rx引脚上。虽然传送是按位来的,但因为有串口控制单元,所以程序往往是一个字节一个字节的发送或接收,甚至用FIFO的多字节发送接收方式。串口发送的波特率即位发送的频率,一般为9600, 19200, ..., 57600, 115200,甚至更高。只要两端设置了一样的波特率,一样的帧格式(校验方式,数据长度,结束位),就可以通信了,如果设置不对就会出现乱码。

串口支持最简单的轮询收发。轮询写,就是读状态寄存器,一直等待发送缓冲区为空,然后把要写的字节丢进去。轮询读,就是读状态寄存器,一直等到接收缓冲区不为空,然后读数据寄存器,取出对方发送的字节。而一般较为正规的,有RTOS(实时操作系统)支持的串口收发,往往是采用中断方式的。中断写,就是把要写的数据放入RTOS的发送缓冲区,开启发送缓冲区为空中断,在中断处理程序中将RTOS发送缓存区中的数据取出,放入控制器的数据寄存器,进行发送。中断读,就是使能接收缓冲区满中断,当串口控制单元收到一定字节数后,会触发中断,在中断处理程序中将数据寄存器中的字节取出,放入RTOS接收缓冲区,等应用程序读串口时,就直接从RTOS的接收缓冲区中取数据。

从实现上来说,轮询方式更为简单;但从效率和可靠性上,却是中断方式更高一筹。我比较亲睐的方式是,轮询写和中断读。因为我的任务需要,我的工作往往是要嵌入式控制器和主机通信,而且对效率要求不高。使用轮询写的方式,一方面实现更为简单,另一方面也更方便调试,只要调用过写串口的函数,就是实际写出去了,即使下一刻要求控制器重启,也不会说串口数据没发出去。而使用中断读,则是可靠性的需要,因为程序往往被各种中断或更高优先级的任务打断,不可能一直等在串口上,接收数据一定会有遗失的地方。即使我在裸机程序上用轮询读,尽量避免中断的干扰,如果CPU主频和波特率相差不是百倍以上,还是会有丢失的情况出现。所以无论是否使用RTOS,中断读串口都势在必行。

对于习惯了ucos等RTOS的我来说,裸机程序遥远而可怕。没有时间片中断,就没有固定的延时,就要靠计算cpu主频和不断尝试来延时,会很不适应。其实远非如此,裸机程序要比带RTOS的程序简单地多。初始化时只要清理一个堆栈,就可以从汇编转到c。没有多任务,就不需要考虑任务切换那一套东西。驱动和中断处理也更为简单。整个程序可以专心地做一件事情。程序生成的可执行文件也要小好几倍。在RTOS盛行的现在,裸机程序仍然占据相当大的份额,不只是因为程序员的古板,也有它的道理在里面。所以说,没有实践过,就没有发言权。以后更要慎言慎行,等考证了再下结论。

原创粉丝点击