单片机解析协议基础教程(基于51单片机).doc
文本预览下载声明
单片机解析协议基础教程(基于51单片机)
????? ? 其实,使用单片机解析协议很简单,我们需要分析协议的格式,将其分开处理即可。例如某一串口指令模块的指令格式为:帧头(2字节)+数据长度(1字节)+数据(N字节,其中N256),指令也放在数据堆里了嘛!!那么我们就按照帧头、数据长度、数据分别处理。写单片机程序要有一种思路就是从整体到局部。那么我们如何判断一个数据帧被完整接收呢?这里就要用到一些标志位来处理了。先给出程序流程图吧
?
图1 程序流程图
协议双方当然事先知道嘛,当然可以比对!只有帧头匹配了接下来就是长度,再继续就是接其他的数据嘛!不匹配继续往后接看数据里是否是帧头嘛!!!接受有效数据(不包含帧头和数据长度),数据长度默认就在帧头后面嘛!
在写程序之前,首先对几个变量及标志位进行说明:? ? 1.帧头高字节和帧头低字节分别使用宏定义指定,这样方便修改,如:????????? ? #define FRM_H ?0XAA????????? ? #define FRM_L ? 0XBB? ? 2.用于指示接收数据的位置,定义一个变量Rx_POS,定义一个变量Rx_Num用于指示要接收数据的长度。????????? ? unsigned char Rx_POS;????????? ? unsigned char Rx_Num;? ? 3.接收到完整帧标志位、接收到帧头标志位、????? ? ????bit RXFRMOK;?????//接收到完整帧标志位????? ? ????bit RXFHOK;????? ? //接收到完整帧头标志位? ? 4.接收的数据缓冲区? ? ? ? ? ? unsinged char RXFH[3];????????????unsigned char?RX_BUF[32];?????????现在我们使用RXFRMOK来标识接收到完整数据帧,首先要写的肯定是没有接收到完整帧的情形。那么我们可以编写程序如下:????????????? ? 代码1:?? ? ? ? ? ? ? ? void UART1_ISR() interrupt 4????????????? ? {????????????????????? ? unsigned char Rx_Data;????????????????????? ? if(RI)????????????????????? ? {????????????????????????????? ? Rx_Data = SBUF;//读取串口缓冲区数据????????????????????????????? ? RI = 0;????????????? ? //清除串口中断请求????????????????????????}????????????????????? ? if(!RXFRMOK)//如果没有接收到完整帧????????????????????? ? {????????????????????????????????????????????????????????}????????????????????? ? if(TI)????????????????????? ? {????????????????????????????? ?TI = 0;????????????????????????}?????????????????}????????代码写到这里,可能就有人急了,怎么才写这么一点啊?别急,这是为了让新手更容易程序是怎么一步步的写出来的,我将代码一点点地写完整,让新手更加轻松地入门。????? ? 根据从整体到局部的思想,我们把整体框架已完成,那么现在开始处理局部的问题了,仔细一看数据帧格式,开头是两个字节的帧头,那么,开辟两个数组,其中一个用于缓存帧头和数据长度,另一个用于缓存串口接收到的数据,缓存帧头和数据长度的数组定义为RXFH[3],我们假设一次接收的数据不超过32字节,则开辟的数组为RX_BUF[32],设置一个unsigned char型的变量Rx_POS用以指示接收数据的位置,这个位置仅用于指示接收到数据的位置,注意:不包含帧头和数据。?????????准备工作做好后,此刻当然是先处理没有接收到帧头的程序了,每接收到一个字节的数据,我们都把缓冲区的数据依次往前挪一个位置,然后判断第一和第二字节数据是否为帧头,如果是帧头,那么第三字节就表示数据长度了,我们把上面的代码1拷贝过来,继续添加代码(添加部分用浅蓝色标识):????????? ?代码2:? ? ? ? ? ? ? ? void UART1_ISR() interrupt 4????
显示全部