新闻中心

EEPW首页>嵌入式系统>设计应用> 单片机通信协议处理

单片机通信协议处理

作者: 时间:2012-10-26 来源:网络 收藏

以下给出具体的实例。在这个系统中,串口的命令非常简单。所有的全部在串口中断中进行。数据包的格式如下:

0x55, 0xAA, 0x7E, 0x12, 0xF0, 0x02, 0x23, 0x45, SUM, XOR, 0x0D

其中0x55, 0xAA, 0x7E为数据帧的帧头,0x0D为帧尾,0x12为设备的目的地址,0xF0为源地址,0x02为数据长度,后面接着两个数据0x23, 0x45,从目的地址开始结算累加、异或校验和,到数据的最后一位结束。

解析的目的,首先判断数据包的完整性,正确性,然后提取数据类型,数据等数据,存放起来用于主程序。代码如下:

if(state_machine == 0) //解析状态机

{

if(rcvdat == 0x55) // 接收到帧头第一个数据

state_machine = 1;

else

state_machine = 0; // 状态机复位

}

else if(state_machine == 1)

{

if(rcvdat == 0xAA) // 接收到帧头第二个数据

state_machine = 2;

else

state_machine = 0; // 状态机复位

}

else if(state_machine == 2)

{

if(rcvdat == 0x7E) // 接收到帧头第三个数据

state_machine = 3;

else

state_machine = 0; // 状态机复位

}

else if(state_machine == 3)

{

sumchkm = rcvdat; // 开始计算累加、异或校验和

xorchkm = rcvdat;

if(rcvdat == m_SrcAdr) // 判断目的地址是否正确

state_machine = 4;

else

state_machine = 0;

}

else if(state_machine == 4)

{

sumchkm += rcvdat;

xorchkm ^= rcvdat;

if(rcvdat == m_DstAdr) // 判断源地址是否正确

state_machine = 5;

else

state_machine = 0;

}

else if(state_machine == 5)

{

lencnt = 0; // 接收数据计数器

rcvcount = rcvdat; // 接收数据长度

sumchkm += rcvdat;

xorchkm ^= rcvdat;

state_machine = 6;

}

else if(state _machine == 6 || state _machine == 7)

{

m_ucData[lencnt++] = rcvdat; // 数据保存

sumchkm += rcvdat;

xorchkm ^= rcvdat;

if(lencnt == rcvcount) // 判断数据是否接收完毕

state_machine = 8;

else

state_machine = 7;

}

else if(state_machine == 8)

{

if(sumchkm == rcvdat) // 判断累加和是否相等

state_machine = 9;

else

state_machine = 0;

}

else if(state_machine == 9)

{

if(xorchkm == rcvdat) // 判断异或校验和是否相等

state_machine = 10;

else

state_machine = 0;

}

else if(state_machine == 10)

{

if(0x0D == rcvdat) // 判断是否接收到帧尾结束符

{

retval = 0xaa; // 置标志,表示一个数据包接收到

}

state_machine = 0; // 复位状态机

}

此过程中,使用了一个变量state_machine作为协议状态机的转换状态,用于确定当前字节处于一帧数据中的那个部位,同时在接收过程中自动对接收数据进行校验和,在数据包接收完的同时也进行了校验的比较。因此当帧尾结束符接收到的时候,则表示一帧数据已经接收完毕,并且通过了校验,关键数据也保存到了缓冲去中。主程序即可通过retval的标志位来进行协议的解析

接收过程中,只要哪一步收到的数据不是预期值,则直接将状态机复位,用于下一帧数据的判断,因此系统出现状态死锁的情况非常少,系统比较稳定,如果出现丢失数据包的情况也可由上位机进行命令的补发,不过这种情况笔者还没有碰到。

对于主程序中进行协议处理的过程与此类似,主程序循环中不断的读取串口缓冲区的数据,此数据即参与到主循环中的协议处理过程中,代码与上面所述完全一样。



评论


相关推荐

技术专区

关闭