当前位置:首页 > 单片机 > 单片机
[导读]前言:串口通讯对于所有的嵌入式工程师十分常见,对于一个与外界交互的系统必须依赖一些手段,比如串口、USB、红外、GPRS之类的数据通讯传输方式。而串口作为一种廉价的短距离可靠的通讯方式得到了广泛应用。废话少说

前言:
串口通讯对于所有的嵌入式工程师十分常见,对于一个与外界交互的系统必须依赖一些手段,比如串口、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上一般采取的做法是这样的,将数据存在缓冲区,接收完一帧数据后再转换成相应的数据结构,再进行分析、校验。

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

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

学好电子技术基础知识,如电路基础、模拟电路、数字电路和微机原理。这几门课程都是弱电类专业的必修课程,学会这些后能保证你看懂单片机电路、知道电路的设计思路和工作原理;

关键字: 单片机 编程 电路设计

单片机编程需要使用专门的软件工具,这些工具能够帮助程序员编写、调试和烧录程序到单片机中。以下是一些常用的单片机编程软件:

关键字: 单片机 编程 软件工具

Java语言和C语言是两种不同的编程语言,它们在语法、特性和应用领域上有许多差别。下面将详细介绍Java语言和C语言之间的差异以及它们各自的技术特点。

关键字: Java语言 C语言 编程

嵌入式系统是现代生活中无处不在的一部分。它们包括了我们的家电、汽车、智能手机、医疗设备等等。这些系统的工作必须高效、可靠,因为它们往往控制着生活中的关键方面。而C语言作为一种广泛用于嵌入式系统开发的编程语言,其质量和稳定...

关键字: 嵌入式系统 C语言 编程

在嵌入式系统开发领域中,C语言是使用最广泛的编程语言之一。它具有高效、灵活和可移植的特点,成为嵌入式系统设计师的首选语言。本文将介绍C语言编程的基本概念、特点以及在嵌入式系统开发中的应用。

关键字: 嵌入式系统 C语言 编程

在编程和计算中,运算符优先级是解释和计算表达式的一个关键因素。本文旨在阐述运算符优先级的概念、规则及其在表达式中的应用,以帮助读者更好地理解和运用运算符优先级。

关键字: 表达式 运算符 编程

泰克科技组合软件总经理Rick Khulman:“激发孩子们——尤其是女孩们对STEM的兴趣,对我本人乃至广大工程界都至关重要。”

关键字: 编程 机器人 示波器

PIC单片机采用精简指令集,例如对于PIC16F716单片机,只有35条单字节指令。要用这么少的指令实现复杂的控制或计算,显然要在程序设计上多做文章,以下就程序设计需要注意的问题谈一些看法。 美国微芯公司开发的CMOS工...

关键字: 单片机 控制 编程

PLC编程是一种数字运算操作的电子系统,专为在工业环境下应用而设计。它采用可编程序的存储器,用来在其内部存储执行逻辑运算、顺序控制、定时、计数和算术运算等操作的指令,并通过数字式、模拟式的输入和输出,控制各种类型的机械或...

关键字: plc 编程 plc编程

初学PLC梯形图编程,应要遵循一定的规则,并养成良好的习惯。下面以西门子PLC为例,简单介绍一下PLC梯形图编程时需要遵循的规则,希望对大家有所帮助。

关键字: 西门子 plc 编程
关闭
关闭