基于51串口通讯编程软件架构剖析

发布者:范隆最新更新时间:2017-11-21 来源: eefocus关键字:串口通讯  编程  软件架构 手机看文章 扫描二维码
随时随地手机看文章

前言:
串口通讯对于所有的嵌入式工程师十分常见,对于一个与外界交互的系统必须依赖一些手段,比如串口、USB、红外、GPRS之类的数据通讯传输方式。而串口作为一种廉价的短距离可靠的通讯方式得到了广泛应用。
废话少说了,就此打住,进入正题。
本文主要从软件结构上讲解如何在资源比较缺乏的系统上实现通讯协议的串口通讯编程,以及如何优化程序效率,从而使系统更快、更稳定运行。

正文:
      我们以51单片机为例。51中一般针对串口通讯编程,通常采取中断接受查询发送的方式。中断函数在接受数据到达时被重复调用,其实是个重复入栈的过程,所以不宜将函数写的太长,函数太长一般会导致栈太深占用系统资源,二是处理时间过长,可能导致通讯出错。为了防止在处理数据过程中不受干扰,通常在处理接受数据前关闭中断,处理完后再开。
通常的的编程方式如下:
static void UartInterruptService(void) interrupt 4
{
    ES = 0;
    RI = 0;
    uart_process(SBUF);
    ES=1;
}
下面重点介绍数据处理函数 uart_process(SBUF);
其实很多时候,对于通讯传输的数据处理才是关键,尤其对于设计通讯协议而言。笔者在刚刚做的一个系统上就碰到这样的问题,当系统庞大了,资源十分有限的情况下,数据处理一旦占用资源太多,效率太低将导致系统崩溃而无法运行。
到了这里,很多工程师可能会考虑开个大的缓冲区FIFO将接收到的数据保存在缓冲区,然后对其进行解析、判断进行下一步程序编写,当然这在系统资源比较丰富的情况下是没有问题的,ARM上采取的就是这样的方式。但如何系统庞大呢,留给的资源缺乏则不行。这样做的一个很大缺点必须是将数据帧接收完了才能够判断,降低了效率和运行速度。
其实还有另外的方式,可以采取在每接收一个字节就对其解析,解析完判断转到下一个状态,并将其中的有用数据存储在相应的数据结构中去,可以采取状态机实现。

将状态机设计为两个控制状态,一是串口状态——uart_state ,一是命令类型状态——cmd_state .
(1)状态机开始状态:串口状态为CMD_NO
(2)接受到STX_CMD,状态变为CMD_START.
(3)接下来将自动进入接受命令帧的状态,再开启命令状态的状态机,对发送来的有用数据进行解析,保存,校验等。处理完毕后将uart_state设为CMD_END状态进行下一步的接受完毕判断,将cmd_state设置为初始的NO_CMD状态。
(4)最后进行ETX_CMD判断,判断数据接收是否完毕。


void uart_process(U8 u8)
{
     if(uart_state == CMD_NO)
     {
    if(u8 == STX_CMD)
      {
        uart_state = CMD_START;
      }

       }
    else if(uart_state == CMD_START)
    {
        switch(cmd_state)
        {
           case NO_CMD:
              cmd_state = u8;
              break;

           case COST_CMD:
                    //解析存储有用数据到相应数据结构中
                    //进行CRC校验
                    ……
                       uart_state = CMD_END;
                       cmd_state = NO_CMD;
                       CRC = 0;
                        break;
                        …… 
                   }
              ……
            }
        else if(uart_state == CMD_END)
         {
            uart_state = CMD_NO;
            if(u8 == ETX_CMD)
            {
              //接受完毕
              //可以考虑抛出一个消息main函数循环中进行响应处理。
             }

           }
}


接下来我们要讨论解析后我们数据存储的问题,其实在资源比较足够的情况下或者能够挤出data区的情况下可以考虑用结构体,我们构造好相应结构体,将接收到的数据存储进去,要应用的时候就十分方便。但这也有个矛盾,一般c51定义的结构体都被存储在data区,一般通讯的字节量大空间必然不够,存在一个矛盾,可以采用联合体union进行存储效果会好一点。当然也可以在保存数据时采用定义在xdata区(片外)的buffer来存储。这样在一定程序上优化了程序的执行效率,在程序处理立即抛出消息处理,提高了通讯数据的处理速度。对于通常资源比较丰富的系统,比如ARM上一般采取的做法是这样的,将数据存在缓冲区,接收完一帧数据后再转换成相应的数据结构,再进行分析、校验。    

总体来说,这种采取状态机实时解析串口通讯数据的方式在一定程序提高了程序运行效率,使软件架构清晰明了,程序可扩展性大,有利于后续开发。以上是笔者的一点愚见,欢迎指教。

关键字:串口通讯  编程  软件架构 引用地址:基于51串口通讯编程软件架构剖析

上一篇:KeilC51_Proteus—联合调制
下一篇:MCS-51单片机的时序单位

推荐阅读最新更新时间:2024-03-16 15:46

51控制的MT8880双音频收发器的汇编程
ORG 0000H AJMP MAIN : : ;******************** ;* 8880 初始化 * ;******************** MAIN: MOV A, #90H MOV P0, A ; 写 8880CRA MOV P0, A ; 写 8880CRA MOV A, #98H MOV P0, A ; 写 8880CRA
[单片机]
STM32F030 I2C 从模式中断编程
第一次用I2C的从模式,之前用的是主模式,用的IO模拟的,在很多设备都用上了,没什么问题。在使用I2C从模式之前,也在网上看到很多人说这个是坑。自己花了几天的时间,终于跳过了这个坑,再次总结下: 1. 最困难的地方:因为需要两个平台对接,主端用的是LINUX系统,芯片是TI335X,从端是STM32F030,我两端的程序都没写过,所以出现问题了,无法判定是哪一边的问题,这个很痛苦。 2. 例子。虽然“拿来主义”不太厚道”,但是站在巨人的肩膀上,往往是最快的。 1) STM32F030的代码:http://www.openedv.com/forum.php?mod=attachment&aid=NDczMzV8N2FkM
[单片机]
C8051F020的SMBus
C8051F020的SMBus兼容I2C,因此可以方便地挂接多个I2C器件,如下图: 主发送器方式: 主接收器方式: SMB0STA: bit SM_BUSY;//读和写时的忙标志位 void SMBus_Init() { SMB0CN=0x44; SMB0CR=0xec;//频率400k EIE1|=0x02; SM_BUSY=0; } void SM_Send(uchar chip_select,uint byte_address,uchar out_byte) {//i2c写驱动 while(SM_BUSY);//等待SMBus空闲 SM_BUSY=1
[单片机]
51单片机+MPU6050驱动程序,1602显示
想做滚球控制系统,先写了个MPU6050驱动看看 单片机源程序如下: #include REG52.H #include math.h //Keil library #include stdio.h //Keil library #include INTRINS.H typedef unsigned char uchar; typedef unsigned short ushort; typedef unsigned int uint; //**************************************** // 定义51单片机端口 //*******************************
[单片机]
<font color='red'>51</font>单片机+MPU6050驱动程序,1602显示
基于RTX51的用户专用键盘软件设计
RTX51实时操作系统进行单片机软件设计,可以真正做到各任务并行执行,同时,由于程序结构更加科学合理,可以方便地实现修改升级,以满足功能较多的设计要求。 1 用户专用键盘简介 用户专用键盘多使用在工业控制场合,它由按键和指示灯组成,对外采用RS232接口,当某个按键按下时,键盘将命令(码值)发送计算机,同时,键盘接收来自计算机的命令(码值)点亮(熄灭)某个指示灯,以指示系统工作状态,从而实现快速人机交互。用户专用键盘硬件原理框图如图1所示。 图中,可编程逻辑芯片实现单片机输出接口扩展,其内部包含多个输出锁存器。工作时,单片机输出的地址信号经可编程芯片内部译码器译码产生片选信号,使能不同的输出锁存器,将数据信号输出控制各个指示
[单片机]
基于RTX<font color='red'>51</font>的用户专用键盘<font color='red'>软件</font>设计
改善8051系统用电效率的微控制器
摘要:一种改进架构的高性能8051设计、外围功能集成、选用合适的时钟源以降低功耗;并介绍节省电能的软件技术及采用待机模式降低功耗的技巧。 关键词:停机模式 空闲模式 功率管理模式 便携式产品的功能和性能日新月异。 消费者对产品性能的要求也越来越高,需要更强大的运算能力支持;另一方面,希望产品具有更低的功耗。 尽管已经出现了很多功耗处理器,但它们的性能通常很有限。Dallas公司的系列高速微控制器在性能和功耗之间取得了一个很好的折衷,采用了8051架构——世界上最流行的微控制器之一。简单易用、丰富的I/O资源使这种微控制器深受设计者的喜爱,并被广泛接受。它的流行势头已蔓延到了便携式领域,在很多应用中都有其用武之地。 本文
[应用]
LabVIEW编程中如何实现集合函数
   Labview 的数组操作功能是非常强大的,除了数组函数选板中提供的函数之外,信号处理函数选板中的函数实际上也是在操作数组,但是并没有提供直接的 集合函数 。在MathScript中, LabVIEW 提供了几个集合相关函数。   下面我我将利用OPENG中的数组函数实现针对一维数组的 集合函数 ,并利用MathScript对其进行验证。   一、uNIque 集合函数   我首先要介绍的是unique函数。unique本意是唯一的意思,对输入的数组去掉重复的元素,形成新的数组,新数组中的所有元素都是唯一的,各不相同。   OPENG中直接提供了这样的函数,函数名为“去除数组中的重复元素”。函数除了返回去除重复元
[测试测量]
LabVIEW<font color='red'>编程</font>中如何实现集合函数
X25165芯片在8051系统中的应用
    摘要: C25165是美国Xicor公司生产的集看门狗、电压监控和串行EEPROM于一体的专用集成电路,文中介绍了X25165的结构,功能及工作原理,并以其在8051系统中的应用实例,给出了X25165与8051单片机的硬件接口电路和软件接口程序。      关键词: 单片机  看门狗  X25165  接口  软件      美国Xicor公司生产的Z25165芯片是集看门狗、电压监控和串行EEPROM三项功能于一体的集成电路产品。该芯片的应用将有利于简化单片机系统的结构,降低系统的成本,减少对电路板的空间需求,增加系统的可靠性。 1 芯片简介     X25
[工业控制]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved