熱門: 51單片機(jī) | 24小時(shí)必答區(qū) | 單片機(jī)教程 | 單片機(jī)DIY制作 | STM32 | Cortex M3 | 模數(shù)電子 | 電子DIY制作 | 音響/功放 | 拆機(jī)樂園 | Arduino | 嵌入式OS | 程序設(shè)計(jì)
|
發(fā)布時(shí)間: 2020-7-13 21:19
正文摘要:程序要求按 A 鍵再按 B 鍵后,顯示兩鍵按下之間的時(shí)間 t(t <60s),單位為 ms。時(shí)間 t 用五位十進(jìn)制整數(shù)顯示,由一位數(shù)碼管從最高位開始逐位顯示一遍?墒俏业某绦蛟诎存I之后顯示的數(shù)字好像和時(shí)間不對(duì)應(yīng),請(qǐng)問大 ... |
| 剛剛又看了一下你自己改的程序。 看來你還是沒有深刻理解單片機(jī)工作方法,特別定時(shí)器這塊。 你的display()函數(shù)里面有 delay(),這個(gè)delay()是多長(zhǎng)時(shí)間? 定時(shí)器周期又是多久? 請(qǐng)仔細(xì)思考這個(gè)問題。! |
Irvingzong 發(fā)表于 2020-7-16 10:23 樓上給你的display()函數(shù)是驅(qū)動(dòng)8段數(shù)碼管的程序, 而你的要求好像只是驅(qū)動(dòng)某個(gè)BCD值模塊的。 都不是一樣的目標(biāo)對(duì)象,你如何能改好。 我們做產(chǎn)品的,很少再用模塊去輔助驅(qū)動(dòng)8段數(shù)碼管的,關(guān)于BCD值的模塊,沒有研究過,也沒有現(xiàn)成的環(huán)境做試驗(yàn),這里不好給你提供幫助。 但是,最終是驅(qū)動(dòng)8段數(shù)碼管,所以,以下程序備注很經(jīng)典,你仔細(xì)讀懂就會(huì)了。 void display() //顯示子程序,從第一位開始逐位顯示't 00秒 000毫秒' { P2&=0xc0;//位碼清0消隱 P0=cnt[m];//送段碼 P2|=0x01<<m;//送位碼 m++; m%=6; } 步驟大概就是1,消隱; 2,送段碼; 3,送位碼; 4,改變循環(huán)值; 5,檢查限定最大循環(huán)值。 |
robinsonlin 發(fā)表于 2020-7-15 16:21 大佬們幫我看下,設(shè)計(jì)框圖規(guī)定了顯示子程序,所以我把上面大佬的程序display()函數(shù)改了一下,可是運(yùn)行時(shí)數(shù)據(jù)又亂了,請(qǐng)問是按照樓頂?shù)目驁D應(yīng)該怎么改? #include<reg51.h> #define uchar unsigned char #define uint unsigned int sbit A1=P3^4; sbit A2=P3^5; uint m=0; uint count,t,d,e,f; uchar code table[]={0x14,0xde,0x38,0x1a,0xd2,0x13,0x11,0x9e,0x10,0x12}; uchar cnt[6]={0};//小數(shù)緩存 bit flag=0; bit init=0; void delay(void) //誤差 0us { unsigned char a,b,c; for(c=67;c>0;c--) for(b=124;b>0;b--) for(a=167;a>0;a--); } void start() { TMOD=0x01; //T0 使用工作方式 1 TH0=(65536-1000)/256; //1ms 定時(shí) TL0=(65536-1000)%256; EA=1; ET0=1; TR0=1; } void display() //顯示子程序,從第一位開始逐位顯示't 00秒 000毫秒' { uint j; if(flag) P0=0xbf;//等待計(jì)數(shù)時(shí)顯示'-' else { if(init==1) for(j=5;j>=0;j--) {P0=cnt[j]; delay(); } } } void main(void) { start(); P0=0xb7;//上電提示符 while(1) { if(A1==0 && flag==0) //按鍵掃描 { flag=1; count=0; t=0; init=1; } if(A2==0 && flag==1) { while(!A2); flag=0; cnt[5]=0xbf; cnt[4]=table[t/10]; cnt[3]=table[t%10];//加秒點(diǎn) cnt[2]=table[count/100]; cnt[1]=table[count/10%10]; cnt[0]=table[count%10]; m=0; } } } void time0(void) interrupt 1 //T0 中斷服務(wù)子程序 { TH0=(65536-1000)/256; TL0=(65536-1000)%256; if(flag) { count++; if(count>=1000) { count=0; t++; if(t>=60) { t=0; } } } display(); } |
wulin 發(fā)表于 2020-7-14 21:17 謝謝,不過設(shè)計(jì)要求用一位數(shù)碼管,可是你第一個(gè)程序的display()函數(shù)我不是很能理解,能再解釋一下嗎 |
Irvingzong 發(fā)表于 2020-7-14 16:41 手把手教你學(xué)51單片機(jī)-C語(yǔ)言版 PDF電子書下載 http://m.raoushi.com/bbs/dpj-48477-1.html (出處: 單片機(jī)論壇) 有C語(yǔ)言基礎(chǔ), 花3天時(shí)間看看就能弄明白了 |
Irvingzong 發(fā)表于 2020-7-14 16:45 轉(zhuǎn)BCD碼是軟件層面的要求,可能是用來直接匹配到哪個(gè)模塊,就可以直接驅(qū)動(dòng)LED8段數(shù)碼管了。 我跟你講的是硬件層面的做法,直接用單片機(jī)的端口加三極管來驅(qū)動(dòng)LED8段數(shù)碼管的方法。 |
| 閃爍點(diǎn)可以用GP來制作,也可以用LED來閃爍,這就是基本的定時(shí)器應(yīng)用 |
Irvingzong 發(fā)表于 2020-7-14 16:41 改成5或6位數(shù)碼管顯示較為合理
|
Irvingzong 發(fā)表于 2020-7-14 16:41 不同的顯示設(shè)備需要不同的驅(qū)動(dòng)碼,LED數(shù)碼管用的是16進(jìn)制筆段碼。如果非得轉(zhuǎn)成BCD碼后再轉(zhuǎn)成筆段碼就是自找麻煩了。不過樓主用一個(gè)數(shù)碼管顯示5位數(shù)也屬特殊用法,未見有在實(shí)際運(yùn)用中出現(xiàn)過。 |
本帖最后由 Irvingzong 于 2020-7-14 16:48 編輯 robinsonlin 發(fā)表于 2020-7-14 16:33 噢噢好的,師傅要求轉(zhuǎn)成BCD碼后譯碼用十進(jìn)制顯示輸出,這個(gè)是怎么理解呢?我感覺沒有用到BCD碼呀 |
wulin 發(fā)表于 2020-7-14 12:31 感謝大佬!另外框圖要求轉(zhuǎn)成BCD碼后譯碼顯示輸出,你這個(gè)顯示子程序是不是也算是符合呢? |
|
1,為什么要在沒有時(shí)間定標(biāo)的主循環(huán)中去控制定時(shí)器? 時(shí)鐘就一直讓它走,只去采集和記錄就好了嗎。 你亂控制主定時(shí)的TR0, 時(shí)間不亂才怪。 2, count++; if(count>=1) {count=0; t++; 這段是干啥? 實(shí)在無法理解。 3, 8段數(shù)碼管輸出的不是BCD碼。是你那個(gè)table[]數(shù)組對(duì)應(yīng)的控制值,而且這個(gè)值分陰碼和陽(yáng)碼,根據(jù)你P0口的線序不同,這個(gè)控制值也會(huì)不同。(為什么要線序不同? 等你自己布線經(jīng)驗(yàn)多一點(diǎn)就明白了) 你這個(gè)顯示子程序,有點(diǎn)花。 不太容易懂的,也不利于你弄明白LED的顯示原理。想弄明白,還是找教程看吧,論壇上就有的。 |
| 要不要把源文件發(fā)上來測(cè)試一下 |
完全下圖做時(shí)間電路和程序,共陽(yáng)數(shù)碼管,可以實(shí)現(xiàn)樓主想要的功能。 A、B 鍵互鎖,不需要消抖,用閃爍表示換顯示位,否則相鄰數(shù)字相同無法分辨。小數(shù)點(diǎn)前為妙,小數(shù)點(diǎn)后為毫秒。
|
Powered by 單片機(jī)教程網(wǎng)