数码管显⽰倒计时c语⾔程序,第32节:数码管中的倒计时程序开场⽩:
上⼀节讲了⼀⼆级菜单的综合程序,这⼀节要教会⼤家三个知识点:
第⼀个:通过本程序,继续加深理解按键与数码管的关联⽅法。
第⼆个:复习⼀下我在第五节教给⼤家的时间校正法。
第三个:继续加深熟悉鸿哥⾸次提出的“⼀⼆级菜单显⽰理论”:凡是⼈机界⾯显⽰,不管是数码管还是液晶屏,都可以把显⽰的内容分成不同的窗⼝来显⽰,每个显⽰的窗⼝中⼜可以分成不同的局部显⽰。其中窗⼝就是⼀级菜单,⽤ucWd变量表⽰。局部就是⼆级菜单,⽤ucPart来表⽰。不同的窗⼝,会有不同的更新显⽰变量ucWdXUpdate来对应,表⽰整屏全部更新显⽰。不同的局部,也会有不同的更新显⽰变量ucWdXPartYUpdate来对应,表⽰局部更新显⽰。
具体内容,请看源代码讲解。
(1)硬件平台:基于朱兆祺51单⽚机学习板。启动和暂停键对应S1键,复位键对应S5键。
(2)实现功能:按下启动暂停按键时,倒计时开始⼯作,再按⼀次启动暂停按键时,则暂停倒计时。在任何时候,按下复位按键,倒计时将暂停⼯作,并且恢复倒计时当前默认值99。
(3)源代码讲解如下:
#include "REG52.H"
#define const_voice_short40 //蜂鸣器短叫的持续时间
#define const_voice_long 200 //蜂鸣器长叫的持续时间
#define const_key_time120 //按键去抖动延时的时间
#define const_key_time220 //按键去抖动延时的时间
#define const_dpy_time_half200//数码管闪烁时间的半值
#define const_dpy_time_all 400//数码管闪烁时间的全值 ⼀定要⽐const_dpy_time_half ⼤
/* 注释⼀:
* 如何知道1秒钟需要多少个定时中断?
* 这个需要编写⼀段⼩程序测试,得到测试的结果后再按⽐例修正。
* 步骤:
* 第⼀步:在程序代码上先写⼊1秒钟⼤概需要200个定时中断。
* 第⼆步:把程序烧录进单⽚机后,上电开始测试,⼿上同步打开⼿机⾥的秒表。
* 如果单⽚机倒计时跑完了99秒,⽽⼿机上的秒表才⾛了45秒。
* 第三步:那么最终得出1秒钟需要的定时中断次数是:const_1s=(200*99)/45=440
*/
#define const_1s440 //⼤概⼀秒钟所需要的定时中断次数
void initial_myself();
void initial_peripheral();
void delay_short(unsigned int uiDelayShort);
void delay_long(unsigned int uiDelaylong);
/
/驱动数码管的74HC595
void dig_hc595_drive(unsigned char ucDigStatusTemp16_09,unsigned char ucDigStatusTemp08_01); void display_drive(); //显⽰数码管字模的驱动函数
void display_service(); //显⽰的窗⼝菜单服务程序
//驱动LED的74HC595
void hc595_drive(unsigned char ucLedStatusTemp16_09,unsigned char ucLedStatusTemp08_01); void T0_time();//定时中断函数
void key_service(); //按键服务的应⽤程序
void key_scan();//按键扫描函数 放在定时中断⾥
sbit key_sr1=P0^0; //对应朱兆祺学习板的S1键
sbit key_sr2=P0^1; //对应朱兆祺学习板的S5键
sbit key_gnd_dr=P0^4; //模拟独⽴按键的地GND,因此必须⼀直输出低电平
sbit beep_dr=P2^7; //蜂鸣器的驱动IO⼝
sbit led_dr=P3^5;//作为中途暂停指⽰灯 亮的时候表⽰中途暂停
sbit dig_hc595_sh_dr=P2^0; //数码管的74HC595程序
sbit dig_hc595_st_dr=P2^1;
sbit dig_hc595_ds_dr=P2^2;
sbit hc595_sh_dr=P2^3; //LED灯的74HC595程序
sbit hc595_st_dr=P2^4;
sbit hc595_ds_dr=P2^5;
unsigned char ucKeySec=0; //被触发的按键编号
unsigned intuiKeyTimeCnt1=0; //按键去抖动延时计数器
unsigned char ucKeyLock1=0; //按键触发后⾃锁的变量标志
unsigned intuiKeyTimeCnt2=0; //按键去抖动延时计数器
unsigned char ucKeyLock2=0; //按键触发后⾃锁的变量标志
unsigned intuiVoiceCnt=0;//蜂鸣器鸣叫的持续时间计数器
unsigned char ucDigShow8;//第8位数码管要显⽰的内容
unsigned char ucDigShow7;//第7位数码管要显⽰的内容
unsigned char ucDigShow6;//第6位数码管要显⽰的内容
unsigned char ucDigShow5;//第5位数码管要显⽰的内容
unsigned char ucDigShow4;//第4位数码管要显⽰的内容
unsigned char ucDigShow3;//第3位数码管要显⽰的内容
unsigned char ucDigShow2;//第2位数码管要显⽰的内容
unsigned char ucDigShow1;//第1位数码管要显⽰的内容
unsigned char ucDigDot8;//数码管8的⼩数点是否显⽰的标志
unsigned char ucDigDot7;//数码管7的⼩数点是否显⽰的标志
unsigned char ucDigDot6;//数码管6的⼩数点是否显⽰的标志
unsigned char ucDigDot5;//数码管5的⼩数点是否显⽰的标志
unsigned char ucDigDot4;//数码管4的⼩数点是否显⽰的标志
unsigned char ucDigDot3;//数码管3的⼩数点是否显⽰的标志
unsigned char ucDigDot2;//数码管2的⼩数点是否显⽰的标志
unsigned char ucDigDot1;//数码管1的⼩数点是否显⽰的标志
unsigned char ucDigShowTemp=0; //临时中间变量
unsigned char ucDisplayDriveStep=1;//动态扫描数码管的步骤变量
unsigned char ucWd=1;//本程序的核⼼变量,窗⼝显⽰变量。类似于⼀级菜单的变量。代表显⽰不同的窗⼝。unsigned char ucWd1Update=1; //窗⼝1更新显⽰标志
unsigned char ucCountDown=99;//倒计时的当前值
unsigned char ucStartFlag=0;//暂停与启动的标志位
unsigned intuiTimeCnt=0;//倒计时的时间计时器
unsigned char ucTemp1=0;//中间过渡变量
unsigned char ucTemp2=0;//中间过渡变量
unsigned char ucTemp3=0;//中间过渡变量
unsigned char ucTemp4=0;//中间过渡变量
unsigned char ucTemp5=0;//中间过渡变量
unsigned char ucTemp6=0;//中间过渡变量
unsigned char ucTemp7=0;//中间过渡变量
unsigned char ucTemp8=0;//中间过渡变量
/
/根据原理图得出的共阴数码管字模表
code unsigned char dig_table[]=
{
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
0x40,//- 序号11
0x73,//P 序号12
};
void main()
{
initial_myself();
delay_long(100);
initial_peripheral();
c语言如何去学while(1)
{
key_service(); //按键服务的应⽤程序
display_service(); //显⽰的窗⼝菜单服务程序
}
}
/* 注释⼆:
*鸿哥⾸次提出的"⼀⼆级菜单显⽰理论":
*凡是⼈机界⾯显⽰,不管是数码管还是液晶屏,都可以把显⽰的内容分成不同的窗⼝来显⽰,
*每个显⽰的窗⼝中⼜可以分成不同的局部显⽰。其中窗⼝就是⼀级菜单,⽤ucWd变量表⽰。
*局部就是⼆级菜单,⽤ucPart来表⽰。不同的窗⼝,会有不同的更新显⽰变量ucWdXUpdate来对应,
*表⽰整屏全部更新显⽰。不同的局部,也会有不同的更新显⽰变量ucWdXPartYUpdate来对应,表⽰局部更新显⽰。*/
void display_service() //显⽰的窗⼝菜单服务程序
{
//由于本程序只有⼀个窗⼝,读者在做实际项⽬的时候,可以省略switch(ucWd)
switch(ucWd)//本程序的核⼼变量,窗⼝显⽰变量。类似于⼀级菜单的变量。代表显⽰不同的窗⼝。
{
case 1: //显⽰窗⼝1的数据
if(ucWd1Update==1)//窗⼝1要全部更新显⽰
{
ucWd1Update=0;//及时清零标志,避免⼀直进来扫描
ucTemp8=10;//显⽰空
ucTemp7=10;//显⽰空
ucTemp6=10;//显⽰空
ucTemp5=10;//显⽰空
ucTemp4=10;//显⽰空
ucTemp3=10;//显⽰空
ucTemp2=ucCountDown/10;//倒计时的当前值
ucTemp1=ucCountDown%10;
ucDigShow8=ucTemp8;
ucDigShow7=ucTemp7;
ucDigShow6=ucTemp6;
ucDigShow5=ucTemp5;
ucDigShow4=ucTemp4;
ucDigShow3=ucTemp3;
if(ucCountDown<10)
{
ucDigShow2=10;
}
else
{
ucDigShow2=ucTemp2;
}
ucDigShow1=ucTemp1;
}
break;
}
}
void key_scan()//按键扫描函数 放在定时中断⾥
{
if(key_sr1==1)//IO是⾼电平,说明按键没有被按下,这时要及时清零⼀些标志位
{
ucKeyLock1=0; //按键⾃锁标志清零
uiKeyTimeCnt1=0;//按键去抖动延时计数器清零,此⾏⾮常巧妙,是我实战中摸索出来的。}
else if(ucKeyLock1==0)//有按键按下,且是第⼀次被按下
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论