从单片机基础到程序框架(全集 2019pdf版).pdf - 第816页
if(1==Cm pTwoBufferI sSame(Cu8T estTable, / /如果接收的 数据与存储的 相等 Gu8ReceTab le, 57)) { vGu8Beep TimerFlag=0 ; vGu16Bee pTimerCnt=1 000; //让蜂鸣器“长鸣 ”一声 vGu8Beep TimerFlag=1 ; GtBigBuf ferUsart.u8 Status=1; //对外 宣布“通讯 成功” } els…

GtBigBufferUsart.u8QueueSendBuffer[14]=CalculateXor(GtBigBufferUsart.u8QueueSendBuffer,
14); //最后一个字节不纳入计算
//队列驱动函数的状态 0 为初始状态 1 为通讯成功 2 为通讯失败
GtBigBufferUsart.u8QueueStatus=0; //队列驱动函数的通讯状态
GtBigBufferUsart.u8QueueSendTrig=1;//队列驱动函数的发送的启动
vGu8BigBufferUsartTimerFlag=0;
vGu16BigBufferUsartTimerCnt=2000;
vGu8BigBufferUsartTimerFlag=1; //过程控制的超时定时器的启动
GtBigBufferUsart.u8Step=4; //切换到下一步
break;
case 4: //发送之后,等待下位机返回的数据的状态
if(1==GtBigBufferUsart.u8QueueStatus) //当前批次的接收到的数据成功
{
//更新累加当前实际已经发送的字节数
GtBigBufferUsart.u32AlreadySendSize=GtBigBufferUsart.u32AlreadySendSize+
GtBigBufferUsart.u32CurrentSize;
//更新下一步起始的发送地址
GtBigBufferUsart.u32CurrentAddr=GtBigBufferUsart.u32CurrentAddr+
GtBigBufferUsart.u32CurrentSize;
//更新下一步从起始地址开始发送的字节数
if((GtBigBufferUsart.u32CurrentAddr+GtBigBufferUsart.u32CurrentSize)>
GtBigBufferUsart.u32NeedSendSize) //最后一段数据的临界点的判断
{
GtBigBufferUsart.u32CurrentSize=GtBigBufferUsart.u32NeedSendSize-
GtBigBufferUsart.u32CurrentAddr;
}
else
{
GtBigBufferUsart.u32CurrentSize=10;
}
//判断是否已经把整个大数组的 57 个字节都已经接收完毕。如果已经接收完毕,则
//结束当前通信;如果还没结束,则继续请求下位机发送下一段新数据。
if(GtBigBufferUsart.u32AlreadySendSize>=GtBigBufferUsart.u32NeedSendSize)
{
GtBigBufferUsart.u8Step=0;
GtBigBufferUsart.u8Start=0; //结束当前的过程通讯

if(1==CmpTwoBufferIsSame(Cu8TestTable, //如果接收的数据与存储的相等
Gu8ReceTable,
57))
{
vGu8BeepTimerFlag=0;
vGu16BeepTimerCnt=1000; //让蜂鸣器“长鸣”一声
vGu8BeepTimerFlag=1;
GtBigBufferUsart.u8Status=1; //对外宣布“通讯成功”
}
else
{
vGu8BeepTimerFlag=0;
vGu16BeepTimerCnt=30; //让蜂鸣器“短鸣”一声
vGu8BeepTimerFlag=1;
GtBigBufferUsart.u8Status=2; //对外宣布“通讯失败”
}
}
else
{
GtBigBufferUsart.u8ReSendCnt=0; //重发计数器清零
GtBigBufferUsart.u8Step=3; //返回上一步,继续发下一段的新数据
}
}
else if(2==GtBigBufferUsart.u8QueueStatus) //当前批次的接收到的数据失败
{
GtBigBufferUsart.u8ReSendCnt++;
if(GtBigBufferUsart.u8ReSendCnt>=SCu8ReSendCntMax) //大于最大的重发次数
{
GtBigBufferUsart.u8Step=0;
GtBigBufferUsart.u8Start=0; //结束当前的过程通讯
GtBigBufferUsart.u8Status=2; //对外宣布“通讯失败”
vGu8BeepTimerFlag=0;
vGu16BeepTimerCnt=30; //让蜂鸣器“短鸣”一声
vGu8BeepTimerFlag=1;
}
else
{
GtBigBufferUsart.u8Step=3; //返回上一步,重发当前段的数据
}
}
else if(0==vGu16BigBufferUsartTimerCnt) //当前批次在等待接收返回数据时,超时

{
GtBigBufferUsart.u8ReSendCnt++;
if(GtBigBufferUsart.u8ReSendCnt>=SCu8ReSendCntMax) //大于最大的重发次数
{
GtBigBufferUsart.u8Step=0;
GtBigBufferUsart.u8Start=0; //结束当前的过程通讯
GtBigBufferUsart.u8Status=2; //对外宣布“通讯失败”
vGu8BeepTimerFlag=0;
vGu16BeepTimerCnt=30; //让蜂鸣器“短鸣”一声
vGu8BeepTimerFlag=1;
}
else
{
GtBigBufferUsart.u8Step=3; //返回上一步,重发当前段的数据
}
}
break;
}
}
/* 注释二:
* 整个项目中只有一个“发送的队列驱动涵数”,负责“通讯管道的占用”的分配,负责数据的具体发
* 送。当同时存在很多“待发送”的请求指令时,此函数会根据“if ,else if...”的优先级,像队列一
* 样安排各指令发送的先后顺序,确保各指令不会发生冲突。
*/
void QueueSend(void) //发送的队列驱动涵数
{
static unsigned char Su8Step=0;
switch(Su8Step)
{
case 0: //分派即将要发送的任务
if(1==GtBigBufferUsart.u8QueueSendTrig)
{
GtBigBufferUsart.u8QueueSendTrig=0; //及时清零。驱动层,不管结果,只发一次。
Gu8QueueReceUpdate=0; //接收应答数据的状态恢复初始值
//发送带指令的数据
UsartSendMessage((const unsigned char *)&GtBigBufferUsart.u8QueueSendBuffer[0],
30);