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

Su8KeyLock 1=0; //按键 解锁 Su16KeyCnt 1=0; //按键 去抖动延时计 数器清零,此 行非常巧妙, 是全场 的亮点。 } else if(0= =Su8KeyLo ck1)//有按键按下 ,且是第一次 被按下。 { Su16KeyCnt 1++; //累加 定时中断次数 if(Su16Key Cnt1>=KEY _FILTER_TIME ) //滤波的“稳定 时间”K EY_FILT ER_TIME…

100%1 / 836
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 的中断的配
TMOD=0x01;
TH0=0xfc;
TL0=0x66;
EA=1;
ET0=1;
TR0=1;
//以下是串口接收中断的配
//串口的波特率与内置的定时器 1 直接相关,因此配置此定时器 1 就等效于配置波特率。
u8_TMOD_Temp=0x20; //即将把定时 1 设置为:工作方式 2,初值自动重装的 8 位定时器。
TMOD=TMOD&0x0f; //此寄存器低 4 位是跟定时器 0 相关, 4 位是跟定时 1 相关。先清零定时器 1。
TMOD=TMOD|u8_TMOD_Temp; //把高 4 位的定时器 1 填入 0x2,低 4 位的定时器 0 保持不变。
TH1=256-(11059200L/12/32/9600); //波特率为 9600。11059200 代表晶振 11.0592MHz,
TL1=256-(11059200L/12/32/9600); //L long 的长类型数据。根据芯片手册提供的计算公式
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)
{
GtBigBufferUsart.u8Start=0; //通讯过程的启动变量必须初始化为 0!这一步很关键!
}
void BeepOpen(void)
{
P3_4=0;
}
void BeepClose(void)