从单片机基础到程序框架(全集 2019pdf版).pdf - 第831页
break; case 0x02: //返回 下位机的 分段数据 Gu8Rece_Xo r=Gu8Rece Buffer[Gu32R eceDataLe ngth-1]; //提取接收 到的“ 异或” Su8Rece_Xo r=Calcula teXor(Gu8Rec eBuffer,G u32ReceDataL ength-1); / /计算“异或 ” if(Su8Rece _Xor!=Gu8 Rece_Xor) //验证 “异或” …

{
Gu8ReceFeedDog=0;
vGu8ReceTimeOutFlag=0;
vGu16ReceTimeOutCnt=RECE_TIME_OUT;//更新一次“超时检测的定时器”的初值
vGu8ReceTimeOutFlag=1;
}
else if(Gu8ReceStep>0&&0==vGu16ReceTimeOutCnt) //超时,并且步骤不在接头暗号的步骤
{
Gu8ReceStep=0; //串口接收数据的中断函数及时切换回接头暗号的步骤
}
if(1==Gu8FinishFlag) //1 代表已经接收完毕一串新的数据,需要马上去处理
{
switch(Gu8ReceType) //接收到的数据类型
{
case 0x01: //返回下位机的数组容量的大小
Gu8Rece_Xor=Gu8ReceBuffer[Gu32ReceDataLength-1]; //提取接收到的“异或”
Su8Rece_Xor=CalculateXor(Gu8ReceBuffer,Gu32ReceDataLength-1); //计算“异或”
if(Su8Rece_Xor!=Gu8Rece_Xor) //验证“异或”,如果不相等,退出当前 switch
{
break; //退出当前 switch
}
GtBigBufferUsart.u8QueueSendBuffer[0]=0xeb; //数据头
GtBigBufferUsart.u8QueueSendBuffer[1]=0x01; //数据类型 返回数组容量的大小
pSu32Data=(unsigned long *)&GtBigBufferUsart.u8QueueSendBuffer[2];
*pSu32Data=11; //数据长度 本条指令的数据总长是 11 个字节
//提取数组容量的大小
pSu32Data=(unsigned long *)&GtBigBufferUsart.u8QueueSendBuffer[2+4];
*pSu32Data=sizeof(Cu8TestTable);//相当于*pSu32Data=57;sizeof 请参考第 69 节
//异或算法的函数
GtBigBufferUsart.u8QueueSendBuffer[10]=CalculateXor(GtBigBufferUsart.u8QueueSendBuffer,
10); //最后一个字节不纳入计算
//队列驱动函数的状态 0 为初始状态 1 为通讯成功 2 为通讯失败
GtBigBufferUsart.u8QueueStatus=0; //队列驱动函数的通讯状态
GtBigBufferUsart.u8QueueSendTrig=1;//队列驱动函数的发送的启动
Gu8QueueReceUpdate=1; //告诉“队列驱动函数”此发送指令无需等待上位机的应答

break;
case 0x02: //返回下位机的分段数据
Gu8Rece_Xor=Gu8ReceBuffer[Gu32ReceDataLength-1]; //提取接收到的“异或”
Su8Rece_Xor=CalculateXor(Gu8ReceBuffer,Gu32ReceDataLength-1); //计算“异或”
if(Su8Rece_Xor!=Gu8Rece_Xor) //验证“异或”,如果不相等,退出当前 switch
{
break; //退出当前 switch
}
pSu32Data=(unsigned long *)&Gu8ReceBuffer[6]; //数据转换。
Su32CurrentAddr=*pSu32Data; //读取的起始地址
pSu32Data=(unsigned long *)&Gu8ReceBuffer[6+4]; //数据转换。
Su32CurrentSize=*pSu32Data; //读取的发送的数据量
GtBigBufferUsart.u8QueueSendBuffer[0]=0xeb; //数据头
GtBigBufferUsart.u8QueueSendBuffer[1]=0x02; //数据类型 返回分段数据
pSu32Data=(unsigned long *)&GtBigBufferUsart.u8QueueSendBuffer[2];
*pSu32Data=6+4+4+Su32CurrentSize+1; //数据总长度
pSu32Data=(unsigned long *)&GtBigBufferUsart.u8QueueSendBuffer[2+4];
*pSu32Data=Su32CurrentAddr; //返回接收到的起始地址
pSu32Data=(unsigned long *)&GtBigBufferUsart.u8QueueSendBuffer[2+4+4];
*pSu32Data=Su32CurrentSize; //返回接收到的当前批次的数据量
for(i=0;i<Su32CurrentSize;i++)
{
//装载即将要发送的分段数据
GtBigBufferUsart.u8QueueSendBuffer[6+4+4+i]=Cu8TestTable[Su32CurrentAddr+i];
}
//异或算法的函数
GtBigBufferUsart.u8QueueSendBuffer[6+4+4+Su32CurrentSize]=
CalculateXor(GtBigBufferUsart.u8QueueSendBuffer, 6+4+4+Su32CurrentSize);
//队列驱动函数的状态 0 为初始状态 1 为通讯成功 2 为通讯失败
GtBigBufferUsart.u8QueueStatus=0; //队列驱动函数的通讯状态
GtBigBufferUsart.u8QueueSendTrig=1;//队列驱动函数的发送的启动

Gu8QueueReceUpdate=1; //告诉“队列驱动函数”此发送指令无需等待上位机的应答
break;
}
Gu8FinishFlag=0; //上面处理完数据再清零标志,为下一次接收新的数据做准备
}
}
void UsartTask(void) //串口收发的任务函数,放在主函数内
{
QueueSend(); //发送的队列驱动涵数
ReceDataHandle(); //接收数据后的处理涵数
}
void usart(void) interrupt 4 //串口接发的中断函数,中断号为 4
{
if(1==RI) //接收完一个字节后引起的中断
{
RI = 0; //及时清零,避免一直无缘无故的进入中断。
if(0==Gu8FinishFlag) //1 代表已经完成接收了一串新数据,并且禁止接收其它新的数据
{
Gu8ReceFeedDog=1; //每接收到一个字节的数据,此标志就置 1 及时更新定时器的值。
switch(Gu8ReceStep)
{
case 0: //“前部分的”数据头。接头暗号的步骤。
Gu8ReceBuffer[0]=SBUF; //直接读取刚接收完的一个字节的数据。
if(0xeb==Gu8ReceBuffer[0]) //等于数据头 0xeb,接头暗号吻合。
{
Gu32ReceCnt=1; //接收缓存的下标
Gu8ReceStep=1; //切换到下一个步骤,接收其它有效的数据
}
break;
case 1: //“前部分的”数据类型和长度
Gu8ReceBuffer[Gu32ReceCnt]=SBUF; //直接读取刚接收完的一个字节的数据。
Gu32ReceCnt++; //每接收一个字节,数组下标都自加 1,为接收下一个数据做准备
if(Gu32ReceCnt>=6) //前 6 个数据。接收完了“数据类型”和“数据长度”。
{
Gu8ReceType=Gu8ReceBuffer[1]; //提取“数据类型”
//以下的数据转换,在第 62 节讲解过的指针法
pu32Data=(unsigned long *)&Gu8ReceBuffer[2]; //数据转换
Gu32ReceDataLength=*pu32Data; //提取“数据长度”
if(Gu32ReceCnt>=Gu32ReceDataLength) //靠“数据长度”来判断是否完成