在使用51单片机开发时,规定相关协议要单片机要通过串口接收一系列数据(以C8051F410单片机为例)。
串口的SBUF寄存器触发中断一次只能接收一个字节的数据,所以使用数组进行存储的时候不能一次将所有数据进行存储。
假设通信协议协议:数据包第一字节为A5,第二位为上报数据状态组成的字节,第三字节为5A,第四字节为前三字节之和的低字节。
数据的接收
以数据为A5 01 5A 00为例。定义一个receive[3]数组,当我们以循环为数组赋值时
for(i=0;i<4;i++)
{
receive[i]=SBUF0;
}
这时数组所存储的全部是最后输入00字节。这是因为每一次SBUF只能存储一个字节的数据,所以每次更新只是将字节进行了覆盖,然后进行了循环存储。
下面我会用数组移位的方式进行对数据包的存储
if(RI0==1)//标志位为1进入中断
{
RI0=0;//先清零标志位
for(i=0;i<3;i++)
{
receive[i]=receive[i+1];//每接收一次数据对数组进行一轮次前移
}
receive[3]=SBUF0;//用数组最后一位对数据进行存储
当进入中断四次后,数组将会存储接收的四个字节数据。
数据的发送
在接收到数据后,我们需要对数据进行判断,是否符合数据的协议 。
void check (unsigned char *checkinput)
{
if((checkinput[0] == 0xA5) && (checkinput[2] == 0x5A))
{
sum=checkinput[0]+checkinput[1]+checkinput[2];
if(sum==checkinput[3])
{
flag=1; //符合判断,flag标志为1,进行输出
}
else
{
flag=0;
}
}
}
判断部分程序较为简单,有不懂的可以私聊博主。需要注意的是,这一部分最好写成函数单独进行调用,不要全部写在中断函数中。
当flag为1时,证明我们收到的数据是符合协议的,现在我们需要对数据进行发送。
if(flag==1)
{
flag=0;
count=0;
SBUF0=receive[0];
}
我们现在先在主函数中进行第一次发送,输出接收数组的第一位,以达到触发单片机中断函数的目的。然后进入中断函数进行后面数据的发送。
if(TI0==1)//第一次发送触发中断,标志位为1
{
TI0=0;
count++;//初值为0,进入直接加1,发送数组第二位
if(count<=4)
{
SBUF0=receive[count];
}
}
中断函数运行结束,数组发送成功。
以上就是以C8051F410为例的串口接收发送协议字符串的程序,对于单片机的init和串口的init本文就不在赘述,如果有不懂的可以私聊博主,在博主力所能及的范围内将会进行解答。
博主的输出方式也有很多不足。博主的程序中,在中断函数里,会进行频繁地循环语句,这是会大大浪费时间的,大家应该了解到,在MCU编程中循环程序是用来进行延时delay的,所以每次的循环将会占用大量的时间,而且所占用的时间随着需要接受数据的长度进行递增,更是会增加时间的浪费。
希望博主的文章能够帮助到大家,如果各位大神还有更好的方法希望大家能多多评论分享。
感谢各位大神的阅读、点赞、收藏、评论。
标签:字节,receive,51,checkinput,单片机,数组,串口,数据 From: https://blog.csdn.net/weixin_48671285/article/details/136912188