从单片机基础到程序框架(全集 2019pdf版).pdf - 第555页
} } } } void KeySc an(void) //此函 数放在定时中 断里每 1 ms 扫描一次 { static unsig ned char Su8KeyL ock1; static unsig ned int Su1 6KeyCnt1; static unsig ned char Su8KeyL ock2; static unsig ned int Su1 6KeyCnt2; //【启动暂停 】按键 K1 的扫 描识别 …

for(;u32DelayTime>0;u32DelayTime--);
}
void PeripheralInitial(void)
{
//跑马灯处于初始化的状态
P1_4=0; //第 1 个灯亮
P1_5=1; //第 2 个灯灭
P1_6=1; //第 3 个灯灭
P3_3=1; //第 4 个灯灭
}
void BeepOpen(void)
{
P3_4=0;
}
void BeepClose(void)
{
P3_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();

}
}
}
}
void KeyScan(void) //此函数放在定时中断里每 1ms 扫描一次
{
static unsigned char Su8KeyLock1;
static unsigned int Su16KeyCnt1;
static unsigned char Su8KeyLock2;
static unsigned int Su16KeyCnt2;
//【启动暂停】按键 K1 的扫描识别
if(0!=KEY_INPUT1)
{
Su8KeyLock1=0;
Su16KeyCnt1=0;
}
else if(0==Su8KeyLock1)
{
Su16KeyCnt1++;
if(Su16KeyCnt1>=KEY_FILTER_TIME)
{
Su8KeyLock1=1;
vGu8KeySec=1; //触发 1 号键
}
}
//【停止】按键 K2 的扫描识别
if(0!=KEY_INPUT2)
{
Su8KeyLock2=0;
Su16KeyCnt2=0;
}
else if(0==Su8KeyLock2)
{
Su16KeyCnt2++;
if(Su16KeyCnt2>=KEY_FILTER_TIME)
{
Su8KeyLock2=1;
vGu8KeySec=2; //触发 2 号键
}
}

}
/* 注释一:
* 本节破题的关键:
* 在 KeyTask 和 RunTask 两个任务函数之间,主要是靠 Gu8RunStart 和 Gu8RunStatus 这两个
* 全局变量来传递信息。
*/
void KeyTask(void) //按键的任务函数,放在主函数内
{
if(0==vGu8KeySec)
{
return; //按键的触发序号是 0 意味着无按键触发,直接退出当前函数,不执行此函数下面的代码
}
switch(vGu8KeySec) //根据不同的按键触发序号执行对应的代码
{
case 1: //1 号按键。【启动暂停】按键 K1
if(0==Gu8RunStatus) //当跑马灯处于“停止”状态时
{
Gu8RunStart=1; //总开关“打开”。
Gu8RunStatus=1; //状态切换到“启动”状态
}
else if(1==Gu8RunStatus) //当跑马灯处于“启动”状态时
{
Gu8RunStatus=2; //状态切换到“暂停”状态
}
else //当跑马灯处于“暂停”状态时
{
Gu8RunStatus=1; //状态切换到“启动”状态
}
vGu8BeepTimerFlag=0;
vGu16BeepTimerCnt=KEY_VOICE_TIME; //触发按键后,发出固定长度的声音
vGu8BeepTimerFlag=1;
vGu8KeySec=0; //响应按键服务处理程序后,按键编号必须清零,避免一直触发
break;
case 2: //2 号按键。【停止】按键 K2
Gu8RunStart=0; //总开关“关闭”。