熱門(mén): 51單片機(jī) | 24小時(shí)必答區(qū) | 單片機(jī)教程 | 單片機(jī)DIY制作 | STM32 | Cortex M3 | 模數(shù)電子 | 電子DIY制作 | 音響/功放 | 拆機(jī)樂(lè)園 | Arduino | 嵌入式OS | 程序設(shè)計(jì)
![]() |
發(fā)布時(shí)間: 2022-1-5 16:01
正文摘要:數(shù)碼管在設(shè)置時(shí)狂閃,該怎樣解決啊,或者說(shuō)調(diào)慢點(diǎn) 單片機(jī)源程序如下: #include<reg52.h> #include<intrins.h> #define uchar unsigned char #define uint unsigned int #define ... |
wulin 發(fā)表于 2022-1-7 20:21 問(wèn)題已解決,感謝您的寶貴建議 |
lkc8210 發(fā)表于 2022-1-7 22:08 問(wèn)題已解決,感謝 |
uhl0 發(fā)表于 2022-1-7 13:01 if(key2==0)的else里缺了一對(duì){} ![]() 這里應(yīng)該是k ![]() |
本帖最后由 wulin 于 2022-1-7 20:23 編輯 uhl0 發(fā)表于 2022-1-7 09:40 數(shù)碼管閃爍提示的實(shí)際視覺(jué)效果不如閃點(diǎn)好。給你改成數(shù)碼管閃爍提示供參考 ![]() |
lkc8210 發(fā)表于 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; //設(shè)置 sbit key2 = P2^4; //加 sbit key3 = P2^5; //減 sbit key4 = P2^6; //啟動(dòng) sbit key5 = P2^7; //手動(dòng) 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; //時(shí)分秒 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}; //數(shù)碼管顯示緩沖區(qū) void init() //定時(shí)器初始化 { TMOD |= 0x01; //設(shè)置定時(shí)器0為工作方式1(M1M0為01) TH0 = (65536-1000)/256; //1ms初值 @12MHz TL0 = (65536-1000)%256; EA = 1; //開(kāi)總中斷 ET0 = 1; //開(kāi)定時(shí)器0中斷 TR0 = 1; //啟動(dòng)定時(shí)器0 } void dis() //顯示函數(shù) { 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() //按鍵掃描函數(shù) { static bit kf1=0,kf2=0,kf3=0; //自鎖標(biāo)志,這里一定要加static(或者用全局變量),否則按鍵不靈 static uint i=0,j=0,k=0,l=0,m=0; //消抖延時(shí)變量 //////////////////////////////////////啟動(dòng)/暫停鍵////////////////////////////////////// if(knum==0) //只要時(shí)分秒都不等于0 { if(key4 == 1) //啟動(dòng) 暫停鍵 { m=0; //按鍵消抖計(jì)時(shí)變量清零 kf2=0; //按鍵自鎖標(biāo)志清零 } else if(kf2 == 0 ) //有按鍵按下,且是第一次被按下 { ++m; //消抖 if( (m>20) && ((miao != 0) || (fen != 0) || (shi != 0)) ) { //時(shí)分秒都為0時(shí),不能啟動(dòng)輸出,只要其中之一不為0,就能啟動(dòng)輸出 m=0; //按鍵消抖計(jì)時(shí)變量清零 kf2=1; //自鎖按鍵置位,避免一直觸發(fā) flag = !flag; //啟動(dòng)、暫停計(jì)時(shí)標(biāo)志 out = !out; //LED狀態(tài)取反 } } } //////////////////////////////////////啟動(dòng)/暫停鍵////////////////////////////////////// if(out==1) //加這句,只有在輸出關(guān)閉的時(shí)候,才能設(shè)置計(jì)時(shí)時(shí)間,在倒計(jì)時(shí)的過(guò)程中是不能設(shè)置的 { if(key1==1) //設(shè)置 //IO是高電平,說(shuō)明按鍵沒(méi)有被按下,這時(shí)要及時(shí)清零一些標(biāo)志位 { i=0; //按鍵消抖計(jì)時(shí)變量清零 kf1=0; //按鍵自鎖標(biāo)志清零 } else if(kf1 == 0) //有按鍵按下,且是第一次被按下 { ++i; //消抖 if(i>12) { i=0; //按鍵消抖計(jì)時(shí)變量清零 kf1=1; //自鎖按鍵置位,避免一直觸發(fā) knum++; //調(diào)節(jié)時(shí)分秒--->123 if(knum==4) knum = 0; //按第四次關(guān)閉設(shè)置 } } } //////////////////////////////////////加1按鍵////////////////////////////////////// if(key2==0) //加1按鍵 快速加數(shù) { j++; if(j >= 3000) //長(zhǎng)按,數(shù)碼管掃描放中斷里面,這里的值就要取得大才行 { //因?yàn)闆](méi)用delay延時(shí),CPU跑的很快 if(knum==1) { miao++; //秒鐘加1 if(miao==60) miao = 0; //超過(guò)60s變成0 } if(knum==2) { fen++; //分鐘加1 if(fen==60) fen=0; //超過(guò)60變0 } if(knum==3) { shi++; //小時(shí)加1 if(shi==24) shi=0; //超過(guò)24變0 } j=1000; //這里j的值可以設(shè)置連加的快慢,j的值越大就越快 } //因?yàn)槌踔翟酱螅拥?000的時(shí)間就越短 } else //慢速加數(shù) { if(j>500 && j<3000) if(knum==1) { miao++; //秒鐘加1 if(miao==60) miao = 0; //超過(guò)60s變成0 } if(knum==2) { fen++; //分鐘加1 if(fen==60) fen=0; //超過(guò)60變0 } if(knum==3) { shi++; //小時(shí)加1 if(shi==24) shi=0; //超過(guò)24變0 } j=0; } //////////////////////////////////////減1按鍵////////////////////////////////////// if(key3==0) //減1按鍵 快速減數(shù) { k++; if(k >= 3000) //長(zhǎng)按,數(shù)碼管掃描放中斷里面,這里的值就要取得大才行 { //因?yàn)闆](méi)用delay延時(shí),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--; //時(shí)鐘減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--; //時(shí)鐘減1 if(shi==255) shi=23; //小于0就等于23 } } k=0; //消抖變量清零,為下次按鍵做準(zhǔn)備 } //////////////////////////////////////////////////////////////////////////// } void main() { init(); //定時(shí)器初始化 out = 1; while(1) { keysan(); //按鍵掃描函數(shù) dis(); //顯示函數(shù) if(shi==0 && fen==0 && miao==0 && flag == 1 ) //倒計(jì)時(shí)時(shí)間到 { flag=0; //停止計(jì)時(shí) flag1=1; //啟動(dòng)蜂鳴器標(biāo)志置1 out=1; //關(guān)閉輸出 } } } void timer() interrupt 1 { TH0 = (65536-1000)/256; //1毫秒初值 TL0 = (65536-1000)%256; //////////////////////////////////////1s計(jì)時(shí)////////////////////////////////////// if(flag) { cont++; if(cont == 1000) //1s到 { cont = 0; //清0 miao--; //秒數(shù)減1 if(miao==255) //如果小于0,就是59 { miao=59; fen--; //分鐘數(shù)減1 if(fen==255) //如果小于0,就是59 { fen=59; shi--; //小時(shí)減1 if(shi==255) shi=0; //時(shí)鐘小于0,就是0 if(shi==0) fen=59; //時(shí)鐘小于0,就是255 if(fen==0 && shi==0) fen=0;//時(shí)鐘分鐘都為0,就是0 } } } } //////////////////////////////////////蜂鳴器控制////////////////////////////////////// if(flag1) //倒計(jì)時(shí)時(shí)間到,啟動(dòng)蜂鳴器 { cont1++; if(cont1==500) //500ms蜂鳴器響一次 { cont1=0; di=!di; cont2++; if(cont2==20)//500*20=10000ms=10s,蜂鳴器響10s后停止 { cont2=0; flag1=0; } } } //////////////////////////////////////啟動(dòng)/暫停鍵////////////////////////////////////// if(knum != 0) { shan_cont++; if(shan_cont==100) //設(shè)置時(shí),100ms閃爍時(shí)間 可根據(jù)實(shí)際效果調(diào)整 { shan_cont=0; shan = !shan; } } /**********************************數(shù)碼管掃描函數(shù)**********************************/ i++; //挨個(gè)顯示 if(i>=8) i=0; //清0 duan = 0x00; switch(i) { case 0: if(knum==1) //如果設(shè)置鍵第一次按下 { if(shan==1) {wei = 0x00; duan = LedBuff[0];} //設(shè)置秒位閃爍 else {wei = weima[0]; duan = LedBuff[0];} } else{wei = weima[0]; duan = LedBuff[0];} break; //否則正常顯示 case 1: if(knum==1) //如果設(shè)置鍵第一次按下 { if(shan==1){wei = 0x00; duan = LedBuff[1];} //設(shè)置秒位閃爍 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) //如果設(shè)置鍵第二次按下 { if(shan==1){wei = 0x00; duan = LedBuff[3];} //設(shè)置分位閃爍 else{wei = weima[3]; duan = LedBuff[3];} } else{wei = weima[3]; duan = LedBuff[3];} break;//否則正常顯示 case 4: if(knum==2) //如果設(shè)置鍵第二次按下 { if(shan==1){wei = 0x00; duan = LedBuff[4];} //設(shè)置分位閃爍 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) //如果設(shè)置鍵第三次按下 { if(shan==1){wei = 0x00; duan = LedBuff[6];} //設(shè)置時(shí)位閃爍 else{wei = weima[6]; duan = LedBuff[6];} } else{wei = weima[6]; duan = LedBuff[6];} break;//否則正常顯示 case 7: if(knum==3) //如果設(shè)置鍵第三次按下 { if(shan==1){wei = 0x00; duan = LedBuff[7];} //設(shè)置時(shí)位閃爍 else{wei = weima[7]; duan = LedBuff[7];} } else{wei = weima[7]; duan = LedBuff[7];} break;//否則正常顯示 default: break; } } 感謝大佬回信,我聽(tīng)你的建議加了在if(key2==0)的else里加了短按判斷if(j>500 && j<3000),秒表問(wèn)題解決,但我時(shí)分顯示也有這個(gè)問(wèn)題,我改了幾次發(fā)現(xiàn)不行不知道怎么改了 |
uhl0 發(fā)表于 2022-1-7 09:40 你是怎么改的? 上代碼啊~ |
lkc8210 發(fā)表于 2022-1-6 00:09 大佬我現(xiàn)在秒表數(shù)碼管顯示正常了,但分鐘和小時(shí)那里又亂閃了,是我后面的短按判斷錯(cuò)了嗎?求指點(diǎn) |
謝謝大佬,剛好用上 |
![]()
|
lkc8210 發(fā)表于 2022-1-6 00:09 建議以采納,謝謝大佬 |
uhl0 發(fā)表于 2022-1-5 19:48 以為你是說(shuō)閃的太快 上Proteus一看 原來(lái)是亂閃 if(key2==0)的else里缺了短按判斷if(j>500 && j<3000) |
lkc8210 發(fā)表于 2022-1-5 16:51 修改之后還是一樣的呀,是不是我程序?qū)懙挠袉?wèn)題?孩子蒙了求指教 |
uint shan_cont;//<<<<<<<<<<<<<<<<<<<<<<< /////////// if(knum != 0) { shan_cont++; if(shan_cont == 10000)//<<<<<<<<<<<<<<<<<<<<<<<< { shan_cont = 0; shan = !shan; } } |
Powered by 單片機(jī)教程網(wǎng)