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

for(i=0; i<u32SendSi ze;i++) // u32SendSize 为发 送的数据长度 { UsartSen dByteData(p Cu8SendMes sage[i]); / /基于“发送单字 节的最小 接口函数” 来实现的 } } unsigned c har Calcu lateXor(cons t unsigne d char *pCu8 Buffer, / /此处加 const 代表 数组“只读” …

100%1 / 836
}
}
}
else //发送数据引起的中
{
TI = 0; //及时清除发送中断的标志,避免一直无缘无故的进入中断。
Gu8SendByteFinish=1; //从 0 变成 1 通知主函数已经发送完一个字节的数据了。
}
}
void UsartSendByteData(unsigned char u8SendData) //发送一个字节的底层驱动函数
{
static unsigned int Su16TimeOutDelay; //超时处理的延时计时器
Gu8SendByteFinish=0; //在发送以字节之前,必须先把此全局变量的标志清零。
SBUF =u8SendData; //依靠寄存器 SBUF 作为载体发送一个字节的数据
Su16TimeOutDelay=0xffff; //超时处理的延时计时器装载一个相对合理的计时初始
while(Su16TimeOutDelay>0) //超时处理
{
if(1==Gu8SendByteFinish)
{
break; //如果 Gu8SendByteFinish 1,则发送一个字节完成,退出当前循环等待
}
Su16TimeOutDelay--; //超时计时器不断递
}
//Delay();//在实际应用中,当连续发送一堆数据时如果发现丢失数据,可以尝试在此增加延
}
//发送带协议的函数
void UsartSendMessage(const unsigned char *pCu8SendMessage,unsigned long u32SendMaxSize)
{
static unsigned long i;
static unsigned long *pSu32;
static unsigned long u32SendSize;
pSu32=(const unsigned long *)&pCu8SendMessage[2];
u32SendSize=*pSu32; //从带协议的数组中提取整包数组的有效发送长度
if(u32SendSize>u32SendMaxSize) //如果“有效发送长度”大于“最大限制的长度”,数据异常
{
return; //数据异常,直接退出当前函数,预防数组越界
}
for(i=0;i<u32SendSize;i++) //u32SendSize 为发送的数据长度
{
UsartSendByteData(pCu8SendMessage[i]); //基于“发送单字节的最小接口函数”来实现的
}
}
unsigned char CalculateXor(const unsigned char *pCu8Buffer, //此处加 const 代表数组“只读”
unsigned long u32BufferSize) //参与计算的数组的大小
{
unsigned long i;
unsigned char Su8Rece_Xor;
Su8Rece_Xor=pCu8Buffer[0]; //提取数据串第“i=0”个数据作为异或的原始数据
for(i=1;i<u32BufferSize;i++) //注意,这里是从第“i=1”个数据开始
{
Su8Rece_Xor=Su8Rece_Xor^pCu8Buffer[i]; //计算“异或”
}
return Su8Rece_Xor; //返回运算后的异或的计算结果
}
//比较两个数组的是否相等。返回 1 代表相等,返回 0 表不相等
unsigned char CmpTwoBufferIsSame(const unsigned char *pCu8Buffer_1,
const unsigned char *pCu8Buffer_2,
unsigned long u32BufferSize) //参与对比的数组的大小
{
unsigned long i;
for(i=0;i<u32BufferSize;i++)
{
if(pCu8Buffer_1[i]!=pCu8Buffer_2[i])
{
return 0; //只要有一个不相等,则返 0 并且退出当前函数
}
}
return 1; //相等
}
void KeyScan(void) //此函数放在定时中断里每 1ms 扫描一次
{
static unsigned char Su8KeyLock1; //1 号按键的自锁
static unsigned int Su16KeyCnt1; //1 号按键的计时器
//1 号按键
if(0!=KEY_INPUT1)//IO 是高电平,说明按键没有被按下,这时要及时清零一些标志位
{
Su8KeyLock1=0; //按键解锁
Su16KeyCnt1=0; //按键去抖动延时计数器清零,此行非常巧妙,是全场的亮点。
}
else if(0==Su8KeyLock1)//有按键按下,且是第一次被按下。
{
Su16KeyCnt1++; //累加定时中断次数
if(Su16KeyCnt1>=KEY_FILTER_TIME) //滤波的“稳定时间”KEY_FILTER_TIME,长度 25ms。
{
Su8KeyLock1=1; //按键的自锁,避免一直触
vGu8KeySec=1; //触发 1 号键
}
}
}
void T0_time() interrupt 1
{
VoiceScan();
KeyScan();
if(1==vGu8BigBufferUsartTimerFlag&&vGu16BigBufferUsartTimerCnt>0) //过程控制的超时定时器
{
vGu16BigBufferUsartTimerCnt--;
}
if(1==vGu8QueueSendTimerFlag&&vGu16QueueSendTimerCnt>0) //队列发送的超时定时器
{
vGu16QueueSendTimerCnt--;
}
if(1==vGu8ReceTimeOutFlag&&vGu16ReceTimeOutCnt>0) //通讯过程中字节之间的超时定时
{
vGu16ReceTimeOutCnt--;
}
TH0=0xfc;
TL0=0x66;
}
void SystemInitial(void)
{
unsigned char u8_TMOD_Temp=0;
//以下是定时 0 的中断的配