从单片机基础到程序框架(全集 2019pdf版) - 第623页
vGu16Updat eTimerCnt =10; //每 10ms 更新显示一 次当前 倒计时的时间 vGu8Update TimerFlag =1; Gu8RunStep =1; //跳转到每 1 0ms 更新显示一 次的步 骤里 break; case 1: //每 10 ms 更新一次显 示,确保实时 显示当前倒 计时的时 间 if(0==vG u16UpdateTi merCnt) //每 10 ms 更新显示一 次当前倒计时…

//Su8Temp_4 提取“十秒”位。
Su8Temp_4=vGu32CountdownTimerCnt/10000%10; //实际精度是 0.001 秒,但显示精度是 0.01 秒
//Su8Temp_3 提取“个秒”位。
Su8Temp_3=vGu32CountdownTimerCnt/1000%10; //实际精度是 0.001 秒,但显示精度是 0.01 秒
//Su8Temp_2 提取“百毫秒”位。
Su8Temp_2=vGu32CountdownTimerCnt/100%10; //实际精度是 0.001 秒,但显示精度是 0.01 秒
//Su8Temp_1 提取“十毫秒”位。
Su8Temp_1=vGu32CountdownTimerCnt/10%10; //实际精度是 0.001 秒,但显示精度是 0.01 秒
//判断数据范围,来决定最高位数码管是否需要显示。
if(vGu32CountdownTimerCnt<10000) //10.000 秒。实际 4 位数码管最大只能显示 99.99 秒
{
Su8Temp_4=10; //在数码管转换表里,10 代表一个“不显示”的数据
}
//上面先分解数据之后,再过渡需要显示的数据到底层驱动变量里,让过渡的时间越短越好
vGu8Display_Righ_4=Su8Temp_4; //过渡需要显示的数据到底层驱动变量
vGu8Display_Righ_3=Su8Temp_3;
vGu8Display_Righ_2=Su8Temp_2;
vGu8Display_Righ_1=Su8Temp_1;
vGu8Display_Righ_Dot_4=0;
vGu8Display_Righ_Dot_3=1; //保留显示 2 位小数点
vGu8Display_Righ_Dot_2=0;
vGu8Display_Righ_Dot_1=0;
}
}
void RunTask(void) //倒计时的应用程序
{
if(0==Gu8RunStart)
{
return; // 如果总开关处于停止状态,则直接退出当前函数,不执行该函数以下的其它代码
}
switch(Gu8RunStep)
{
case 0: //在这个步骤里,主要用来初始化一些参数
vGu8UpdateTimerFlag=0;

vGu16UpdateTimerCnt=10; //每 10ms 更新显示一次当前倒计时的时间
vGu8UpdateTimerFlag=1;
Gu8RunStep=1; //跳转到每 10ms 更新显示一次的步骤里
break;
case 1: //每 10ms 更新一次显示,确保实时显示当前倒计时的时间
if(0==vGu16UpdateTimerCnt) //每 10ms 更新显示一次当前倒计时的时间
{
vGu8UpdateTimerFlag=0;
vGu16UpdateTimerCnt=10; //重置定时器,为下一个 10ms 更新做准备
vGu8UpdateTimerFlag=1;
Gu8WdUpdate=1; //整屏更新一次显示当前倒计时的时间
if(0==vGu32CountdownTimerCnt) //如果倒计时的时间到,则跳转到结束的步骤
{
Gu8RunStep=2; //跳转到倒计时结束的步骤
}
}
break;
case 2: //倒计时结束的步骤
//Gu8RunStatus=0; //这行代码注释掉,让每次新启动之前都必须按一次 K1 复位按键才有效
Gu8RunStart=0; //倒计时的运行步骤的停止
Gu8RunStep=0; //总运行步骤归零。建议跟 vGu8RunStart 成双成对出现
vGu8BeepTimerFlag=0;
vGu16BeepTimerCnt=VOICE_TIME; //蜂鸣器发出“滴”一声
vGu8BeepTimerFlag=1;
Gu8WdUpdate=1; //整屏更新一次显示当前倒计时的时间
break;
}
}

void KeyScan(void) //按键底层的驱动扫描函数,放在定时中断函数里
{
static unsigned char Su8KeyLock1;
static unsigned int Su16KeyCnt1;
static unsigned char Su8KeyLock2;
static unsigned int Su16KeyCnt2;
if(0!=KEY_INPUT1)
{
Su8KeyLock1=0;
Su16KeyCnt1=0;
}
else if(0==Su8KeyLock1)
{
Su16KeyCnt1++;
if(Su16KeyCnt1>=KEY_FILTER_TIME)
{
Su8KeyLock1=1;
vGu8KeySec=1;
}
}
if(0!=KEY_INPUT2)
{
Su8KeyLock2=0;
Su16KeyCnt2=0;
}
else if(0==Su8KeyLock2)
{
Su16KeyCnt2++;
if(Su16KeyCnt2>=KEY_FILTER_TIME)
{
Su8KeyLock2=1;
vGu8KeySec=2;
}
}
}
void DisplayScan(void) //数码管底层的驱动扫描函数,放在定时中断函数里
{
static unsigned char Su8GetCode;
static unsigned char Su8ScanStep=1;
if(0==vGu16ScanTimerCnt)