wulin 发表于 2022-1-7 20:21 问题已解决,感谢您的宝贵建议 |
lkc8210 发表于 2022-1-7 22:08 问题已解决,感谢 |
uhl0 发表于 2022-1-7 13:01 if(key2==0)的else里缺了一对{} ![]() 这里应该是k ![]() |
本帖最后由 wulin 于 2022-1-7 20:23 编辑 uhl0 发表于 2022-1-7 09:40 数码管闪烁提示的实际视觉效果不如闪点好。给你改成数码管闪烁提示供参考 ![]() |
lkc8210 发表于 2022-1-7 10:19 #include<reg52.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};//共阴段码表 // 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(j>500 && j<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; 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; } } 感谢大佬回信,我听你的建议加了在if(key2==0)的else里加了短按判断if(j>500 && j<3000),秒表问题解决,但我时分显示也有这个问题,我改了几次发现不行不知道怎么改了 |
uhl0 发表于 2022-1-7 09:40 你是怎么改的? 上代码啊~ |
lkc8210 发表于 2022-1-6 00:09 大佬我现在秒表数码管显示正常了,但分钟和小时那里又乱闪了,是我后面的短按判断错了吗?求指点 |
谢谢大佬,刚好用上 |
![]()
|
lkc8210 发表于 2022-1-6 00:09 建议以采纳,谢谢大佬 |
uhl0 发表于 2022-1-5 19:48 以为你是说闪的太快 上Proteus一看 原来是乱闪 if(key2==0)的else里缺了短按判断if(j>500 && j<3000) |
lkc8210 发表于 2022-1-5 16:51 修改之后还是一样的呀,是不是我程序写的有问题啊?孩子蒙了求指教 |
uint shan_cont;//<<<<<<<<<<<<<<<<<<<<<<< /////////// if(knum != 0) { shan_cont++; if(shan_cont == 10000)//<<<<<<<<<<<<<<<<<<<<<<<< { shan_cont = 0; shan = !shan; } } |