前言
1.上一章(中断定时+超时接收)的逻辑,适用于协议较为复杂的情况,即中断判断接收结束,数据放置缓冲区,主函数中解析数据。
2.实际开发中,用户自定义协议的帧头是可预见的,包括数据长度等。
3.本章测试使用中断即时解析自定义协议
提示:以下是本篇文章正文内容,下面案例可供参考
一、场景
示例一串数据:固定帧头区(AA 66 AA )+数据类型(01/02)+数据区+和校验+异或校验
其中,01LED,02蜂鸣器 ,数据区为工作时间,低位在前高位在后
二、编程实现
1.知识点
a.“状态机”的算法思想
状态机是有限状态自动机的简称,是现实事物运行规则抽象而成的一个数学模型。
包括:State(状态)、Event(事件)、Action(动作)、Transition(转换)
链接:什么是状态机
b.用户自定义协议一般格式:
eg:
数据类型包括外部负载,如led、继电器、蜂鸣器
2.代码设计
1.串口中断服务函数中判断数据有效性,仅保存数据区到缓冲区recv_buf[]
2.校验ok后清相关变量,置数据有效接收标志1
void uart_ISR() interrupt 4
{
if(RI)
{
RI = 0;
recv_data = SBUF;
switch(machine_step)
{
case 0:
if(0xAA == recv_data) //1.帧头符合,状态+1,下一次中断进入后继续检测,否则丢弃
{
machine_step = 1;
}
else
{
machine_step = 0;
}
break;
case 1:
if(0x66 == recv_data)
{
machine_step = 2;
}
else
{
machine_step = 0;
}
break;
case 2:
if(0xAA == recv_data)
{
machine_step = 3;
recv_Cnt = 0; //2.即将进入数据区,计数启动
}
else
{
machine_step = 0;
}
break;
case 3: //3.校验计算
sum_check += recv_data;
xor_check ^= recv_data;
recv_buf[recv_Cnt] = recv_data; //4.数据区存储到缓冲区
recv_Cnt++;
if(recv_Cnt >2)
{
machine_step = 4;
}
break;
case 4:
if(sum_check == recv_data) //5.校验判断 //recv_data已经是新的一个字节,
{
machine_step = 5;
}
else
{
machine_step = 0; //累加和错误,下次重新开始判断
sum_check = 0; //校验清0,否则下一串数据在状态3时出错
xor_check = 0;
}
break;
case 5:
if(xor_check == recv_data)
{
recv_flag = 1; //6.数据正确,标志置1
}
else
{
machine_step = 0; //异或校验错误,下次重新开始判断
}
sum_check = 0; //校验清0,否则下一串数据在状态3时出错
xor_check = 0;
machine_step = 0; //++的数都要记得在某个地方清0
recv_Cnt = 0; //不清也ok,养成习惯清除
break;
default:break;
}
}
}
3.主函数中执行数据解析:
数据类型01时LED工作,02时蜂鸣器工作,recv_buf[1]时间低位,recv_buf[2]数据高位,整合成unsigned int
void Convert(unsigned char *vbuf)
{
UC i;
if(recv_flag)
{
recv_flag = 0;
// timer_start = 0; //关掉定时器,防止T0一直在执行
for (i = 0; i < cRealLen; i++)
{
uart_Recv[i] = vbuf[i];
}
sendString(vbuf); //test
Exchange_Func();
clr_recvbuffer(vbuf);
}
}
void Exchange_Func(void)
{
// UC cSchIndex; //帧头不是指定特征帧头时,移位查找
// UC cErr_Info[] = {'e','r','r','o','r','n'};
// UC fvalid; //有效数据标志
switch(recv_buf[0])
{
case 1:
recv_Led_time = recv_buf[2];
recv_Led_time <<= 8;
recv_Led_time += recv_buf[1];
break;
case 2:
recv_Beep_time = recv_buf[2];
recv_Beep_time <<= 8;
recv_Beep_time += recv_buf[1];
break;
default:break;
}
4.T0定时器中断服务函数中将计数–处理,计时
void Timer0_ISR() interrupt 1
{
TR0 = 0; //进T0中断首先关闭定时器
if(recv_Led_time)
{
recv_Led_time--;
fLedShine = 1;
}
else
{
fLedShine = 0;
}
if(recv_Beep_time)
{
recv_Beep_time--;
set_buzz(BUZZ_TYPE1);
}
else
{
BUZZER = 1;
}
主函数数据解析开放性实现功能
总结
1.本章仅简单测试设计框架:“中断即时解析用户自定义数据”,较上一章而言,优点在于简易的协议情况下,处理速度更快。
2.引用“状态机”的编程思想
3.根据实际情况选择合适的代码方案。
上一篇:#C51串口通讯4-#一串数据#中断即时解析用户自定义协议(握手接收应答)
下一篇:#C51串口通讯2-#一串数据#定时中断实现超时接收
设计资源 培训 开发板 精华推荐
- 使用 Infineon Technologies AG 的 OMR7805ST 的参考设计
- EVAL-AD7492CB,用于数据采集系统的 AD7492、12 位、1MSPS ADC 的评估板
- #第二届立创大赛#基于脚本语言的可设置界面的真彩LCD液晶双路电压电流表头
- Sheet_1
- 雪花打孔改进版
- EV-ADF411xSD1Z,用于评估 ADF411x 整数 N 和分数 N PLL 频率合成器的评估板
- 具有调光功能的3A HB LED驱动器,基于SO-8 Batwing封装的LED2000
- AD8330-EVALZ,评估套件是一种易于使用的附件,可用于对 AD8330 可变增益放大器 (VGA) 进行动手评估
- NCV7101电流源运算放大器典型应用电路
- 山东建筑大学 电子校园卡