倒计时100分钟,2个共阴数码管,导入后显示8个8,想要达到图2那样,程序应该怎样改?求各位大佬帮忙
单片机源程序如下:
- #include<stc15.h>
- #include <REGX51.H>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define duan P1 //段选
- #define wei P3 //位选
- sbit key1 = P2^3; //设置
- sbit key2 = P2^4; //加
- sbit key3 = P2^5; //减
- sbit key4 = P2^6; //启动
- sbit key5 = P2^7; //手动
- sbit out = P2^2; //输出控制 ,低电平有效
- sbit di = P2^0; //蜂鸣器
- void Delay100ms() //@11.0592MHz
- {
- unsigned char i, j, k;
- _nop_();
- _nop_();
- i = 5;
- j = 52;
- k = 195;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
- bit flag=0,flag1=0,shan=0;
- uchar knum,shan_cont,i;
- uchar shi=0,fen=0,miao=0; //时分秒
- uint cont,cont1,cont2;
- uchar code duanma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴段码表
- // 0 1 2 3 5 6 7 8 9
- uchar code weima[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //位码 加反相器用
- // 1 2 3 4 5 6 7 8
- uchar LedBuff[]={0,0,0,0,0,0,0,0}; //数码管显示缓冲区
- void init() //定时器初始化
- {
- TMOD |= 0x01; //设置定时器0为工作方式1(M1M0为01)
- TH0 = (65536-1000)/256; //1ms初值 @12MHz
- TL0 = (65536-1000)%256;
- EA = 1; //开总中断
- ET0 = 1; //开定时器0中断
- TR0 = 1; //启动定时器0
- }
- void dis() //显示函数
- {
- LedBuff[0] = duanma[miao%10];
- LedBuff[1] = duanma[miao/10];
- LedBuff[2] = 0x40;
- LedBuff[3] = duanma[fen%10];
- LedBuff[4] = duanma[fen/10];
- LedBuff[5] = 0x40;
- LedBuff[6] = duanma[shi%10];
- LedBuff[7] = duanma[shi/10];
- }
- void keysan() //按键扫描函数
- {
- static bit kf1=0,kf2=0,kf3=0; //自锁标志,这里一定要加static(或者用全局变量),否则按键不灵
- static uint i=0,j=0,k=0,l=0,m=0; //消抖延时变量
- //////////////////////////////////////启动/暂停键//////////////////////////////////////
- if(knum==0) //只要时分秒都不等于0
- {
- if(key4 == 1) //启动 暂停键
- {
- m=0; //按键消抖计时变量清零
- kf2=0; //按键自锁标志清零
-
- }
- else if(kf2 == 0 ) //有按键按下,且是第一次被按下
- {
-
- ++m; //消抖
- if( (m>20) && ((miao != 0) || (fen != 0) || (shi != 0)) )
- {
- //时分秒都为0时,不能启动输出,只要其中之一不为0,就能启动输出
- m=0; //按键消抖计时变量清零
- kf2=1; //自锁按键置位,避免一直触发
- flag = !flag; //启动、暂停计时标志
- out = !out; //LED状态取反
- }
- }
- }
- //////////////////////////////////////启动/暂停键//////////////////////////////////////
- if(out==1) //加这句,只有在输出关闭的时候,才能设置计时时间,在倒计时的过程中是不能设置的
- {
- if(key1==1) //设置 //IO是高电平,说明按键没有被按下,这时要及时清零一些标志位
- {
-
- i=0; //按键消抖计时变量清零
- kf1=0; //按键自锁标志清零
- }
- else if(kf1 == 0) //有按键按下,且是第一次被按下
-
- {
-
- ++i; //消抖
- if(i>12)
- {
- i=0; //按键消抖计时变量清零
- kf1=1; //自锁按键置位,避免一直触发
- knum++; //调节时分秒--->123
- if(knum==4) knum = 0; //按第四次关闭设置
- }
- }
- }
- //////////////////////////////////////加1按键//////////////////////////////////////
- if(key2==0) //加1按键 快速加数
- {
- j++;
- if(j >= 3000) //长按,数码管扫描放中断里面,这里的值就要取得大才行
- { //因为没用delay延时,CPU跑的很快
- if(knum==1)
- {
- miao++; //秒钟加1
- if(miao==60) miao = 0; //超过60s变成0
- }
-
- if(knum==2)
- {
- fen++; //分钟加1
- if(fen==60) fen=0; //超过60变0
- }
-
- if(knum==3)
- {
- shi++; //小时加1
- if(shi==24) shi=0; //超过24变0
- }
-
- j=1000; //这里j的值可以设置连加的快慢,j的值越大就越快
- } //因为初值越大,加到3000的时间就越短
- }
- else //慢速加数
- {
- if(j>500 && j<3000)
- {
- if(knum==1)
- {
- miao++; //秒钟加1
- if(miao==60) miao = 0; //超过60s变成0
- }
-
- if(knum==2)
- {
- fen++; //分钟加1
- if(fen==60) fen=0; //超过60变0
- }
-
- if(knum==3)
- {
- shi++; //小时加1
- if(shi==24) shi=0; //超过24变0
- }
- j=0;
-
- }
- }
- //////////////////////////////////////减1按键//////////////////////////////////////
- if(key3==0) //减1按键 快速减数
- {
- k++;
- if(k >= 3000) //长按,数码管扫描放中断里面,这里的值就要取得大才行
- { //因为没用delay延时,CPU跑的很快
- if(knum==1)
- {
- miao--; //秒钟减1
- if(miao==255) miao = 59; //小于0就等于59
-
- }
- if(knum==2)
- {
- fen--; //分钟减1
- if(fen==255) fen=59; //小于0就等于59
-
- }
- if(knum==3)
- {
- shi--; //时钟减1
- if(shi==255) shi=23; //小于0就等于23
-
- }
- k=1000;
- }
- }
- else
- {
- if(k>500 && k<3000)
-
- {
- if(knum==1)
- {
- miao--; //秒钟减1
- if(miao==255) miao = 59; //小于0就等于59
-
- }
- if(knum==2)
- {
- fen--; //分钟减1
- if(fen==255) fen=59; //小于0就等于59
-
- }
- if(knum==3)
- {
- shi--; //时钟减1
- if(shi==255) shi=23; //小于0就等于23
-
- }
- }
- k=0; //消抖变量清零,为下次按键做准备
- }
- ////////////////////////////////////////////////////////////////////////////
- }
- void main()
- {
- init(); //定时器初始化
- out = 1;
- P1M0=0xff;
- P1M1=0x00;
- while(1)
- {
- keysan(); //按键扫描函数
- dis(); //显示函数
- if(shi==0 && fen==0 && miao==0 && flag == 1 ) //倒计时时间到
- {
- flag=0; //停止计时
- flag1=1; //启动蜂鸣器标志置1
- out=1; //关闭输出
- }
- }
- }
- void timer() interrupt 1
- {
- TH0 = (65536-1000)/256; //1毫秒初值
- TL0 = (65536-1000)%256;
- //////////////////////////////////////1s计时//////////////////////////////////////
- if(flag)
- {
- cont++;
- if(cont == 1000) //1s到
- {
- cont = 0; //清0
- miao--; //秒数减1
- if(miao==255) //如果小于0,就是59
- {
- miao=59;
- fen--; //分钟数减1
- if(fen==255) //如果小于0,就是59
- {
- fen=59;
- shi--; //小时减1
- if(shi==255) shi=0; //时钟小于0,就是0
- if(shi==0) fen=59; //时钟小于0,就是255
- if(fen==0 && shi==0) fen=0;//时钟分钟都为0,就是0
- }
- }
- }
- }
- //////////////////////////////////////蜂鸣器控制//////////////////////////////////////
- if(flag1) //倒计时时间到,启动蜂鸣器
- {
- cont1++;
- if(cont1==500) //500ms蜂鸣器响一次
- {
- cont1=0;
- di=!di;
- cont2++;
- if(cont2==20)//500*20=10000ms=10s,蜂鸣器响10s后停止
- {
- cont2=0;
- flag1=0;
- }
- }
- }
- //////////////////////////////////////启动/暂停键//////////////////////////////////////
- if(knum != 0)
- {
- shan_cont++;
- if(shan_cont==100) //设置时,100ms闪烁时间 可根据实际效果调整
- {
- shan_cont=0;
- shan = !shan;
- }
- }
- /**********************************数码管扫描函数**********************************/
- i++; //挨个显示
- if(i>=8) i=0; //清0
- duan = 0x00;
- switch(i)
- {
- case 0:
- if(knum==1) //如果设置键第一次按下
- {
- if(shan==1) {wei = 0x00; duan = LedBuff[0];} //设置秒位闪烁
-
- else {wei = weima[0]; duan = LedBuff[0];}
- }
- else{wei = weima[0]; duan = LedBuff[0];} break; //否则正常显示
- case 1:
- if(knum==1) //如果设置键第一次按下
- {
- if(shan==1){wei = 0x00; duan = LedBuff[1];} //设置秒位闪烁
- else{wei = weima[1]; duan = LedBuff[1];}
- }
- else{wei = weima[1]; duan = LedBuff[1];} break; //否则正常显示
- case 2: wei = weima[2]; duan = LedBuff[2]; break; //显示-
- case 3:
- if(knum==2) //如果设置键第二次按下
- {
- if(shan==1){wei = 0x00; duan = LedBuff[3];} //设置分位闪烁
- else{wei = weima[3]; duan = LedBuff[3];}
- }
- else{wei = weima[3]; duan = LedBuff[3];} break;//否则正常显示
- case 4:
- if(knum==2) //如果设置键第二次按下
- {
- if(shan==1){wei = 0x00; duan = LedBuff[4];} //设置分位闪烁
- else{wei = weima[4]; duan = LedBuff[4];}
- }
- else{wei = weima[4]; duan = LedBuff[4];} break; //否则正常显示
- case 5: wei = weima[5]; duan = LedBuff[5]; break; //显示-
- case 6:
- if(knum==3) //如果设置键第三次按下
- {
- if(shan==1){wei = 0x00; duan = LedBuff[6];} //设置时位闪烁
- else{wei = weima[6]; duan = LedBuff[6];}
- }
- else{wei = weima[6]; duan = LedBuff[6];} break;//否则正常显示
- case 7:
- if(knum==3) //如果设置键第三次按下
- {
- if(shan==1){wei = 0x00; duan = LedBuff[7];} //设置时位闪烁
- else{wei = weima[7]; duan = LedBuff[7];}
- }
- else{wei = weima[7]; duan = LedBuff[7];} break;//否则正常显示
- default: break;
- }
复制代码
|