实例96 能预置初值的倒计时秒表 先Proteus仿真一下,确认有效。 ![]() ![]() 以上摘自张志良编著《80C51单片机仿真设计实例教程——基于Keil C和Proteus》清华大学出版社ISBN 978-7-302-41682-1,内有常用的单片机应用100案例,用于仿真实验操作,书中电路和程序设计有详细说明,电路与程序真实可靠可信可行,程序语句条条有注解。 |
本帖最后由 zl2168 于 2018-5-15 21:21 编辑 实例93 99.9秒秒表 先Proteus仿真一下,确认有效。 ![]() ![]() 以上摘自张志良编著《80C51单片机仿真设计实例教程——基于Keil C和Proteus》清华大学出版社ISBN 978-7-302-41682-1,内有常用的单片机应用100案例,用于仿真实验操作,书中电路和程序设计有详细说明,电路与程序真实可靠可信可行,程序语句条条有注解。若需99.99秒,硬件电路增加一位595。软件程序增加0.01s(10ms)计数器,并修改相应计数显示程序。 |
已解决问题,感谢各位大神的指导 |
HC6800-ES-V2.0 发表于 2018-5-15 08:25 你没有看清楚,楼主的程序是在8位数码管的实验板上从左至右只使用第5、6、7三个数码管显示。 |
wulin 发表于 2018-5-14 17:24 程序没什么大问题。 不过我认为你的显示函数中,显示第5位与显示第7位应该对调一下吧。 不可能100ms显示在s之前,对不对 |
//上电待令,按键计时开始,再按计时停止,再按清0,周而复始。 #include <reg51.h> #define uint unsigned int #define uchar unsigned char sbit LSA=P2^2; sbit LSB=P2^3; sbit LSC=P2^4;//连接译码器,选择点亮的数码管 sbit k3=P3^2; uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; uchar Cntus=0,Cnt100ms,Cnt1s=0;//中断计时变量 bit zantin=0; //暂停标志 /***********定时器初始化程序****************/ void Timer0Init(void) //2500微秒@12.000MHz { TMOD= 0x01; //设置定时器模式 TL0 = 0x3C; //设置定时初值 TH0 = 0xF6; //设置定时初值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 EA=1; //开总中断 ET0=1; //开定时器0中断 } /***********按键扫描程序****************/ void keyscan() { static uint count2=0,count1=0; //计数变量 static bit key_sign=0; //按键状态标志 if(k3==0) //检测输入如果为0 { count1++; //计数延时消抖 if((count1>=500)&&(key_sign==0))//检测按键如果为0 { key_sign=1; //按键状态标志置1,防止重复响应 count2++; if(count2>=3) count2=0; switch(count2) { case 0: Cntus=0; Cnt100ms=0; Cnt1s=0; break;//清0 case 1: zantin=1; break;//计时 case 2: zantin=0; break;//暂停 } } } else { count1=0; //计数变量清0 key_sign=0; //按键状态标志清0 } } void display()//显示程序 { static uchar i=0; P0=0x00;//消隐 switch(i) { case(0): LSA=0;LSB=0;LSC=1;P0=table[Cnt1s/10];i++; break;//显示第5位 case(1): LSA=1;LSB=0;LSC=1;P0=table[Cnt1s%10]|0x80;i++; break;//显示第6位 case(2): LSA=0;LSB=1;LSC=1;P0=table[Cnt100ms];i=0; break;//显示第7位 } } /***************主程序****************/ void main() { Timer0Init(); //定时器初始化 while(1) { keyscan(); //按键扫描 } } /**************中断服务程序*****************/ void timer0() interrupt 1//2500微秒@11.0592MHz { TL0 = 0x00; //设置定时初值 TH0 = 0xF7; //设置定时初值 Cntus++; //中断变量Cntus自+1 if(Cntus>=40) //10ms { Cntus=0; //清0 if(zantin==1) //暂停/启动 Cnt100ms++; //毫秒计数 if(Cnt100ms>=10) { Cnt100ms=0; Cnt1s++; //秒计数 if(Cnt1s>=60) Cnt1s=0; } } display(); //显示程序 } |
你的程序我简单看了一下,楼上的几位都没说到点子上。 问题在你的dingshi()子函数中。 你这个子函数中,有一个while(n),而n=1,那么,程序执行到此处,就“死”在这里了,死循环,直到你按下k3键,出现这条语句n=0;break;才能跳出来,才会有显示啊。 由于n=0了,所以,dingshi()子函数再也不执行了,所以,就没法看其它时间了。 秒表的按键,一定要用外部中断才行的,你的这个程序思路有点不对,所以我没有帮你改,改不了啊。 |
改大delay(i);,不能及时响应按键,建议按键采用外中断 |
改大delay(i);,时间太短频率高,显示不出 |