从单片机基础到程序框架(全集 2019pdf版).pdf - 第430页
Delay(10 000); Peripher alInitial() ; while(1) { Combinat ionKeyTask( ); //组合按键任 务函数 SingleKe yTask(); / /单击按键任 务函数 } } void T0_ti me() inte rrupt 1 { VoiceSca n(); KeyScan( ); //按键 识别的驱动函 数 TH0=0xfc ; TL0=0x66 ; } void …

按键是分先后顺序的,比如,像电脑的复制快捷键(Ctrl+C),你必须先按住 Ctrl 再按住 C 此时“复制快捷
键”才有效,如果你先按住 C 再按住 Ctrl 此时“复制快捷键”无效。本节讲的例程就是要实现这个功能,
用 K1 代表 C 这类“字符数字键”,用 K2 代表 Ctrl 这类“辅助按键”,因此,要触发组合键(K2+K1),必须
先按住 K2 再按 K1 才有效。本节讲的例程功能如下:(1)K1 每单击一次,LED 要么从“灭”变成“亮”,要
么从“亮”变成“灭”,在两种状态之间切换。(2)如果先按住 K2 再按 K1,就认为构造了“电脑键盘式”组
合键,蜂鸣器发出“嘀”的一声。代码如下:
#include "REG52.H"
#define KEY_VOICE_TIME 50 //组合按键触发后发出的声音长度 50ms
#define KEY_FILTER_TIME 25 //按键滤波的“稳定时间”25ms
void T0_time();
void SystemInitial(void) ;
void Delay(unsigned long u32DelayTime) ;
void PeripheralInitial(void) ;
void BeepOpen(void);
void BeepClose(void);
void LedOpen(void);
void LedClose(void);
void VoiceScan(void);
void KeyScan(void); //按键识别的驱动函数,放在定时中断里
void SingleKeyTask(void); //单击按键任务函数,放在主函数内
void CombinationKeyTask(void); //组合按键任务函数,放在主函数内
sbit P3_4=P3^4; //蜂鸣器
sbit P1_4=P1^4; //LED
sbit KEY_INPUT1=P2^2; //K1 按键识别的输入口。
sbit KEY_INPUT2=P2^1; //K2 按键识别的输入口。
volatile unsigned char vGu8BeepTimerFlag=0;
volatile unsigned int vGu16BeepTimerCnt=0;
unsigned char Gu8LedStatus=0; //记录 LED 灯的状态,0 代表灭,1 代表亮
volatile unsigned char vGu8SingleKeySec=0; //单击按键的触发序号
volatile unsigned char vGu8CombinationKeySec=0; //组合按键的触发序号
void main()
{
SystemInitial();

Delay(10000);
PeripheralInitial();
while(1)
{
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)
{
if(0==Gu8LedStatus)
{
LedClose();
}
else
{
LedOpen();
}

}
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();
}