標(biāo)題: 這個(gè)單片機(jī)LCD1602時(shí)鐘程序到底哪里出問(wèn)題了? [打印本頁(yè)]

作者: gqzjl    時(shí)間: 2020-10-31 18:15
標(biāo)題: 這個(gè)單片機(jī)LCD1602時(shí)鐘程序到底哪里出問(wèn)題了?
為什么我程序里定義了星期,這上面卻不顯示?顯示用的是LCD1602,時(shí)鐘用的是DS1302.求解


單片機(jī)源程序如下:
  1. /********************************************************************************************
  2. 程序名:    1602液晶屏?xí)r鐘驅(qū)動(dòng)程序
  3. 硬件支持:  LCD1602液晶屏  STC12C2052 外部12MHZ晶振
  4. 說(shuō)明備注:    使用2402液晶屏程序,與1602液晶屏程序完全兼容
  5. /********************************************************************************************/
  6. #include <stc12c2052ad.h>                                                // 包含頭文件 //
  7. /********************************************************************************************/
  8. typedef unsigned char      uint8;          // 無(wú)符號(hào)8位整型變量 //

  9. /********************************************************************************************
  10. // 引腳定義 // (使用者根據(jù)實(shí)際更改)
  11. /********************************************************************************************/
  12. #define                LCM2402_DB0_DB7                P1                        // 定義LCM2402的數(shù)據(jù)總線
  13. sbit LCM2402_RS   = P3 ^ 2;                                        // 定義LCM2402的RS控制線
  14. sbit LCM2402_RW   = P3 ^ 3;                                        // 定義LCM2402的RW控制線
  15. sbit LCM2402_E    = P3 ^ 4;                                        // 定義LCM2402的E控制線
  16. sbit LCM2402_Busy = P1 ^ 7;                                        // 定義LCM2402的測(cè)忙線(與LCM2402_DB0_DB7關(guān)聯(lián))
  17. data unsigned char DIS_BIT = 0; //多種信息的切換顯示
  18. data unsigned char day = 0; //星期
  19. /********************************************************************************************
  20. // 定義LCM2402指令集 // (詳細(xì)請(qǐng)見(jiàn)技術(shù)手冊(cè))
  21. /********************************************************************************************/
  22. #define                        CMD_clear                0x01             // 清除屏幕
  23. #define                        CMD_back                0x02             // DDRAM回零位
  24. #define                        CMD_dec1                0x04             // 讀入后AC(指針)減1,向左寫
  25. #define                        CMD_add1                0x06             // 讀入后AC(指針)加1,向右寫
  26. #define                        CMD_dis_gb1                0x0f             // 開(kāi)顯示_開(kāi)光標(biāo)_開(kāi)光標(biāo)閃爍
  27. #define                        CMD_dis_gb2                0x0e             // 開(kāi)顯示_開(kāi)光標(biāo)_關(guān)光標(biāo)閃爍
  28. #define                        CMD_dis_gb3                0x0c             // 開(kāi)顯示_關(guān)光標(biāo)_關(guān)光標(biāo)閃爍
  29. #define                        CMD_OFF_dis                0x08             // 關(guān)顯示_關(guān)光標(biāo)_關(guān)光標(biāo)閃爍
  30. #define                        CMD_set82                0x38             // 8位總線_2行顯示
  31. #define                        CMD_set81                0x30             // 8位總線_1行顯示(上邊行)
  32. #define                        CMD_set42                0x28             // 4位總線_2行顯示
  33. #define                        CMD_set41                0x20             // 4位總線_1行顯示(上邊行)
  34. #define                        lin_1                        0x80             // 4位總線_1行顯示(上邊行)
  35. #define                        lin_2                        0xc0             // 4位總線_1行顯示(上邊行)

  36. /********************************************************************************************
  37. // 讀LCM忙程序 [底層協(xié)議] // (所有底層協(xié)議都無(wú)需關(guān)注)
  38. // LCM2402測(cè)忙,若LCM2402處于忙狀態(tài),本函數(shù)將等待至非忙狀態(tài) //
  39. /********************************************************************************************/
  40. void LCM2402_TestBusy(void){
  41.            LCM2402_DB0_DB7 = 0xff;                //設(shè)備讀狀態(tài)
  42.            LCM2402_RS = 0;
  43.            LCM2402_RW = 1;
  44.            LCM2402_E = 1;
  45.            while(LCM2402_Busy);                //等待LCM不忙
  46.            LCM2402_E = 0;                                //
  47. }
  48. /********************************************************************************************
  49. // 寫指令程序 //
  50. // 向LCM2402寫命令 本函數(shù)需要1個(gè)指令集的入口參數(shù) //
  51. /********************************************************************************************/
  52. void LCM2402_WriteCMD(uint8 LCM2402_command) {
  53.           LCM2402_TestBusy();
  54.           LCM2402_DB0_DB7 = LCM2402_command;
  55.           LCM2402_RS = 0;
  56.           LCM2402_RW = 0;
  57.           LCM2402_E = 1;
  58.           LCM2402_E = 0;
  59. }
  60. /********************************************************************************************
  61. // 寫數(shù)據(jù)程序 //
  62. // 向LCM2402寫數(shù)據(jù) //
  63. /********************************************************************************************/
  64. void LCM2402_WriteData(uint8 LCM2402_data){
  65.     LCM2402_TestBusy();
  66.         LCM2402_DB0_DB7 = LCM2402_data;
  67.           LCM2402_RS = 1;
  68.           LCM2402_RW = 0;
  69.           LCM2402_E = 1;
  70.           LCM2402_E = 0;
  71. }
  72. /********************************************************************************************
  73. // 打印字符串程序 // (本函數(shù)調(diào)用指針函數(shù))
  74. // 向LCM發(fā)送一個(gè)字符串,長(zhǎng)度48字符之內(nèi)
  75. // 第一行位置 0x00~0x17  第二行位置 0x40~0x57
  76. // 應(yīng)用舉例:print(0x80,"doyoung.net"); //在第一行第一位處從左向右打印doyoung.net字符串
  77. /********************************************************************************************/
  78. void print(uint8 a,uint8 *str){
  79.         LCM2402_WriteCMD(a | 0x80);
  80.         while(*str != '\0'){
  81.                 LCM2402_WriteData(*str++);
  82.         }
  83.         *str = 0;
  84. }
  85. /********************************************************************************************
  86. // 打印單字符程序 //
  87. // 第一行位置 0x00~0x17  第二行位置 0x40~0x57
  88. // 向LCM發(fā)送一個(gè)字符,以十六進(jìn)制(0x00)表示
  89. // 應(yīng)用舉例:print(0xc0,0x30); //在第二行第一位處打印字符“0”
  90. /********************************************************************************************/
  91. void print2(uint8 a,uint8 t){
  92.                 LCM2402_WriteCMD(a | 0x80);
  93.                 LCM2402_WriteData(t);
  94. }
  95. /********************************************************************************************
  96. // 定義小漢字 //
  97. // 可寫入8個(gè)自字義字符,寫入后可用其CGRAM代碼直接提取顯示。
  98. // 字符定義方法請(qǐng)參考技術(shù)手冊(cè)
  99. /********************************************************************************************/
  100. uint8 code Xword[]={
  101.     0x18,0x18,0x07,0x08,0x08,0x08,0x07,0x00,        //℃,代碼 0x00
  102.     0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,        //一,代碼 0x01
  103.     0x00,0x00,0x00,0x0e,0x00,0xff,0x00,0x00,        //二,代碼 0x02
  104.     0x00,0x00,0xff,0x00,0x0e,0x00,0xff,0x00,        //三,代碼 0x03
  105.     0x00,0x00,0xff,0xf5,0xfb,0xf1,0xff,0x00,        //四,代碼 0x04
  106.     0x00,0xfe,0x08,0xfe,0x0a,0x0a,0xff,0x00,        //五,代碼 0x05
  107.     0x00,0x04,0x00,0xff,0x00,0x0a,0x11,0x00,        //六,代碼 0x06
  108.     0x00,0x1f,0x11,0x1f,0x11,0x11,0x1f,0x00,        //日,代碼 0x07
  109. };
  110. void CgramWrite(void) {        // 裝入CGRAM //
  111.     uint8 i;
  112.         LCM2402_WriteCMD(0x06);                        // CGRAM地址自動(dòng)加1
  113.         LCM2402_WriteCMD(0x40);                        // CGRAM地址設(shè)為00處
  114.     for(i=0;i<64;i++) {
  115.             LCM2402_WriteData(Xword[i]);// 按數(shù)組寫入數(shù)據(jù)
  116.     }
  117. }
  118. /********************************************************************************************
  119. // LCM2402初始化 //(使用者可自定義,加 * 號(hào)程序行必須保留但可修改)
  120. /********************************************************************************************/
  121. void LCM2402_Init(void){
  122.           LCM2402_WriteCMD(CMD_set82);        //* 顯示模式設(shè)置:顯示2行,每個(gè)字符為5*7個(gè)像素
  123.           LCM2402_WriteCMD(CMD_clear);        //  顯示清屏
  124.           LCM2402_WriteCMD(CMD_back);                //* 數(shù)據(jù)指針指向第1行第1個(gè)字符位置
  125.           LCM2402_WriteCMD(CMD_add1);                //  顯示光標(biāo)移動(dòng)設(shè)置:文字不動(dòng),光標(biāo)右移
  126.           LCM2402_WriteCMD(CMD_dis_gb3);         //  顯示開(kāi)及光標(biāo)設(shè)置:顯示開(kāi),光標(biāo)開(kāi),閃爍開(kāi)
  127.         CgramWrite();                                        //  向CGRAM寫入自定義字符
  128. }
  129. /********************************************************************************************/
  130. //                        以上是LCM2402驅(qū)動(dòng)程序                        //
  131. /*********************************************************************************************/

  132. /*****************************************************************************/
  133. //定義DS1302時(shí)鐘接口
  134. sbit clock_clk = P3 ^ 7;//ds1302_clk(時(shí)鐘線)
  135. sbit clock_dat = P3 ^ 1;//ds1302_dat(數(shù)據(jù)線)
  136. sbit clock_Rst = P3 ^ 5;//ds1302_Rst(復(fù)位線)
  137. /*****************************************************************************/
  138. //定義累加器A中的各位
  139. sbit a0   = ACC ^ 0;
  140. sbit a1   = ACC ^ 1;
  141. sbit a2   = ACC ^ 2;
  142. sbit a3   = ACC ^ 3;
  143. sbit a4   = ACC ^ 4;
  144. sbit a5   = ACC ^ 5;
  145. sbit a6   = ACC ^ 6;
  146. sbit a7   = ACC ^ 7;
  147. /****************************************************************************/
  148. //定義全局變量
  149. //unsigned char yy,mo,dd,xq,hh,mm,ss;//定義時(shí)間映射全局變量(專用寄存器)

  150. bit w = 0; //調(diào)時(shí)標(biāo)志位
  151. /*****************************************************************************/
  152. //1302驅(qū)動(dòng)程序(底層協(xié)議)
  153. void clock_out(unsigned char dd){
  154.         ACC=dd;
  155.         clock_dat=a0; clock_clk=1; clock_clk=0;
  156.         clock_dat=a1; clock_clk=1; clock_clk=0;
  157.         clock_dat=a2; clock_clk=1; clock_clk=0;
  158.         clock_dat=a3; clock_clk=1; clock_clk=0;
  159.         clock_dat=a4; clock_clk=1; clock_clk=0;
  160.         clock_dat=a5; clock_clk=1; clock_clk=0;
  161.         clock_dat=a6; clock_clk=1; clock_clk=0;
  162.         clock_dat=a7; clock_clk=1; clock_clk=0;
  163. }
  164. /*****************************************************************************/
  165. //DS1302寫入字節(jié)(底層協(xié)議)
  166. unsigned char clock_in(void){
  167.         clock_dat=1;
  168.         a0=clock_dat;
  169.         clock_clk=1; clock_clk=0; a1=clock_dat;
  170.         clock_clk=1; clock_clk=0; a2=clock_dat;
  171.         clock_clk=1; clock_clk=0; a3=clock_dat;
  172.         clock_clk=1; clock_clk=0; a4=clock_dat;
  173.         clock_clk=1; clock_clk=0; a5=clock_dat;
  174.         clock_clk=1; clock_clk=0; a6=clock_dat;
  175.         clock_clk=1; clock_clk=0; a7=clock_dat;
  176.         return(ACC);
  177. }
  178. /*****************************************************************************/
  179. //DS1302寫數(shù)據(jù)(底層協(xié)議)
  180. void write_clock(unsigned char ord, unsigned char dd){
  181.         clock_clk=0;
  182.         clock_Rst=0;
  183.         clock_Rst=1;
  184.         clock_out(ord);
  185.         clock_out(dd);
  186.         clock_Rst=0;
  187.         clock_clk=1;
  188. }
  189. /*****************************************************************************/
  190. //DS1302讀數(shù)據(jù)(底層協(xié)議)
  191. unsigned char read_clock(unsigned char ord){
  192.         unsigned char dd=0;
  193.         clock_clk=0;
  194.         clock_Rst=0;
  195.         clock_Rst=1;
  196.         clock_out(ord);
  197.         dd=clock_in();
  198.         clock_Rst=0;
  199.         clock_clk=1;
  200.         return(dd);
  201. }
  202. /*****************************************************************************/
  203. //檢測(cè)時(shí)鐘芯片是否未被初始化,如是則設(shè)置1302的初始時(shí)間
  204. void Init_1302(void){//(2020年10月31日00時(shí)00分00秒星期一)
  205.         if(read_clock(0xc1) != 0xaa){
  206.                 write_clock(0x8e,0x00);//允許寫操作
  207.                 write_clock(0x8c,0x20);//年
  208.                 write_clock(0x8a,0x06);//星期
  209.                 write_clock(0x88,0x10);//月
  210.                 write_clock(0x86,0x31);//日
  211.                 write_clock(0x84,0x00);//小時(shí)
  212.                 write_clock(0x82,0x00);//分鐘
  213.                 write_clock(0x80,0x00);//秒
  214.                 write_clock(0x90,0xa5);//充電        
  215.                 write_clock(0xc0,0xaa);//寫入初始化標(biāo)志RAM(第00個(gè)RAM位置)
  216.                 write_clock(0x8e,0x80);//禁止寫操作
  217.         }
  218. }
  219. /********************************************************************************************/
  220. /**********************************************************************************************/        
  221. void init (void){ //上電初始化
  222.         TMOD = 0x11;         // 定時(shí)/計(jì)數(shù)器0,1工作于方式1   
  223.     TH0 = 0x3c;          // 預(yù)置產(chǎn)生50ms時(shí)基信號(hào)   
  224.     TL0 = 0xb0;   
  225.     EA = 1;              // 開(kāi)總中斷   
  226.     ET0 = 1;             // 定時(shí)/計(jì)數(shù)器0允許中斷   
  227.     TR0 = 1;             // 開(kāi)閉定時(shí)/計(jì)數(shù)器0   
  228. }
  229. /********************************************************************************************
  230. //顯示項(xiàng)目 時(shí)間部分 在第一行全行顯示時(shí)間
  231. *********************************************************************************************/   
  232. void RealTime_Display(void){
  233.                
  234.           switch (day){                 
  235.                  case 1: print(0x8c,"Mon"); break;
  236.                  case 2: print(0x8c,"Tues"); break;
  237.                  case 3: print(0x8c,"Wed"); break;
  238.                  case 4: print(0x8c,"Thur"); break;
  239.                  case 5: print(0x8c,"Fir"); break;
  240.                  case 6: print(0x8c,"Sat"); break;
  241.                  case 7: print(0x8c,"Sun"); break;
  242.           }
  243.         
  244.             print(0x80,"20");
  245.             print2(0x82,(read_clock(0x8d)/16)+0x30);
  246.             print2(0x83,(read_clock(0x8d)%16)+0x30);
  247.                 print(0x84,"/");            // 顯示年
  248.                 //
  249.             print2(0x85,(read_clock(0x89)/16)+0x30);
  250.             print2(0x86,(read_clock(0x89)%16)+0x30);
  251.                 print(0x87,"/");            // 顯示月
  252.                 //
  253.             print2(0x88,(read_clock(0x87)/16)+0x30);
  254.             print2(0x89,(read_clock(0x87)%16)+0x30);
  255.     // 顯示日
  256.                
  257.             print2(0x41,(read_clock(0x85)/16)+0x30);//小時(shí)
  258.             print2(0x42,(read_clock(0x85)%16)+0x30);
  259.                 print(0x43,":");            // 顯示cgram第一個(gè)字模":"
  260.                 //
  261.             print2(0x44,(read_clock(0x83)/16)+0x30);//分鐘
  262.             print2(0x45,(read_clock(0x83)%16)+0x30);
  263.                 print(0x46,".");            // 顯示cgram第一個(gè)字模"."
  264.                 //
  265.             print2(0x47,(read_clock(0x81)/16)+0x30);//秒
  266.             print2(0x48,(read_clock(0x81)%16)+0x30);
  267.                 //
  268.                 print(0x49," ");//在主顯示區(qū)空白處寫入空格 防止亂碼
  269.                 print(0x52," ");
  270.                 print(0x52," ");
  271.                
  272. }
  273. /********************************************************************************************/
  274. // 測(cè)試用函數(shù) //
  275. void main (void){
  276.         init();//初始化                           
  277.         LCM2402_Init();//LCM2402初始化   
  278.   Init_1302();//DS1302初始化  
  279.         while(1){ //主線程//
  280.                 RealTime_Display();            
  281. //        print(0x40,"www.torrancerestoration.com"); //在第一行第一位處從左向右打印www.torrancerestoration.com字符串
  282.                 day=(read_clock(0x8b)%16)+0x30; //星期

  283.   }
  284. }
  285. /********************************************************************************************/   
復(fù)制代碼




作者: chenyinhu    時(shí)間: 2020-10-31 20:35
switch (day)里面加一個(gè)default測(cè)試一下有沒(méi)有顯示,如果有顯示就是day有問(wèn)題
作者: hhdsdy    時(shí)間: 2020-10-31 20:58
你這程序是拼湊的嗎?你的年月日等為了顯示都是+30轉(zhuǎn)換成ASCII碼,但星期的顯示方式卻是不一樣,是字符串直接顯示,而判斷卻是1到7,但是從1302提取數(shù)據(jù)后卻習(xí)慣性+30(286行的day=(read_clock(0x8b)%16)+0x30; //星期),這樣肯定造成判斷錯(cuò)誤而不會(huì)顯示星期的英文字母串,把+30去掉試試吧

作者: a1051118722    時(shí)間: 2020-10-31 22:44
加一個(gè)default測(cè)試一下
作者: gqzjl    時(shí)間: 2020-11-1 10:17
謝謝大佬們的幫助,問(wèn)題解決了
作者: hhdsdy    時(shí)間: 2020-11-1 17:54
gqzjl 發(fā)表于 2020-11-1 10:17
謝謝大佬們的幫助,問(wèn)題解決了

你的程序都貼在這里了,不管問(wèn)題怎么解決的,說(shuō)一下哪里出錯(cuò)怎么解決的,也給大家學(xué)習(xí)一下吧。
作者: gqzjl    時(shí)間: 2023-5-3 07:22
hhdsdy 發(fā)表于 2020-11-1 17:54
你的程序都貼在這里了,不管問(wèn)題怎么解決的,說(shuō)一下哪里出錯(cuò)怎么解決的,也給大家學(xué)習(xí)一下吧。

Emmm,一眨眼就過(guò)了三年。剛剛翻了下以前的程序,第286行的day=(read_clock(0x8b)%16)+0x30;只要改成day=read_clock(0x8b);就行了(+0x30是轉(zhuǎn)成ASCII,%16是取低位)




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1