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

GtBigBuffe rUsart.u8 Step=1; //切换到下一 步 } break; //-------- ---先发送“ 读取下位机 的数组容量的 大小的指令” -------- ------------ - //-------- ---EB 01 00 0 0 00 07 ED -- ----------- -------- case 1: GtBigBuf ferUsart.u8 QueueSendB uffer[0]=…

100%1 / 836
}
void KeyTask(void) //按键任务函数,放在主函数内
{
if(0==vGu8KeySec)
{
return; //按键的触发序号是 0 意味着无按键触发,直接退出当前函数,不执行此函数下面的代码
}
switch(vGu8KeySec) //根据不同的按键触发序号执行对应的代码
{
case 1: //1 号按键。K1 的独立按键
//GtBigBufferUsart.u8Start 在开机初始化函数里必须初始化 0!这一步很关键!
if(0==GtBigBufferUsart.u8Start) //只有在还没有启动的情况下,才能启动
{
GtBigBufferUsart.u8Status=0; //通讯过程的状态 0 为初始状态
GtBigBufferUsart.u8Step=0; //通讯过程的步骤 0 为从当前开始的步骤
GtBigBufferUsart.u8Start=1; //通讯过程的启
}
vGu8KeySec=0; //响应按键服务处理程序后,按键编号必须清零,避免一致触
break;
}
}
/* 注释一:
* 每一个通讯事件都对应的一个独立的“通讯过程的控制涵数”,一个系统中有多少个通讯事件,就存在
* 多少个“通讯过程的控制涵数”。该函数负责某个通讯事件从开始到结束的整个过程。比如本节项目,
* 在通讯过程中,如果发现接收到的数据错误,则继续启动重发的机制。当发现接收到的累加字节数等于
* 预期想要接收的数量时,则结束这个通讯的事件
*/
void BigBufferUsart(void) //读取下位机大数组的“通讯过程的控制涵数”
{
static const unsigned char SCu8ReSendCntMax=3; //重发的次数
static unsigned long *pSu32Data; //用于数据与数组转换的指针
switch(GtBigBufferUsart.u8Step) //过程控制,我首选 switch 语句!
{
case 0:
if(1==GtBigBufferUsart.u8Start) //通讯过程的启动
{
//根据实际项目需要,在此 0 步骤里可以添加一些初始化相关的数据
GtBigBufferUsart.u8ReSendCnt=0; //重发计数器清零
GtBigBufferUsart.u8Step=1; //切换到下一
}
break;
//-----------先发送“读取下位机的数组容量的大小的指令”---------------------
//-----------EB 01 00 00 00 07 ED ---------------------
case 1:
GtBigBufferUsart.u8QueueSendBuffer[0]=0xeb; //数据
GtBigBufferUsart.u8QueueSendBuffer[1]=0x01; //数据类型 读取数组容量大小
pSu32Data=(unsigned long *)&GtBigBufferUsart.u8QueueSendBuffer[2];
*pSu32Data=7; //数据长度 本条指令的数据总长是 7 个字节
//异或算法的函数
GtBigBufferUsart.u8QueueSendBuffer[6]=CalculateXor(GtBigBufferUsart.u8QueueSendBuffer,
6) ; //最后一个字节不纳入计算
//队列驱动函数的状态 0 为初始状态 1 为通讯成功 2 为通讯失败
GtBigBufferUsart.u8QueueStatus=0; //队列驱动函数的通讯状态
GtBigBufferUsart.u8QueueSendTrig=1;//队列驱动函数的发送的启
vGu8BigBufferUsartTimerFlag=0;
vGu16BigBufferUsartTimerCnt=2000;
vGu8BigBufferUsartTimerFlag=1; //过程控制的超时定时器的启动
GtBigBufferUsart.u8Step=2; //切换到下一步
break;
case 2: //发送之后,等待下位机返回的数据的状
if(1==GtBigBufferUsart.u8QueueStatus) //当前批次的接收到的数据成功
{
GtBigBufferUsart.u8ReSendCnt=0; //重发计数器清零
GtBigBufferUsart.u32AlreadySendSize=0; //实际已经发送的数据量清
GtBigBufferUsart.u32CurrentAddr=0; //当前批次需要发送的起始地址
GtBigBufferUsart.u32CurrentSize=10; //从当前批次起始地址开始发送的数据量
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=1; //返回上一步,重发当前段的数据
}
}
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=1; //返回上一步,重发当前段的数据
}
}
break;
//-----------接着发送“读取下位机的大数组的分段数据的指令”---------------------
//-----------EB 02 00 00 00 0F RR RR RR RR YY YY YY YY ZZ ---------------------
case 3:
GtBigBufferUsart.u8QueueSendBuffer[0]=0xeb; //数据
GtBigBufferUsart.u8QueueSendBuffer[1]=0x02; //数据类型 读取分段数据
pSu32Data=(unsigned long *)&GtBigBufferUsart.u8QueueSendBuffer[2];
*pSu32Data=15; //数据长度 本条指令的数据总长 15 个字
pSu32Data=(unsigned long *)&GtBigBufferUsart.u8QueueSendBuffer[2+4];
*pSu32Data=GtBigBufferUsart.u32CurrentAddr; //当前批次需要发送的起始地址
pSu32Data=(unsigned long *)&GtBigBufferUsart.u8QueueSendBuffer[2+4+4];
*pSu32Data=GtBigBufferUsart.u32CurrentSize; //从当前批次起始地址发送的数据
//异或算法的函数