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

void LedOp en(void) { P1_4=0; } void LedCl ose(void) { P1_4=1; } void Voice Scan(void ) { static u nsigned cha r Su8Lock= 0; if(1==vGu8 BeepTimer Flag&&vGu16B eepTimerC nt>0) { if(0==Su 8Lock) { Su8Lock=1; Bee…

100%1 / 836
CombinationKeyTask(); //组合按键任务函数
SingleKeyTask(); //单击按键任务函数
}
}
void T0_time() interrupt 1
{
VoiceScan();
KeyScan(); //按键识别的驱动函
TH0=0xfc;
TL0=0x66;
}
void SystemInitial(void)
{
TMOD=0x01;
TH0=0xfc;
TL0=0x66;
EA=1;
ET0=1;
TR0=1;
}
void Delay(unsigned long u32DelayTime)
{
for(;u32DelayTime>0;u32DelayTime--);
}
void PeripheralInitial(void)
{
LedClose(); //初始化关闭 LED
}
void BeepOpen(void)
{
P3_4=0;
}
void BeepClose(void)
{
P3_4=1;
}
void LedOpen(void)
{
P1_4=0;
}
void LedClose(void)
{
P1_4=1;
}
void VoiceScan(void)
{
static unsigned char Su8Lock=0;
if(1==vGu8BeepTimerFlag&&vGu16BeepTimerCnt>0)
{
if(0==Su8Lock)
{
Su8Lock=1;
BeepOpen();
}
else
{
vGu16BeepTimerCnt--;
if(0==vGu16BeepTimerCnt)
{
Su8Lock=0;
BeepClose();
}
}
}
}
/* 注释一:
* 组合按键扫描的详细过程
* 第一步:平时只要 K1 K2 两个按键中有一个没有被按下时,按键的自锁标志,去抖动延时计数器
* 一直被清零
* 第二步:一旦两个按键都处于被按下的状态,去抖动延时计数器开始在定时中断函数里累加,在还没
* 累加到阀值 KEY_FILTER_TIME 时,如果在这期间由于受外界干扰或者按键抖动,而使其中一个
* IO 口突然瞬间触发成高电平,这个时候马上把延时计数 Su16CombinationKeyTimeCnt
* 清零了,这个过程非常巧妙,非常有效地去除瞬间的杂波干扰。
* 第三步:如果两个按键按下的时间超过了阀值 KEY_FILTER_TIME,马上把自锁标志 Su8CombinationKeyLock
* 1,防止按住两个按键不松手后一直触发。并把按键编 vGu8CombinationKeySec 赋值,
* 触发一次组合按键。
* 第四步:等其中一个按键松开后,自锁标志 Su8CombinationKeyLock 及时清零,为下一次自锁做准备
*/
void KeyScan(void) //此函数放在定时中断里每 1ms 扫描一次
{
static unsigned char Su8KeyLock1;
static unsigned int Su16KeyCnt1;
static unsigned char Su8KeyLock2;
static unsigned int Su16KeyCnt2;
static unsigned char Su8CombinationKeyLock; //组合按键的自锁
static unsigned int Su16CombinationKeyCnt; //组合按键的计时器
//K1 按键与 K2 按键的组合触发
if(0!=KEY_INPUT1||0!=KEY_INPUT2)//两个按键只要有一个按键没有按下,处于非组合按键”的状态。
{
Su8CombinationKeyLock=0; //组合按键解锁
Su16CombinationKeyCnt=0; //组合按键去抖动延时计数器清零,此行非常巧妙,是全场的亮点。
}
else if(0==Su8CombinationKeyLock)//两个按键被同时按下,且是第一次被按下。此行请看专题分析。
{
Su16CombinationKeyCnt++; //累加定时中断次数
if(Su16CombinationKeyCnt>=KEY_FILTER_TIME) //滤波的“稳定时间”KEY_FILTER_TIME。
{
Su8CombinationKeyLock=1; //组合按键的自锁,避免一直触发
vGu8CombinationKeySec=1; //触发 K1 K2 的组合键操作
}
}
//K1 按键的单击
if(0!=KEY_INPUT1)
{
Su8KeyLock1=0;
Su16KeyCnt1=0;
}
else if(0==Su8KeyLock1)
{
Su16KeyCnt1++;