从单片机基础到程序框架(全集 2019pdf版).pdf - 第790页

BeepOpen (); } else { vGu16Bee pTimerCnt-- ; if(0==vGu1 6BeepTime rCnt) { Su8Lock=0; BeepClose( ); } } } }

100%1 / 836
TR1=1; //开启定时器 1
SM0=0;
SM1=1; //SM0 SM1 的设置:选择 10 位异步通信,波特率根据定时器 1 可变
REN=1; //允许串口接收数据
//为了保证串口中断接收的数据不丢失,必须设 IP = 0x10,相当于把串口中断设置为最高优先级,
//这个时候,串口中断可以打断任何其他的中断服务函数实现嵌套,
IP =0x10; //把串口中断设置为最高优先级,必须的
ES=1; //允许串口中断
EA=1; //允许总中断
}
void Delay(unsigned long u32DelayTime)
{
for(;u32DelayTime>0;u32DelayTime--);
}
void PeripheralInitial(void)
{
}
void BeepOpen(void)
{
P3_4=0;
}
void BeepClose(void)
{
P3_4=1;
}
void VoiceScan(void)
{
static unsigned char Su8Lock=0;
if(1==vGu8BeepTimerFlag&&vGu16BeepTimerCnt>0)
{
if(0==Su8Lock)
{
Su8Lock=1;
BeepOpen();
}
else
{
vGu16BeepTimerCnt--;
if(0==vGu16BeepTimerCnt)
{
Su8Lock=0;
BeepClose();
}
}
}
}
第一百三十二节:“转发、透传、多种协议并存”的双缓存串口程序框架。
【132.1 字节间隔时间、双缓存切换、指针切换关联。
在一些通讯模块的项目中,常常涉及数据的转发,透传,提取关键字的处理单片机接收到的数据不
随意丢失,必须全部暂存,然后提取关键字,再把整包数据“原封不动”或者“略作修改”转发给“下家”
这类项目的特点是,通讯协议不是固定唯一的,因此,前面章节那种接头暗号(数据头)的程序框架不适
这里,本节跟大家分享另外一种程序框架。
第一个要突破的技术难点是,既然通讯协议不是固定唯一的那么,如何识别一串数据已经接收完毕?
答案是靠接收每个字节之间的间隔时间来识别。当一串数据正在接收时,每个字节之间的间隔时间是短暂
的相对均匀的”当一串数据已经接收完毕时每个字节之间的间隔时间是“突然变长的”代码的具体实现,
是靠一个软件定时器,模拟单片机“看门狗”的“喂狗”原理
第二个要突破的技术难点是,既然通讯协议不是固定唯一的数据内容带有随机性,甚至字节之间的间
隔时间的长短也带有随机性和不确定性,那么,如何预防正在处理数据时突然“接收中断”又接收到的新数
据覆盖了尚未来得及处理的旧数据,或者,如何预防正在处理旧数据时丢失了“突然又新过来的本应该
收的新数据”?答案是用双缓存轮流切换的机制。双缓存一个用在处理刚刚接收到的旧数据,另一个用在
时刻准备着接收新数据,轮流切换,两不误。
第三个要突破的技术难点是,既然是用双缓存轮流切换的机制,那么,在主程序里如何统一便捷地处
两个缓存的数组?这里的“统一”是关键,要把两个数组“统一”成(看成是)一个数组,方法是,只需用
“指针切换关联”的技术就可以了。
【132.2 程序例程。
上图 132.2.1 有源蜂鸣器电路