找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 10180|回復: 22
打印 上一主題 下一主題
收起左側(cè)

1602液晶顯示月份,日,時分秒為四根橫線,哪位大神幫忙看看,調(diào)了好久

  [復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:229016 發(fā)表于 2017-11-4 20:41 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
1黑幣

單片機源程序如下:
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. sbit sck=P1^0;
  6. sbit io=P1^1;
  7. sbit rst=P1^2;
  8. sbit dula=P2^6;  
  9. sbit wela=P2^7;
  10. sbit lcden=P3^4;        //液晶使能端
  11. sbit lcdrs=P3^5;     //液晶命令選擇端
  12. uchar time_data[7]={17,11,1,20,40,30};                         //年周月日時分秒
  13. uchar write_add[7]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};
  14. uchar read_add[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};
  15. uchar disp[19];
  16. void delayms(uint z)
  17. {
  18.   uint i,j;
  19. for(i=z;i>0;i--)
  20.   for(j=110;j>0;j--);
  21. }
  22. void write_ds1302_byte(uchar dat)   //單字節(jié)寫數(shù)據(jù)
  23. {
  24. uchar i;
  25. for(i=0;i<8;i++)
  26. {
  27.   sck=0;
  28.   io=dat&0x01;              //為了每次傳輸?shù)妥止?jié)
  29.   dat=dat>>1;      //右移
  30.   sck=1;
  31. }
  32. }
  33. void write_ds1302(uchar add,uchar dat)  //寫地址,寫數(shù)據(jù)
  34. {
  35. rst=0;
  36. _nop_();
  37. sck=0;
  38. _nop_();
  39. rst=1;
  40. _nop_();
  41. write_ds1302_byte(add);
  42. write_ds1302_byte(dat);
  43. rst=0;
  44. _nop_();
  45. io=1;
  46. sck=1;
  47. }
  48. uchar read_ds1302(uchar add)
  49. {
  50. uchar i,value;
  51. rst=0;
  52. _nop_();
  53. sck=0;
  54. _nop_();
  55. rst=1;
  56. _nop_();
  57. write_ds1302_byte(add);
  58. for(i=0;i<8;i++)
  59. {
  60.      value=value>>1;       //移位
  61.   sck=0;
  62.   if(io)               //io是1的話在最低位,讀和寫都是從最低位開始的
  63.   value=value|0x80;      //用value取值,控制字最高位必須為1
  64.   sck=1;         //是1的話表示數(shù)據(jù)讀完
  65. }
  66. rst=0;
  67. _nop_();
  68. sck=0;
  69. _nop_();         //使芯片停止
  70. sck=1;
  71. io=1;
  72. return value;  
  73. }
  74. void set_rtc(void)        //設置時間
  75. {
  76. uchar i,j;
  77. for(i=0;i<7;i++)       //年月日周時分秒共七個
  78. {
  79.   j=time_data[i]/10;
  80.   time_data[i]=time_data[i]%10;   //把十進制轉(zhuǎn)成BCD碼  存?zhèn)位
  81.   time_data[i]=time_data[i]+j*16;   //個位加上十位
  82. }
  83. write_ds1302(0x8e,0x00);   //去除寫保護,地址是8e,數(shù)據(jù)是0
  84. for(i=0;i<7;i++)
  85. {
  86.   write_ds1302(write_add[i],time_data[i]);
  87. }
  88. write_ds1302(0x8e,0x80);      //加寫保護,把WP置1成了80
  89. }
  90. void read_rtc()
  91. {
  92. uchar i;
  93. for(i=0;i<7;i++)
  94. {
  95.   time_data[i]=read_ds1302(read_add[i]);
  96. }  
  97. }
  98. void time_pros(void)      //把BCD碼轉(zhuǎn)換成十進制
  99. {  
  100.    
  101. read_rtc();
  102.     disp[0]='2';
  103. disp[1]='0';
  104. disp[2]=time_data[0]%16;  //年十位
  105. disp[3]=time_data[0]/16;  //年個位
  106. disp[4]='-';
  107. disp[5]=time_data[1]%16;  //月十位
  108. disp[6]=time_data[1]/16;  //月個位
  109. disp[7]='-';
  110. disp[8]=time_data[2]%16;  //日十位
  111. disp[9]=time_data[2]/16;  //日個位
  112. disp[10]='-';
  113. disp[11]=time_data[3]%16;       //時十位
  114. disp[12]=time_data[3]/16;  //時個位
  115. disp[13]='-';
  116. disp[14]=time_data[4]%16;   //分十位
  117. disp[15]=time_data[4]/16;   //分個位
  118. disp[16]='-';
  119. disp[17]=time_data[5]%16;     //秒十位
  120. disp[18]=time_data[5]/16;      //秒個位
  121. }
  122. void write_com(uchar com)
  123. {   
  124.    lcdrs=0;             //選擇寫命令模式
  125.    P0=com;              //將要寫的命令送到數(shù)據(jù)總線上
  126.    delayms(5);          //稍做延時以待數(shù)據(jù)穩(wěn)定
  127.    lcden=1;             //使能端給一個高脈沖,因為初始化函數(shù)中已經(jīng)將lcden置為0
  128.    delayms(5);          //稍做延時
  129.    lcden=0;              //將使能端置0以完成高脈沖
  130. }
  131. void write_data(uchar date)
  132. {  
  133.    lcdrs=1;               //選擇寫數(shù)據(jù)模式
  134.    P0=date;               //將要寫的數(shù)據(jù)疏導數(shù)據(jù)總線上
  135.    delayms(5);
  136.    lcden=1;
  137.    delayms(5);
  138.    lcden=0;
  139. }
  140. void init()  //液晶初始化
  141. {
  142.    dula=0;
  143.    wela=0;
  144.    lcden=0;
  145.    write_com(0x38);    //設置16×2顯示,5×7點陣,8位數(shù)據(jù)口;
  146.    write_com(0x0c);    //設置開顯示,不顯示光標
  147.    write_com(0x06);    //寫一個字符后地址指針加1
  148.    write_com(0x01);    //顯示請0,數(shù)據(jù)指針請0;
  149. }
  150. void display()
  151. {
  152.   uchar i,j;
  153.   write_com(0x80);
  154.   for(i=0;i<10;i++)
  155.   {
  156.     time_pros();
  157.     write_data(disp[i]);
  158. delayms(5);
  159.   }
  160.   write_com(0x80+0x40);
  161.   for(j=11;j<19;j++)
  162.   {
  163.     time_pros();
  164.     write_data(disp[j]);
  165. delayms(5);
  166.    }
  167. }
  168. void main()
  169. {
  170.     set_rtc();
  171. init();
  172. while(1)
  173. { read_rtc();
  174.   time_pros();
  175.   display();
  176. }
  177. }
復制代碼






評分

參與人數(shù) 1黑幣 +5 收起 理由
topchao + 5 贊一個!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發(fā)
ID:82765 發(fā)表于 2017-11-4 21:43 | 只看該作者
提示: 作者被禁止或刪除 內(nèi)容自動屏蔽
回復

使用道具 舉報

板凳
ID:111634 發(fā)表于 2017-11-4 21:47 | 只看該作者
本帖最后由 zl2168 于 2017-11-4 21:49 編輯

介紹你一個正確有效的案例,自己對照查錯吧!
實例91  具有校正功能的時鐘1302LCD1602顯示)

先Proteus仿真,確認有效。
實例91 帶校正時鐘1302(LCD1602顯示).rar (52.68 KB, 下載次數(shù): 21)
以上摘自張志良編著《80C51單片機仿真設計實例教程——基于Keil CProteus》清華大學出版社ISBN 978-7-302-41682-1,書中電路和程序設計有詳細說明,程序語句條條有注解。仿真電路和Hex文件能在清華出版社網(wǎng)站免費下載,程序源代碼只能到書上看了。到圖書館借,或到新華書店翻閱,或到網(wǎng)上書店打折購買。
回復

使用道具 舉報

地板
ID:229016 發(fā)表于 2017-11-5 00:39 | 只看該作者
cjjcjj1 發(fā)表于 2017-11-4 21:43
你好!你的程序和實物的 DS1302 的端口定義的一樣嗎

檢查過好幾遍了,是一致的
回復

使用道具 舉報

5#
ID:229016 發(fā)表于 2017-11-5 00:43 | 只看該作者
zl2168 發(fā)表于 2017-11-4 21:47
介紹你一個正確有效的案例,自己對照查錯吧!
實例91  具有校正功能的時鐘1302(LCD1602顯示)
先Proteus ...

好吧,其實有些資料我可以找到,我就想把這個調(diào)出來,看看問題出在哪里,對于像我這樣初學的菜鳥,這些調(diào)試的過程就是一種提高的過程
回復

使用道具 舉報

6#
ID:229016 發(fā)表于 2017-11-5 00:45 | 只看該作者
cjjcjj1 發(fā)表于 2017-11-4 21:43
你好!你的程序和實物的 DS1302 的端口定義的一樣嗎

我剛開始有六位數(shù)碼管顯示I時分秒完全沒問題,但在1602液晶上顯示就是亂碼了
回復

使用道具 舉報

7#
ID:229016 發(fā)表于 2017-11-5 01:09 | 只看該作者
zl2168 發(fā)表于 2017-11-4 21:47
介紹你一個正確有效的案例,自己對照查錯吧!
實例91  具有校正功能的時鐘1302(LCD1602顯示)
先Proteus ...

還是很希望前輩能幫我看看我自己的代碼,畢竟這個花了一段時間了,我不想就這么放棄,拜托!
先前在數(shù)碼管上可以正常顯示,但在1602液晶就如圖所示了!
回復

使用道具 舉報

8#
ID:164602 發(fā)表于 2017-11-5 09:42 | 只看該作者
我對照了我的程序,仔細看了你說的過程,有了以下判斷,你覺得怎么樣?
第一:你說用數(shù)碼管是成功的,那么,1302是沒有問題的。
第二:1602與數(shù)碼管的顯示,不同在于編碼。看到你的截圖,可以認為,只是1602的顯示碼出問題了。
綜上所述,我認為你的問題,就是這個地方:
uchar time_data[7]={17,11,1,20,40,30};                         //年周月日時分秒
改為:uchar time_data[7]={0x17,0x11,0x01,0x20,0x40,0x30};
回復

使用道具 舉報

9#
ID:229016 發(fā)表于 2017-11-5 10:13 | 只看該作者
HC6800-ES-V2.0 發(fā)表于 2017-11-5 09:42
我對照了我的程序,仔細看了你說的過程,有了以下判斷,你覺得怎么樣?
第一:你說用數(shù)碼管是成功的,那么 ...

謝謝,我剛才試了一下,結(jié)果還是如圖所示,而且我覺得程序中有將十進制轉(zhuǎn)化為BCD碼的,這里為何要用十六進制呢?
回復

使用道具 舉報

10#
ID:213173 發(fā)表于 2017-11-5 10:20 | 只看該作者
給你一個成熟例程參考
/*******************************
描述:LCD萬年歷,TX-1C實驗板
STC89C52RC,晶振11.0592MHz
(如果晶振12MHz時間更準些)
********************************/
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit LCD_EN=P3^4;                                 //定義1602液晶LCDEN端,使能信號
sbit LCD_RS=P3^5;                                 //定義1602液晶RS端,數(shù)據(jù)/命令選擇端(H/L)
//sbit LCD_RW=P3^6;                         //定義1602液晶RW端,讀/寫選擇端(H/L)已接地禁止讀
sbit BUZZ=P2^3;                                 //定義蜂鳴器端,按鍵釋放和整點響
sbit dula=P2^6;                                        //段端口
sbit wela=P2^7;                                        //位端口
sbit key_1=P3^0;                                //進入調(diào)試方式
sbit key_2=P3^1;                                //調(diào)試+
sbit key_3=P3^2;                                //調(diào)試-
sbit key_4=P3^3;                                //退出調(diào)試方式
sbit MND_1=P3^7;                                //矩陣鍵盤模擬地

uchar code keycode[] = {0x11,0x12,0x14,0x18,0x21,0x22,0x24,0x28,//按鍵鍵值
                        0x41,0x42,0x44,0x48,0x81,0x82,0x84,0x88};
uchar yue,ri,shi,fen,miao,week,nian;         //月、日、時、分、秒、周、年變量
uchar flag=0;        //功能鍵計數(shù)變量
uint count=0;        //中斷計數(shù)變量
bit Cnt1s=0;        //秒標志
uchar code table[7][3]={"MON","TUE","WED","THU","FRI","SAT","SUN"};//顯示周

/***********毫秒級延時函數(shù)**********/
void delay(uint x)
{
        uint y,z;
        for(y=x;y>0;y--)
                for(z=110;z>0;z--);
}
/***********蜂鳴器發(fā)聲函數(shù)**********/
void di(uint dd)
{
        BUZZ=0;
        delay(dd);
        BUZZ=1;
}
/***********LCD1602忙等待**********/
/*
uchar busycheck()
{
        uchar s;                        //臨時變量
        LCD_RS=0;                //允許寫指令
//        LCD_RW=1;                //允許讀數(shù)據(jù)(讀寫端已接地,禁止讀)
        LCD_EN=1;                //高電平使能讀數(shù)據(jù)
        delay(1);                //延時
        s=P0;                                //讀P0數(shù)據(jù)賦值s
        LCD_EN=0;                //低跳變執(zhí)行
        return s;                //返回s值 s=0x80有效
}
*/
/***********液晶寫指令函數(shù)**********/
void write_com(uchar com)
{
//        while((busycheck()&0x80)==0x80);//忙等待
        LCD_RS=0;        //允許寫指令
//        LCD_RW=0;        //讀寫端已接地,禁止讀
        LCD_EN=0;        //初始設置LCD_EN低電平
        P0=com;                //傳遞指令
        delay(5);        //延時
        LCD_EN=1;        //使能寫入
        delay(5);        //延時
        LCD_EN=0;        //低跳變執(zhí)行
}

/***********液晶寫數(shù)據(jù)函數(shù)**********/
void write_date(uchar date)
{
//        while((busycheck()&0x80)==0x80);//忙等待
        LCD_RS=1;        //允許寫數(shù)據(jù)
//        LCD_RW=0;        //讀寫端已接地,禁止讀
        LCD_EN=0;        //初始設置LCD_EN低電平
        P0 =date;        //傳遞數(shù)據(jù)
        delay(5);        //延時
        LCD_EN=1;        //使能寫入
        delay(5);        //延時
        LCD_EN=0;        //低跳變執(zhí)行
}

/***********寫年函數(shù)**********/
void write_nian(uchar add,uchar date)reentrant  //reentrant定義為可重入函數(shù),允許被遞歸調(diào)用
{
        uint bai,shi,ge;                //定義百、十、個變量
        bai=date/100;                        //分解百
        shi=date%100/10;                //分解十
        ge=date%100%10;                //分解個
        write_com(0x80+add); //寫指令、設置顯示位置
        write_date(0x30+bai);//寫數(shù)據(jù)百位0~9對應的字符碼是0x30~0x39
        write_date(0x30+shi);//寫數(shù)據(jù)十位
        write_date(0x30+ge); //寫數(shù)據(jù)個位
        /*write_date(dat[bai]);
        write_date(dat[shi]);
        write_date(dat[ge]);*/
}

/***********大小月份設置**********/
uchar dxy(uchar r)
{
        uchar k;
        switch(r)
        {
                case 1:
                        k=31;
                break;

                case 2: //閏年29天, 平年28天
                if((2000+nian)%100==0)
                        if((2000+nian)%400==0)
                                k=29;
                        else
                                k=28;
                        else if((2000+nian)%4==0)
                                k=29;
                        else
                                k=28;
                break;

                case  3:k=31;break;
                case  4:k=30;break;
                case  5:k=31;break;
                case  6:k=30;break;
                case  7:k=31;break;
                case  8:k=31;break;
                case  9:k=30;break;
                case 10:k=31;break;
                case 11:k=30;break;
                case 12:k=31;break;
        }
        return k;
}

/***********寫月、日、時、分、秒函數(shù)**********/
void write_yrsfm(uchar add,uchar date)
{
        uchar shi,ge;
        shi=date/10;
        ge=date%10;
        write_com(0x80+add); //設置顯示位置
        write_date(0x30+shi);
        write_date(0x30+ge);
        /*write_date(dat[shi]);
        write_date(dat[ge]);*/
}

/***********寫星期函數(shù)**********/
void write_week(uchar add,uchar date)
{
        uchar i;
        write_com(0x80+add); //設置顯示位置
        for(i=0;i<3;i++)
        {
                write_date(table[date][i]);
                delay(5);
        }
}

/***********初始化函數(shù)**********/
void init()
{
        count=0;                         //
        dula=0;                                //關(guān)閉數(shù)碼管段端口
        wela=0;                                //關(guān)閉數(shù)碼管位端口
//        P0=0xff;                         //關(guān)閉發(fā)光二極管
        write_com(0x38); //設置16*2顯示,5*7點陣,8位數(shù)據(jù)接口
        write_com(0x0c); //設置開顯示,不顯示光標
        write_com(0x06); //寫一個字符后地址指針加1
        write_com(0x01); //顯示清零,數(shù)據(jù)指針清零
        write_com(0x80); //設置顯示初始位置
        write_com(0x80+1); //寫出年份的最高位“2”
        write_date('2');         //寫數(shù)據(jù)'2'
        write_com(0x80+5); //寫指令,顯示位置 日期顯示部分的的兩'-'
        write_date('-');         //寫數(shù)據(jù)'-'
        write_com(0x80+8); //寫指令,顯示位置 日期顯示部分的的兩'-'
        write_date('-');          //寫數(shù)據(jù)'-'
        write_com(0x80+0x40+6); //寫指令,時間顯示部分的的兩個“:”
        write_date(':');                //寫數(shù)據(jù)':'
        write_com(0x80+0x40+9); //寫指令,時間顯示部分的的兩個“:”
        write_date(':');                                //寫數(shù)據(jù)':'
        miao=0;                                                        //秒
        fen=0;                                                        //分
        shi=0;                                                        //時
        week=5;                                                //星期
        ri=20;                                      //日
        yue=5;                                      //月
        nian=17;                                              //年
        write_yrsfm(0x40+10,miao);        //寫入秒
        write_yrsfm(0x40+7,fen);        //寫入分
        write_yrsfm(0x40+4,shi);        //寫入時
        write_week(12,week);                   //寫入星期
        write_yrsfm(9,ri);                        //寫入日
        write_yrsfm(6,yue);                        //寫入月
        write_nian(2,nian);                        //寫入年
}
/***********按鍵掃描函數(shù)**********/
void keyscan()
{
        if(key_1==0) //功能鍵按下
        {
                delay(10); //消抖
                if(key_1==0)//功能鍵確認按下
                {
                        flag++; //記錄功能鍵按下次數(shù)
                        while(!key_1); //確認釋放功能鍵
                        di(100); //每當有按鍵釋放蜂鳴器發(fā)出滴聲提醒
                        if((flag==1)||(flag==8)) //第一次按下功能鍵光標閃爍到秒位置
                        {
                                TR0=0; //關(guān)閉定時器
                                write_com(0x80+0x40+11); //光標定位到秒位置
                                write_com(0x0f); //光標開始閃爍
                        }
                        if(flag==2) //第二次按下功能鍵光標閃爍到分鐘位置
                        {
                                write_com(0x80+0x40+8);
                        }
                        if(flag==3) //第三次按下功能鍵光標閃爍到時位置
                        {
                                write_com(0x80+0x40+5);
                        }
                        if(flag==4) //第四次按下功能鍵光標閃爍到星期位置
                        {
                                write_com(0x80+12);
                        }
                        if(flag==5) //第五次按下功能鍵光標閃爍到日位置
                        {
                                write_com(0x80+10);
                        }
                        if(flag==6) //第六次按下功能鍵光標閃爍到月位置
                        {
                                write_com(0x80+7);
                        }
                        if(flag==7) //第七次按下功能鍵光標閃爍到年位置
                        {
                                write_com(0x80+4);
                        }
                        if(flag==8) //第八次按下功能鍵退出功能鍵
                                flag=1; //記錄變成1;光標重新回到秒位置
                }
        }
        if(key_4==0) //退出調(diào)節(jié)
        {
                delay(10);
                if(key_4==0)
                {
                        while(!key_4); //釋放按鍵
                        if(TR0==0)
                        di(100); //只在調(diào)節(jié)時有按鍵釋放蜂鳴器發(fā)出滴聲
                        flag=0; //功能鍵按鍵次數(shù)清零
                        write_com(0x0c); //取消光標閃爍
                        count=0;
                        Cnt1s=0;
                        TR0=1; //啟動定時器
                }
        }
        if(flag!=0) //功能鍵按下后flag=1
        {  //增大鍵
                if(key_2==0) //只有功能鍵按下后,增大和減少鍵才有效
                {
                        delay(10);
                        if(key_2==0)//確認增加按下
                        {
                                while(!key_2); //釋放按鍵
                                di(100); //每當有按鍵釋放蜂鳴器發(fā)出滴聲提醒
                                if(flag==1) //功能鍵第一次按下調(diào)節(jié)秒
                                {
                                        miao++; //秒加1
                                        if(miao>59)
                                                miao=0;
                                        write_yrsfm(0x40+10,miao); //每調(diào)節(jié)一次送液晶顯示一下
                                        write_com(0x80+0x40+11); //顯示位置重新回到調(diào)節(jié)處
                                }
                                if(flag==2) //功能鍵第二次按下調(diào)節(jié)分
                                {
                                        fen++;
                                        if(fen>59)
                                                fen=0;
                                        write_yrsfm(0x40+7,fen);
                                        write_com(0x80+0x40+8);
                                }
                                if(flag==3) //功能鍵第三次按下調(diào)節(jié)時
                                {
                                        shi++;
                                        if(shi>23)
                                                shi=0;
                                        write_yrsfm(0x40+4,shi);
                                        write_com(0x80+0x40+5);
                                }
                                if(flag==4)    //功能鍵第四次按下調(diào)節(jié)星期
                                {
                                        week++;
                                        if(week>6)
                                                week=0;
                                        write_week(12,week);
                                        write_com(0x80+12);
                                }
                                if(flag==5) //功能鍵第五次按下調(diào)節(jié)日
                                {
                                        ri++;
                                        if(ri>(dxy(yue)))
                                                ri=1;
                                        write_yrsfm(9,ri);
                                        write_com(0x80+10);
                                }
                                if(flag==6) //功能鍵第六次按下調(diào)節(jié)月份
                                {
                                        yue++;
                                        if(yue>12)
                                                yue=1;
                                        write_yrsfm(6,yue);
                                        write_com(0x80+7);
                                }
                                if(flag==7)          //功能鍵第七次按下調(diào)節(jié)年份
                                {
                                        nian++;
                                        write_nian(2,nian);
                                        write_com(0x80+4);
                                }
                        }
                }
                //減少鍵
                if(key_3==0) //減少鍵被按下
                {
                        delay(10);
                        if(key_3==0)//確認減少鍵被按下
                        {
                                while(!key_3);//按鍵釋放
                                di(100); //每當有按鍵釋放蜂鳴器發(fā)出滴聲
                                if(flag==1) //功能鍵第一次按下調(diào)節(jié)秒
                                { //秒減1
                                        miao--;
                                        if((miao==(-1))||(miao>59)) //59到0循環(huán)遞減;
                                                miao=59;
                                        write_yrsfm(0x40+10,miao); //每調(diào)節(jié)一次送液晶顯示一下
                                        write_com(0x80+0x40+11); //顯示位置重新回到調(diào)節(jié)處
                                }
                                if(flag==2) //功能鍵第二次按下調(diào)節(jié)分
                                {
                                        fen--;
                                        if((fen==(-1))||(fen>59))
                                                fen=59;
                                        write_yrsfm(0x40+7,fen);
                                        write_com(0x80+0x40+8);
                                }
                                if(flag==3) //功能鍵第三次按下調(diào)節(jié)時
                                {
                                        shi--;
                                        if((shi==(-1))||(shi>23))
                                                shi=23;
                                        write_yrsfm(0x40+4,shi);
                                        write_com(0x80+0x40+5);
                                }
                                if(flag==4) //功能鍵第四次按下調(diào)節(jié)星期
                                {
                                        week--;
                                        if((week==(-1))||(week>6))
                                                week=6;
                                        write_week(12,week);
                                        write_com(0x80+12);
                                }
                                if(flag==5) //功能鍵第五次按下調(diào)節(jié)日
                                {
                                        ri--;
                                        if((ri==0)||ri>dxy(yue))
                                                ri=dxy(yue);
                                        write_yrsfm(9,ri);
                                        write_com(0x80+10);
                                }
                                if(flag==6) //功能鍵第六次按下調(diào)節(jié)月份
                                {
                                        yue--;
                                        if((yue==0)||(yue>12))
                                                yue=12;
                                        write_yrsfm(6,yue);
                                        write_com(0x80+7);
                                }
                                if(flag==7)         //功能鍵第七次按下調(diào)節(jié)年份
                                {
                                        nian--;
                                        write_nian(2,nian);
                                        write_com(0x80+4);
                                }
                        }
                }
        }
}
void LCD_Refresh()
{
        if(flag==0)                //調(diào)整時停止刷新
        {
                if((ri>dxy(yue))||(ri<1)) //大小月匹配
                        ri=1;
                write_yrsfm(9,ri); //日若變化則重新寫入
                if(Cnt1s==1) //1秒時間到
                {
                        Cnt1s=0; //清零
                        miao++; //秒、分、時、星期、日、月、年自動調(diào)節(jié)功能運行
                        if(miao==60)
                        {
                                miao=0;
                                fen++;
                                if(fen==60)
                           {
                                   fen=0;
                                   di(500); //整點提醒
                                   shi++;
                                        if(shi==24)
                                        {
                                                shi=0;
                                                week++;
                                                ri++;
                                                if(week>6)
                                                        week=0;
                                                write_week(12,week); //星期若變化則重新寫入
                                                if(ri>dxy(yue))
                                                {
                                                        ri=1;
                                                        yue++;
                                                        if(yue==13)
                                                        {
                                                                yue=1;
                                                                nian++;
                                                                write_nian(2,nian); //年份若變化則重新寫入
                                                        }
                                                        write_yrsfm(6,yue); //月份若變化則重新寫入
                                                }
                                                write_yrsfm(9,ri); //日若變化則重新寫入
                                        }
                                        write_yrsfm(0x40+4,shi); //時若變化則重新寫入
                                }
                                write_yrsfm(0x40+7,fen); //分若變化則重新寫入
                        }
                        write_yrsfm(0x40+10,miao); //秒若變化則重新寫入
                }
        }
}
void Timer0Init()                                //100微秒@12.000MHz
{
        TMOD = 0x02;                                //設置定時器自動重載模式
//        TL0 = 0x9C;                                        //設置定時初值
//        TH0 = 0x9C;                                        //設置定時重載值
        TL0=0xA4;                                         //定時器裝初值 100微秒@11.0592MHz
        TH0=0xA4;                                         //定時器裝初值 100微秒@11.0592MHz
        TF0 = 0;                                                //清除TF0標志
        TR0 = 1;                                                //定時器0開始計時
        EA=1;                                                 //開總中斷
        ET0=1;                                                 //開定時器0中斷
}
/***********主函數(shù)**********/
void main()
{
        MND_1=0;                                                        //矩陣鍵盤模擬地
        init();                                                                //初始化程序
        Timer0Init();                                                //初始化定時器                                       
        di(100);                                                                //開機蜂鳴器提示音
        while(1)                                                         //不停地檢測按鍵是否被按下
        {
                keyscan();                                                //按鍵掃描程序
                LCD_Refresh();                                        //液晶屏顯示刷新
        }
}
/***********中斷函數(shù)**********/
void timer0() interrupt 1
{
        count++;                                         //11.0592MHz誤差0.17%,12MHz誤差0
        if(count>=10017)                        //1秒/11.0592MHz
//        if(count>=10000)                        //1秒/12MHz
        {
                count=0;                                        //清0
                Cnt1s=1;                                        //1秒標標志置1
        }
}
回復

使用道具 舉報

11#
ID:229016 發(fā)表于 2017-11-5 12:52 | 只看該作者
wulin 發(fā)表于 2017-11-5 10:20
給你一個成熟例程參考
/*******************************
描述:LCD萬年歷,TX-1C實驗板

我只是個剛?cè)腴T的菜鳥,有些不一定看得懂,如果可以,我很希望大佬幫我看看我的問題出在哪里
回復

使用道具 舉報

12#
ID:229016 發(fā)表于 2017-11-5 14:14 | 只看該作者
HC6800-ES-V2.0 發(fā)表于 2017-11-5 09:42
我對照了我的程序,仔細看了你說的過程,有了以下判斷,你覺得怎么樣?
第一:你說用數(shù)碼管是成功的,那么 ...

你好像提醒了我,我寫入的數(shù)據(jù)應該是字符型或是ASCLL碼,而我寫的是十進制數(shù),但變量的十進制怎么轉(zhuǎn)化為字符型呢?
disp[2]=time_data[0]%16;                //年十位
        disp[3]=time_data[0]/16;                //年個位
write_data(disp[j]);
回復

使用道具 舉報

13#
ID:111634 發(fā)表于 2017-11-5 15:37 | 只看該作者
探路 發(fā)表于 2017-11-5 01:09
還是很希望前輩能幫我看看我自己的代碼,畢竟這個花了一段時間了,我不想就這么放棄,拜托!
先前在數(shù)碼 ...

冗長程序一般人是不會去看的。只有讀懂正確有效程序,自己對照查錯。
回復

使用道具 舉報

14#
ID:164602 發(fā)表于 2017-11-5 15:39 | 只看該作者
探路 發(fā)表于 2017-11-5 14:14
你好像提醒了我,我寫入的數(shù)據(jù)應該是字符型或是ASCLL碼,而我寫的是十進制數(shù),但變量的十進制怎么轉(zhuǎn)化為 ...

很簡單啊:
你顯示的都是數(shù)字吧,那么,每個值加上0x30
如:要顯示1,則輸入顯示值為0x30+1=0x31,1的ASCII碼就是0x31
再如:顯示9,則輸入顯示值為0x30+9=0x39。
回復

使用道具 舉報

15#
ID:213173 發(fā)表于 2017-11-6 15:17 | 只看該作者
探路 發(fā)表于 2017-11-5 14:14
你好像提醒了我,我寫入的數(shù)據(jù)應該是字符型或是ASCLL碼,而我寫的是十進制數(shù),但變量的十進制怎么轉(zhuǎn)化為 ...

聲明一個字符數(shù)組unsigned char table[] ="0123456789";與0~9數(shù)字數(shù)組一樣用
10進制變量按位分解
shi= table[x/10];
gei= table[x%10];
回復

使用道具 舉報

16#
ID:185385 發(fā)表于 2017-11-6 21:57 | 只看該作者
交給你個辦法,不會的去淘寶店鋪搜索用法。
回復

使用道具 舉報

17#
ID:140489 發(fā)表于 2017-11-7 14:04 | 只看該作者
給你修改了一下,現(xiàn)在顯示正常了
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. sbit sck=P1^0;
  6. sbit io=P1^1;
  7. sbit rst=P1^2;
  8. sbit dula=P2^6;  
  9. sbit wela=P2^7;
  10. sbit lcden=P3^4;        //液晶使能端
  11. sbit lcdrs=P3^5;     //液晶命令選擇端
  12. sbit lcdrw=P3^6;

  13. //uchar time_data[7]={17,11,1,20,40,30};                         //年周月日時分秒

  14. uchar time_data[7]={17,2,11,7,14,3,0};                         //年周月日時分秒

  15. uchar write_add[7]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};
  16. uchar read_add[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};
  17. uchar disp[19];
  18. void delayms(uint z)
  19. {
  20.   uint i,j;
  21. for(i=z;i>0;i--)
  22.   for(j=110;j>0;j--);
  23. }
  24. void write_ds1302_byte(uchar dat)   //單字節(jié)寫數(shù)據(jù)
  25. {
  26. uchar i;
  27. sck=0;
  28. for(i=0;i<8;i++)
  29. {
  30. // sck=0;
  31.   io=dat&0x01;              //為了每次傳輸?shù)妥止?jié)
  32.   sck=1;
  33.   dat=dat>>1;      //右移
  34.   sck=0;
  35. }
  36. }
  37. void write_ds1302(uchar add,uchar dat)  //寫地址,寫數(shù)據(jù)
  38. {
  39. rst=0;
  40. _nop_();
  41. sck=0;
  42. _nop_();
  43. rst=1;
  44. _nop_();
  45. write_ds1302_byte(add);
  46. write_ds1302_byte(dat);
  47. rst=0;
  48. _nop_();
  49. io=1;
  50. sck=1;
  51. }
  52. uchar read_ds1302(uchar add)
  53. {
  54. uchar i,value;
  55. rst=0;
  56. _nop_();
  57. sck=0;
  58. _nop_();
  59. rst=1;
  60. _nop_();
  61. write_ds1302_byte(add);
  62. for(i=0;i<8;i++)
  63. {
  64.      value=value>>1;       //移位
  65.   sck=0;
  66.   if(io)               //io是1的話在最低位,讀和寫都是從最低位開始的
  67.   value=value|0x80;      //用value取值,控制字最高位必須為1
  68.   sck=1;         //是1的話表示數(shù)據(jù)讀完
  69. }
  70. rst=0;
  71. _nop_();
  72. sck=0;
  73. _nop_();         //使芯片停止
  74. sck=1;
  75. io=1;
  76. return value;  
  77. }

  78. void set_rtc(void)        //設置時間
  79. {
  80. uchar i,j;
  81. for(i=0;i<7;i++)       //年月日周時分秒共七個
  82. {
  83.   j=time_data[i]/10;
  84.   time_data[i]=time_data[i]%10;   //把十進制轉(zhuǎn)成BCD碼  存?zhèn)位
  85.   time_data[i]=time_data[i]+j*16;   //個位加上十位
  86. }
  87. write_ds1302(0x8e,0x00);   //去除寫保護,地址是8e,數(shù)據(jù)是0
  88. for(i=0;i<7;i++)
  89. {
  90.   write_ds1302(write_add[i],time_data[i]);
  91. }
  92. write_ds1302(0x8e,0x80);      //加寫保護,把WP置1成了80
  93. }

  94. void read_rtc()
  95. {
  96. uchar i;
  97. for(i=0;i<7;i++)
  98. {
  99.   time_data[i]=read_ds1302(read_add[i]);
  100. }  
  101. }


  102. void time_pros(void)      //把BCD碼轉(zhuǎn)換成十進制
  103. {  
  104.    
  105. read_rtc();
  106. disp[0]='2';
  107. disp[1]='0';
  108. disp[2]=time_data[0]/16+0x30;  //年十位
  109. disp[3]=time_data[0]%16+0x30;  //年個位
  110. disp[4]='-';
  111. disp[5]=time_data[2]/16+0x30;  //月十位
  112. disp[6]=time_data[2]%16+0x30;  //月個位
  113. disp[7]='-';
  114. disp[8]=time_data[3]/16+0x30;  //日十位
  115. disp[9]=time_data[3]%16+0x30;  //日個位
  116. disp[10]='-';
  117. disp[11]=time_data[4]/16+0x30;       //時十位
  118. disp[12]=time_data[4]%16+0x30;  //時個位
  119. disp[13]='-';
  120. disp[14]=time_data[5]/16+0x30;   //分十位
  121. disp[15]=time_data[5]%16+0x30;   //分個位
  122. disp[16]='-';
  123. disp[17]=time_data[6]/16+0x30;     //秒十位
  124. disp[18]=time_data[6]%16+0x30;      //秒個位
  125. }


  126. void write_com(uchar com)
  127. {   
  128.    lcdrs=0;             //選擇寫命令模式
  129.    P0=com;              //將要寫的命令送到數(shù)據(jù)總線上
  130.    delayms(5);          //稍做延時以待數(shù)據(jù)穩(wěn)定
  131.    lcden=1;             //使能端給一個高脈沖,因為初始化函數(shù)中已經(jīng)將lcden置為0
  132.    delayms(5);          //稍做延時
  133.    lcden=0;              //將使能端置0以完成高脈沖
  134. }

  135. void write_data(uchar date)
  136. {  
  137.    lcdrs=1;               //選擇寫數(shù)據(jù)模式
  138.    P0=date;               //將要寫的數(shù)據(jù)疏導數(shù)據(jù)總線上
  139.    delayms(5);
  140.    lcden=1;
  141.    delayms(5);
  142.    lcden=0;
  143. }

  144. void init()  //液晶初始化
  145. {
  146.    dula=0;
  147.    wela=0;
  148.    lcdrw=0;
  149.    lcden=0;
  150.    write_com(0x38);    //設置16×2顯示,5×7點陣,8位數(shù)據(jù)口;
  151.    write_com(0x0c);    //設置開顯示,不顯示光標
  152.    write_com(0x06);    //寫一個字符后地址指針加1
  153.    write_com(0x01);    //顯示請0,數(shù)據(jù)指針請0;
  154. }

  155. void display()
  156. {
  157.   uchar i,j;
  158.   write_com(0x80);
  159.   for(i=0;i<10;i++)
  160.   {
  161.     time_pros();
  162.     write_data(disp[i]);
  163. delayms(5);
  164.   }
  165.   write_com(0x80+0x40);
  166.   for(i=11;i<19;i++)
  167.   {
  168.     time_pros();
  169.     write_data(disp[i]);
  170. delayms(5);
  171.    }
  172. }

  173. void main()
  174. {
  175.     set_rtc();
  176. init();
  177. while(1)
  178. { read_rtc();
  179.   time_pros();
  180.   display();
  181. }
  182. }
復制代碼
回復

使用道具 舉報

18#
ID:140489 發(fā)表于 2017-11-7 14:21 | 只看該作者
給你改了一下,現(xiàn)在顯示正常了
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. sbit sck=P1^0;
  6. sbit io=P1^1;
  7. sbit rst=P1^2;
  8. sbit dula=P2^6;  
  9. sbit wela=P2^7;
  10. sbit lcden=P3^4;        //液晶使能端
  11. sbit lcdrs=P3^5;     //液晶命令選擇端
  12. sbit lcdrw=P3^6;

  13. //uchar time_data[7]={17,11,1,20,40,30};                         //年周月日時分秒

  14. uchar time_data[7]={17,2,11,7,14,3,0};                         //年周月日時分秒

  15. uchar write_add[7]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};
  16. uchar read_add[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};
  17. uchar disp[19];
  18. void delayms(uint z)
  19. {
  20.   uint i,j;
  21. for(i=z;i>0;i--)
  22.   for(j=110;j>0;j--);
  23. }
  24. void write_ds1302_byte(uchar dat)   //單字節(jié)寫數(shù)據(jù)
  25. {
  26. uchar i;
  27. sck=0;
  28. for(i=0;i<8;i++)
  29. {
  30. // sck=0;
  31.   io=dat&0x01;              //為了每次傳輸?shù)妥止?jié)
  32.   sck=1;
  33.   dat=dat>>1;      //右移
  34.   sck=0;
  35. }
  36. }
  37. void write_ds1302(uchar add,uchar dat)  //寫地址,寫數(shù)據(jù)
  38. {
  39. rst=0;
  40. _nop_();
  41. sck=0;
  42. _nop_();
  43. rst=1;
  44. _nop_();
  45. write_ds1302_byte(add);
  46. write_ds1302_byte(dat);
  47. rst=0;
  48. _nop_();
  49. io=1;
  50. sck=1;
  51. }
  52. uchar read_ds1302(uchar add)
  53. {
  54. uchar i,value;
  55. rst=0;
  56. _nop_();
  57. sck=0;
  58. _nop_();
  59. rst=1;
  60. _nop_();
  61. write_ds1302_byte(add);
  62. for(i=0;i<8;i++)
  63. {
  64.      value=value>>1;       //移位
  65.   sck=0;
  66.   if(io)               //io是1的話在最低位,讀和寫都是從最低位開始的
  67.   value=value|0x80;      //用value取值,控制字最高位必須為1
  68.   sck=1;         //是1的話表示數(shù)據(jù)讀完
  69. }
  70. rst=0;
  71. _nop_();
  72. sck=0;
  73. _nop_();         //使芯片停止
  74. sck=1;
  75. io=1;
  76. return value;  
  77. }

  78. void set_rtc(void)        //設置時間
  79. {
  80. uchar i,j;
  81. for(i=0;i<7;i++)       //年月日周時分秒共七個
  82. {
  83.   j=time_data[i]/10;
  84.   time_data[i]=time_data[i]%10;   //把十進制轉(zhuǎn)成BCD碼  存?zhèn)位
  85.   time_data[i]=time_data[i]+j*16;   //個位加上十位
  86. }
  87. write_ds1302(0x8e,0x00);   //去除寫保護,地址是8e,數(shù)據(jù)是0
  88. for(i=0;i<7;i++)
  89. {
  90.   write_ds1302(write_add[i],time_data[i]);
  91. }
  92. write_ds1302(0x8e,0x80);      //加寫保護,把WP置1成了80
  93. }

  94. void read_rtc()
  95. {
  96. uchar i;
  97. for(i=0;i<7;i++)
  98. {
  99.   time_data[i]=read_ds1302(read_add[i]);
  100. }  
  101. }


  102. void time_pros(void)      //把BCD碼轉(zhuǎn)換成十進制
  103. {  
  104.    
  105. read_rtc();
  106. disp[0]='2';
  107. disp[1]='0';
  108. disp[2]=time_data[0]/16+0x30;  //年十位
  109. disp[3]=time_data[0]%16+0x30;  //年個位
  110. disp[4]='-';
  111. disp[5]=time_data[2]/16+0x30;  //月十位
  112. disp[6]=time_data[2]%16+0x30;  //月個位
  113. disp[7]='-';
  114. disp[8]=time_data[3]/16+0x30;  //日十位
  115. disp[9]=time_data[3]%16+0x30;  //日個位
  116. disp[10]='-';
  117. disp[11]=time_data[4]/16+0x30;       //時十位
  118. disp[12]=time_data[4]%16+0x30;  //時個位
  119. disp[13]='-';
  120. disp[14]=time_data[5]/16+0x30;   //分十位
  121. disp[15]=time_data[5]%16+0x30;   //分個位
  122. disp[16]='-';
  123. disp[17]=time_data[6]/16+0x30;     //秒十位
  124. disp[18]=time_data[6]%16+0x30;      //秒個位
  125. }


  126. void write_com(uchar com)
  127. {   
  128.    lcdrs=0;             //選擇寫命令模式
  129.    P0=com;              //將要寫的命令送到數(shù)據(jù)總線上
  130.    delayms(5);          //稍做延時以待數(shù)據(jù)穩(wěn)定
  131.    lcden=1;             //使能端給一個高脈沖,因為初始化函數(shù)中已經(jīng)將lcden置為0
  132.    delayms(5);          //稍做延時
  133.    lcden=0;              //將使能端置0以完成高脈沖
  134. }

  135. void write_data(uchar date)
  136. {  
  137.    lcdrs=1;               //選擇寫數(shù)據(jù)模式
  138.    P0=date;               //將要寫的數(shù)據(jù)疏導數(shù)據(jù)總線上
  139.    delayms(5);
  140.    lcden=1;
  141.    delayms(5);
  142.    lcden=0;
  143. }

  144. void init()  //液晶初始化
  145. {
  146.    dula=0;
  147.    wela=0;
  148.    lcdrw=0;
  149.    lcden=0;
  150.    write_com(0x38);    //設置16×2顯示,5×7點陣,8位數(shù)據(jù)口;
  151.    write_com(0x0c);    //設置開顯示,不顯示光標
  152.    write_com(0x06);    //寫一個字符后地址指針加1
  153.    write_com(0x01);    //顯示請0,數(shù)據(jù)指針請0;
  154. }

  155. void display()
  156. {
  157.   uchar i,j;
  158.   write_com(0x80);         //顯示第一行
  159.   for(i=0;i<10;i++)
  160.   {
  161.     time_pros();
  162.     write_data(disp[i]);
  163. delayms(5);
  164.   }
  165.   write_com(0x80+0x40);         //顯示第二行
  166.   for(i=11;i<19;i++)
  167.   {
  168.     time_pros();
  169.     write_data(disp[i]);
  170. delayms(5);
  171.    }
  172. }

  173. void main()
  174. {
  175.     set_rtc();
  176. init();
  177. while(1)
  178. { read_rtc();
  179.   time_pros();
  180.   display();
  181. }
  182. }
復制代碼
回復

使用道具 舉報

19#
ID:247198 發(fā)表于 2017-11-8 09:58 | 只看該作者
你這個不是程序的問題,是顯示器接觸不良了,換個顯示器試試看
回復

使用道具 舉報

20#
ID:111634 發(fā)表于 2017-11-9 19:34 | 只看該作者
探路 發(fā)表于 2017-11-5 00:43
好吧,其實有些資料我可以找到,我就想把這個調(diào)出來,看看問題出在哪里,對于像我這樣初學的菜鳥,這些調(diào) ...

“其實有些資料我可以找到”,資料與資料不一樣!你能看懂就行,就怕看不懂,看不懂就看我的吧,能讓你看懂才叫“資料”!!
回復

使用道具 舉報

21#
ID:229016 發(fā)表于 2017-11-11 09:29 | 只看該作者
zl2168 發(fā)表于 2017-11-9 19:34
“其實有些資料我可以找到”,資料與資料不一樣!你能看懂就行,就怕看不懂,看不懂就看我的吧,能讓你看 ...

已經(jīng)找到問題了,寫入1602液晶的數(shù)據(jù)加‘0’,轉(zhuǎn)化為對應的字符型數(shù)據(jù)就可以了!
回復

使用道具 舉報

22#
ID:468786 發(fā)表于 2019-1-20 17:30 | 只看該作者
zl2168 發(fā)表于 2017-11-4 21:47
介紹你一個正確有效的案例,自己對照查錯吧!
實例91  具有校正功能的時鐘1302(LCD1602顯示)
先Proteus ...

請問有程序嗎?
回復

使用道具 舉報

23#
ID:303383 發(fā)表于 2019-1-20 18:07 | 只看該作者
提示: 作者被禁止或刪除 內(nèi)容自動屏蔽
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表