从单片机基础到程序框架(全集 2019pdf版).pdf - 第620页
unsigned c har Gu8Ru nStatus=0; / /当前倒计时 的状态。0 代表停 止,1 代表 正在工作中 unsigned c har Gu8Wd Update=1; //开机 默认整屏更新 一次显示。此 变量在 显示框架中是 非常重要的变 量 volatile u nsigned c har vGu8Disp lay_Righ_ 4=1; //显示“1” ,跟 v Gu32Cou ntdownTimerC nt …

sbit KEY_INPUT1=P2^2;
sbit KEY_INPUT2=P2^1;
sbit P1_0=P1^0;
sbit P1_1=P1^1;
sbit P1_2=P1^2;
sbit P1_3=P1^3;
sbit P3_4=P3^4;
//数码管转换表
code unsigned char Cu8DigTable[]=
{
0x3f, //0 序号 0
0x06, //1 序号 1
0x5b, //2 序号 2
0x4f, //3 序号 3
0x66, //4 序号 4
0x6d, //5 序号 5
0x7d, //6 序号 6
0x07, //7 序号 7
0x7f, //8 序号 8
0x6f, //9 序号 9
0x00, //不显示 序号 10
};
//数码管底层驱动扫描的软件定时器
volatile unsigned char vGu8ScanTimerFlag=0;
volatile unsigned int vGu16ScanTimerCnt=0;
//倒计时的软件定时器,注意,这里是 unsigned long 类型,范围是 0 到 4294967295 毫秒
volatile unsigned char vGu8CountdownTimerFlag=0;
volatile unsigned long vGu32CountdownTimerCnt=10000; //开机默认显示初始值 10.000 秒
//数码管上层每 10ms 就定时刷新一次显示的软件定时器。用于及时更新显示秒表当前的实时数值
volatile unsigned char vGu8UpdateTimerFlag=0;
volatile unsigned int vGu16UpdateTimerCnt=0;
//蜂鸣器的软件定时器
volatile unsigned char vGu8BeepTimerFlag=0;
volatile unsigned int vGu16BeepTimerCnt=0;
unsigned char Gu8RunStart=0; //应用程序的总启动
unsigned char Gu8RunStep=0; //应用程序的总运行步骤。建议跟 vGu8RunStart 成双成对出现

unsigned char Gu8RunStatus=0; //当前倒计时的状态。0 代表停止,1 代表正在工作中
unsigned char Gu8WdUpdate=1; //开机默认整屏更新一次显示。此变量在显示框架中是非常重要的变量
volatile unsigned char vGu8Display_Righ_4=1; //显示“1”,跟 vGu32CountdownTimerCnt 高位一致
volatile unsigned char vGu8Display_Righ_3=0;
volatile unsigned char vGu8Display_Righ_2=0;
volatile unsigned char vGu8Display_Righ_1=0;
volatile unsigned char vGu8Display_Righ_Dot_4=0;
volatile unsigned char vGu8Display_Righ_Dot_3=1; //开机默认保留显示 2 个小数点
volatile unsigned char vGu8Display_Righ_Dot_2=0;
volatile unsigned char vGu8Display_Righ_Dot_1=0;
volatile unsigned char vGu8KeySec=0;
void main()
{
SystemInitial();
Delay(10000);
PeripheralInitial();
while(1)
{
KeyTask(); //按键的任务函数
DisplayTask(); //数码管显示的上层任务函数
RunTask(); //倒计时的应用程序
}
}
void KeyTask(void) //按键的任务函数
{
if(0==vGu8KeySec)
{
return;
}
switch(vGu8KeySec)
{
case 1: //复位按键
Gu8RunStatus=0; //倒计时返回停止的状态
Gu8RunStart=0; //倒计时的运行步骤的停止
Gu8RunStep=0; //总运行步骤归零。建议跟 vGu8RunStart 成双成对出现

vGu8CountdownTimerFlag=0; //禁止倒计时开始(而 Gu8RunStart 是启动开关,不矛盾)
vGu32CountdownTimerCnt=10000; //倒计时的软件定时器恢复初始值 10.000 秒
Gu8WdUpdate=1; //整屏更新一次显示
vGu8KeySec=0;
break;
case 2: //启动的按键
if(0==Gu8RunStatus) //在停止状态下
{
vGu8CountdownTimerFlag=0;
vGu32CountdownTimerCnt=10000; //初始值是 10.000 秒
vGu8CountdownTimerFlag=1; //允许倒计时的软件定时器的启动
Gu8RunStatus=1; //倒计时处于工作状态(并且,这一瞬间才正式启动倒计时)
Gu8RunStart=1; //倒计时的运行步骤的总开关开启
Gu8RunStep=0; //总运行步骤归零。建议跟 vGu8RunStart 成双成对出现
Gu8WdUpdate=1; //整屏更新一次显示,确保在启动的时候能显示到最新的数据
}
vGu8KeySec=0;
break;
}
}
void DisplayTask(void) //数码管显示的上层任务函数
{
//需要借用的中间变量,用来拆分数据位。
static unsigned char Su8Temp_4,Su8Temp_3,Su8Temp_2,Su8Temp_1; //需要借用的中间变量
if(1==Gu8WdUpdate) //如果需要整屏更新
{
Gu8WdUpdate=0; //及时清零,只更新一次显示即可,避免一直进来更新显示
//先分解数据,注意,这里分解的时候,“先整除后求余”必须用一行代码一气呵成,不能拆
//分成两行代码,否则会有隐患会有 bug。除非,把四个临时变都改成 unsigned long 类型。