|
|||||||||||
| 技術交流 | 電路欣賞 | 工控天地 | 數(shù)字廣電 | 通信技術 | 電源技術 | 測控之家 | EMC技術 | ARM技術 | EDA技術 | PCB技術 | 嵌入式系統(tǒng) 驅動編程 | 集成電路 | 器件替換 | 模擬技術 | 新手園地 | 單 片 機 | DSP技術 | MCU技術 | IC 設計 | IC 產(chǎn)業(yè) | CAN-bus/DeviceNe |
單片機的數(shù)字鐘顯示問題 |
| 作者:hgchenkv 欄目:單片機 |
各位好!請教一個問題:我用51做數(shù)字鐘并用1601顯示,現(xiàn)在只做到讓秒數(shù)顯示的程序,但實驗結果不動,各位 能否幫忙改一下程序,謝謝! 程序如下: #include <at89x51.h> #define uint unsigned int #define uCHAR unsigned CHAR #define LCM_RW P2_0 //定義引腳 #define LCM_RS P2_1 #define LCM_E P2_2 #define LCM_Data P1 #define Busy 0x80 //用于檢測LCM狀態(tài)字中的Busy標識 void WriteDataLCM(uCHAR WDLCM); void WriteCommandLCM(uCHAR WCLCM,BuysC); uCHAR ReadDataLCM(void); uCHAR ReadStatusLCM(void); void LCMInit(void); void DisplayOneChar(uCHAR X, uCHAR Y, uCHAR DData); void DisplayListChar(uCHAR X, uCHAR Y, uCHAR code *DData); void Delay5Ms(void); void Delay400Ms(void); uint time=0; uCHAR i=1,j=1; uint s_high,s_low; uCHAR code net[] = {"N 00 H 00 M 00 S"}; code struct { uint position; uint pattern;//注意此處一定不能用CHAR類型 }next[]= {{0,0x30},{20,0x31},{40,0x32},{60,0x33},{80,0x34},{100,0x35},{120,0x36},{140,0x37},{160,0x38},{180,0x39},{200,0xff}}; void timer0(void)interrupt 1 using 1 { TH0=-(50000/256); TL0=-(50000%256); time++; if(time==next[i].position) { if(next[i].pattern==0xff) { i=0;time=0;//時間計數(shù)清零必須設在此處 if(next[j].pattern==0x36)j=0; s_high=next[j++].pattern; DisplayOneChar(0xc, 0, s_high); } s_low=next[i++].pattern; DisplayOneChar(0xd, 0, s_low); } } void init_time() { TMOD=0x01; TH0=-(50000/256); TL0=-(50000%256); TR0=1; ET0=1; EA=1; } void main(void) { Delay400Ms(); //啟動等待,等LCM講入工作狀態(tài) LCMInit(); //LCM初始化 Delay5Ms(); //延時片刻(可不要) DisplayListChar(0, 0, net); ReadDataLCM();//測試用句無意義 init_time(); for(;;){;} } //寫數(shù)據(jù) void WriteDataLCM(uCHAR WDLCM) { ReadStatusLCM(); //檢測忙 LCM_Data = WDLCM; LCM_RS = 1; LCM_RW = 0; LCM_E = 0; //若晶振速度太高可以在這后加小的延時 LCM_E = 0; //延時 LCM_E = 1; } //寫指令 void WriteCommandLCM(uCHAR WCLCM,BuysC) //BuysC為0時忽略忙檢測 { if (BuysC) ReadStatusLCM(); //根據(jù)需要檢測忙 LCM_Data = WCLCM; LCM_RS = 0; LCM_RW = 0; LCM_E = 0; LCM_E = 0; LCM_E = 1; } //讀數(shù)據(jù) uCHAR ReadDataLCM(void) { LCM_RS = 1; LCM_RW = 1; LCM_E = 0; LCM_E = 0; LCM_E = 1; return(LCM_Data); } //讀狀態(tài) uCHAR ReadStatusLCM(void) { LCM_Data = 0xFF; LCM_RS = 0; LCM_RW = 1; LCM_E = 0; LCM_E = 0; LCM_E = 1; while (LCM_Data & Busy); //檢測忙信號 return(LCM_Data); } void LCMInit(void) //LCM初始化 { LCM_Data = 0; WriteCommandLCM(0x38,0); //三次顯示模式設置,不檢測忙信號 Delay5Ms(); WriteCommandLCM(0x38,0); Delay5Ms(); WriteCommandLCM(0x38,0); Delay5Ms(); WriteCommandLCM(0x38,1); //顯示模式設置,開始要求每次檢測忙信號 WriteCommandLCM(0x08,1); //關閉顯示 WriteCommandLCM(0x01,1); //顯示清屏 WriteCommandLCM(0x06,1); // 顯示光標移動設置 WriteCommandLCM(0x0C,1); // 顯示開及光標設置 } //按指定位置顯示一個字符 void DisplayOneChar(uCHAR X, uCHAR Y, uCHAR DData) { Y &= 0x1; X &= 0x0F; //限制X不能大于15,Y不能大于1 //if (Y) X |= 0x40; //當要顯示第二行時地址碼+0x40; if(X>=0x8)X=(X|0x40)&0xf7; X |= 0x80; // 算出指令碼 WriteCommandLCM(X, 0); //這里不檢測忙信號,發(fā)送地址碼 WriteDataLCM(DData); } //按指定位置顯示一串字符 void DisplayListChar(uCHAR X, uCHAR Y, uCHAR code *DData) { uCHAR ListLength; ListLength = 0; Y &= 0x1; X &= 0x0F; //限制X不能大于15,Y不能大于1 while (DData[ListLength]!='\0') //若到達字串尾則退出 { if (X <= 0x0F) //X坐標應小于0xF { DisplayOneChar(X, Y, DData[ListLength]); //顯示單個字符 ListLength++; X++; } } } //5ms延時 void Delay5Ms(void) { uint TempCyc = 5552; while(TempCyc--); } //400ms延時 void Delay400Ms(void) { uCHAR TempCycA = 5; uint TempCycB; while(TempCycA--) { TempCycB=7269; while(TempCycB--); }; } |
| 2樓: | >>參與討論 |
| 作者: hgchenkv 于 2006/4/26 22:16:00 發(fā)布:
先謝謝各位了 實驗結果就是:只顯示如下N 00 H 00 M 00 S但就是那個秒前面的00不動啊,請各位幫忙看看,謝謝! |
|
| 3樓: | >>參與討論 |
| 作者: 3極管 于 2006/4/26 22:36:00 發(fā)布:
re單片機的數(shù)字鐘顯示問題 #define LCM_RW P2_0 //定義引腳 #define LCM_RS P2_1 #define LCM_E P2_2 這幾句是不是有問題啊 |
|
| 4樓: | >>參與討論 |
| 作者: hgchenkv 于 2006/4/26 22:56:00 發(fā)布:
3極管你好 這幾句應該沒問題吧,我在做單純的用1601顯示時一點問題都沒有的,只是在加上那個中斷后才有的我開始問的問題 |
|
| 5樓: | >>參與討論 |
| 作者: 3極管 于 2006/4/26 23:15:00 發(fā)布:
00來看看這個貼啊 |
|
| 6樓: | >>參與討論 |
| 作者: hgchenkv 于 2006/4/26 23:19:00 發(fā)布:
再謝謝各位!請幫忙看看 |
|
| 7樓: | >>參與討論 |
| 作者: hgchenkv 于 2006/4/27 12:20:00 發(fā)布:
再求各位幫忙費力看看,謝謝! |
|
| 8樓: | >>參與討論 |
| 作者: hgchenkv 于 2006/4/27 18:13:00 發(fā)布:
??? 21IC的各位高手,幫幫忙! |
|
| 9樓: | >>參與討論 |
| 作者: hgchenkv 于 2006/4/27 21:27:00 發(fā)布:
哎 來論壇這么長時間了,從沒有見到過00大哥在我發(fā)的帖上留言 |
|
| 10樓: | >>參與討論 |
| 作者: ctunan 于 2006/4/27 21:55:00 發(fā)布:
中斷,主函數(shù)調(diào)用了同一函數(shù) DisplayOneChar()這個函數(shù)在main函數(shù)里調(diào)用了,在中斷里也調(diào)用了,而且未聲明DisplayOneChar()該函數(shù)可重入,所有就有可能出現(xiàn)問題。建議你將秒的更新顯示部分放到你的main函數(shù)中去。 將time中斷中的 DisplayOneChar(0xc, 0, s_high); DisplayOneChar(0xd, 0, s_low); 這兩句去掉,然后在main中的主循環(huán)中加入顯示就可以了。 for(;;){ DisplayOneChar(0xc, 0, s_high); DisplayOneChar(0xd, 0, s_low); } |
|
| 11樓: | >>參與討論 |
| 作者: ctunan 于 2006/4/27 21:58:00 發(fā)布:
還有一個問題 void DisplayOneChar(uchar X, uchar Y, uchar DData) { Y &= 0x1; X &= 0x0F; //限制X不能大于15,Y不能大于1 //if (Y) X |= 0x40; //當要顯示第二行時地址碼+0x40; if(X>=0x8)X=(X|0x40)&0xf7; X |= 0x80; // 算出指令碼 WriteCommandLCM(X, 0); //這里不檢測忙信號,發(fā)送地址碼 WriteDataLCM(DData); } 這個看得不是很明白,看樣子是從1602液晶改過來的程序,我覺得 if(X>=0x8)X=(X|0x40)&0xf7; 這一句可以去掉,好像沒什么意義。 |
|
| 12樓: | >>參與討論 |
| 作者: ctunan 于 2006/4/27 22:04:00 發(fā)布:
我以前用1602做的萬年歷 貼個N久以前我用1602做的萬年歷,自動調(diào)整大小月,潤月,從當前日期可自動計算出星期。 #include <AT89X51.H> #include <intrins.h> typedef unsigned CHAR uCHAR; typedef unsigned int uint; typedef bit BOOL ; #define rs P2_7 // #define rw P2_6 #define ep P2_5 #define DATA P0 void delay(uCHAR); BOOL lcd_bz(void); void lcd_wcmd(uCHAR); void lcd_pos(uCHAR); void lcd_wdat(uCHAR); void lcd_init(void); //uCHAR get_month(uCHAR,uCHAR); //uCHAR get_weekday(uCHAR,uCHAR,uCHAR); /////////////////////////////////////////////////////////////////////////////////// void delay(uCHAR ms) { // ÑÓʱ×Ó³ÌÐò uCHAR i; while(ms--) { for(i = 0; i< 250; i++) { _nop_(); _nop_(); _nop_(); _nop_(); } } } /////////////////////////////////////////////////////////////////////////////////// BOOL lcd_bz() { // ²âÊÔLCDæÂ&MICRO;״̬ BOOL result; rs = 0; rw = 1; ep = 1; _nop_(); _nop_(); _nop_(); _nop_(); result =(BOOL)(P0 & 0x80); ep = 0; return result; } /////////////////////////////////////////////////////////////////////////////////// void lcd_wcmd(uCHAR cmd) { // дÈëÖ¸ÁîÊý¾Ý&MICRO;½LCD while(lcd_bz()); rs = 0; rw = 0; ep = 0; _nop_(); _nop_(); DATA = cmd; _nop_(); _nop_(); _nop_(); _nop_(); ep = 1; _nop_(); _nop_(); _nop_(); _nop_(); ep = 0; } /////////////////////////////////////////////////////////////////////////////////// void lcd_pos(uCHAR pos) { //É趨ÏÔʾλÖà lcd_wcmd(pos | 0x80); } /////////////////////////////////////////////////////////////////////////////////// void lcd_wdat(uCHAR dat) { //дÈë×Ö·ûÏÔʾÊý¾Ý&MICRO;½LCD while(lcd_bz()); rs = 1; rw = 0; ep = 0; DATA = dat; _nop_(); _nop_(); _nop_(); _nop_(); ep = 1; _nop_(); _nop_(); _nop_(); _nop_(); ep = 0; } /////////////////////////////////////////////////////////////////////////////////// void lcd_init() { //LCD³õʼ»¯É趨 lcd_wcmd(0x38); // delay(1); lcd_wcmd(0x0c); // delay(1); lcd_wcmd(0x06); // delay(1); lcd_wcmd(0x01); //Çå³ýLCD&MICRO;ÄÏÔʾÄÚÈÝ delay(1); } /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// uCHAR Display1[]={"2005-12-01"};//YY-MM-DD uCHAR code Display2[7][3]={{'S','U','N'},{'M','O','N'},{'T','U','E'}, {'W','E','D'},{'T','H','U'},{'F','R','I'},{'S','A','T'}};//Weekday 2001-01-01 MON. uCHAR Display3[]={"12:30:00"};//12:00:00 uCHAR code Display4[]={"By:NAN"}; uCHAR code month_week[]={0,3,6,0,3,5,1,3,6,2,4,0,2}; uCHAR year; uCHAR month; uCHAR day; uCHAR second;// uCHAR minite; uCHAR hour; uint tcnt; BOOL flag_second=0; uCHAR key_mode=0; uCHAR key_add; uCHAR temp1,temp2; void main(void) { TMOD=0x02;//timer mode:timer 0,mode 2 TH0=0x06;//timer high &nbs |
|
| 13樓: | >>參與討論 |
| 作者: hgchenkv 于 2006/4/28 18:19:00 發(fā)布:
ctunan ctunan ,你好!首先感謝帶給小兄弟我的幫助!其次,還有兩個問題我需要說明一下:一是我的那個液晶顯示程序是從1602改過來的,由于是初學者所以1601的驅動不會寫,只能在那個基礎上改了;二是if(X>=0x8)X=(X|0x40)&0xf7;這句話是在1601只能顯示8個字符的條件加入后才能顯示出一行16個字符來,這是根據(jù)1601的說明書改的,改后顯示正常了,所以我感覺這句話是必要的而且必須加,不知道ctunan 是如何理解的?有了ctunan 高手的參考程序,感覺又可以在短時間內(nèi)學很多東西,所以再次感謝ctunan 的幫忙!謝謝 |
|
| 14樓: | >>參與討論 |
| 作者: hgchenkv 于 2006/4/28 23:17:00 發(fā)布:
感謝! 感謝ctunan高手!但是我又有個新問題:1601剛開始用時沒什么問題,顯示正常,但是現(xiàn)在不是顯示不全就是特別不清晰,本來5*7顯示就不是很清楚,現(xiàn)在基本上就很難看清楚了,各位高手,我沒有接15、16腳的背光,跟這有關系還是 ……我的1601運用時間加起來總共還沒超過10個小時啊,感謝各位幫忙。 |
|
| 15樓: | >>參與討論 |
| 作者: tc9148 于 2006/4/30 13:16:00 發(fā)布:
哦哦 如果你能把時鐘做好,單片機的所有功能你都可以熟悉了。 包括中斷,寄存器換來換去, 我做的用匯編寫的,7短碼顯示。大概寫了450行。 |
|
| 16樓: | >>參與討論 |
| 作者: hgchenkv 于 2006/5/1 13:04:00 發(fā)布:
多謝鼓勵! 呵呵,多謝各位幫忙和鼓勵!我會繼續(xù)努力的,同時希望依舊得到各位的支持! |
|
| 17樓: | >>參與討論 |
| 作者: hgchenkv 于 2006/5/2 22:59:00 發(fā)布:
正在努力中!!!!! |
|
| 18樓: | >>參與討論 |
| 作者: hgchenkv 于 2006/5/6 23:33:00 發(fā)布:
ctunan你好! 請教個問題: 這個算法小弟我不太明白,能否簡單給小弟點一下嗎? temp2=(year+year/4+day+2+month_week[month])%7;//Why???????? //month_week[]={0,3,6,0,3,5,1,3,6,2,4,0,2} 小弟先謝過了!!! |
|
| 19樓: | >>參與討論 |
| 作者: hgchenkv 于 2006/5/7 23:02:00 發(fā)布:
ctunan, 最近很忙! |
|
|
|
| 免費注冊為維庫電子開發(fā)網(wǎng)會員,參與電子工程師社區(qū)討論,點此進入 |
Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號 |