从单片机基础到程序框架(全集 2019pdf版).pdf - 第605页
vGu8Scan TimerFlag=1 ; } } void T0_ti me() inte rrupt 1 { DisplayS can(); if(1==vG u8ScanTimer Flag&&vGu1 6ScanTimerC nt>0) { vGu16Sca nTimerCnt-- ; } TH0=0xfc ; TL0=0x66 ; } void Syste mInitial( void) { P0=0x…

}
P0=Su8GetCode;
P1_0=1;
P1_1=0;
P1_2=1;
P1_3=1;
break;
case 3:
Su8GetCode=Cu8DigTable[vGu8Display_Righ_3];
if(1==vGu8Display_Righ_Dot_3) //如果打开了需要显示第 3 个数码管的小数点
{
Su8GetCode=Su8GetCode|0x80; //把第 7 位数据改为 1,显示小数点
}
P0=Su8GetCode;
P1_0=1;
P1_1=1;
P1_2=0;
P1_3=1;
break;
case 4:
Su8GetCode=Cu8DigTable[vGu8Display_Righ_4];
if(1==vGu8Display_Righ_Dot_4) //如果打开了需要显示第 4 个数码管的小数点
{
Su8GetCode=Su8GetCode|0x80; //把第 7 位数据改为 1,显示小数点
}
P0=Su8GetCode;
P1_0=1;
P1_1=1;
P1_2=1;
P1_3=0;
break;
}
Su8ScanStep++;
if(Su8ScanStep>4)
{
Su8ScanStep=1;
}
vGu8ScanTimerFlag=0;
vGu16ScanTimerCnt=SCAN_TIME;

vGu8ScanTimerFlag=1;
}
}
void T0_time() interrupt 1
{
DisplayScan();
if(1==vGu8ScanTimerFlag&&vGu16ScanTimerCnt>0)
{
vGu16ScanTimerCnt--;
}
TH0=0xfc;
TL0=0x66;
}
void SystemInitial(void)
{
P0=0x00;
P1_0=1;
P1_1=1;
P1_2=1;
P1_3=1;
TMOD=0x01;
TH0=0xfc;
TL0=0x66;
EA=1;
ET0=1;
TR0=1;
}
void Delay(unsigned long u32DelayTime)
{
for(;u32DelayTime>0;u32DelayTime--);
}
void PeripheralInitial(void)
{
}

第一百一十五节: 按键控制数码管的秒表。
【115.1 按键控制数码管的秒表。】
上图 115.1.1 数码管
上图 115.1.2 独立按键
本节通过一个秒表的小项目,让大家学会以下 4 个知识点:
(1)上层的界面显示框架几乎都要用到更新变量,更新变量包括整屏更新和局部更新,本节只用到整
屏更新。更新变量是用全局变量在函数之间传递信息。作用是,当有某个需要显示的数据发生改变的时候,
就要给更新变量置 1,让显示函数重新更新一次显示,确保最新的数据能及时显示出来,平时没有数据更新
改变的时候不用频繁更新显示避免占用 CPU 过多的时间。
(2)凡是需要显示数字的地方,都必须涉及如何把一个数据按“个十百千万...”的位逐个提取出来的
算法。这个算法比较简单,主要用“求余”和“求商”这两个运算语句就可以随心所欲的把数据位提取出来。
除此之外,还要学会如何用 if 语句判断数据的范围,来把高位尚未用到的某个数码管屏蔽,让该位数码管
只显示一个“不显示”的数据(避免直接显示一个 0)。
(3)我常把单片机程序简化成 4 个代表:按键(人机输入),数码管(人机界面),跑马灯(应用程序),
串口(通信)。本节的“应用程序”不是跑马灯,而是秒表。不管是跑马灯,还是秒表,都要用到一个总启
动 Gu8RunStart 和一个总运行步骤 Gu8RunStep。建议大家,总启动 Gu8RunStart 和总运行步骤 Gu8RunStep