找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2145|回復(fù): 3
打印 上一主題 下一主題
收起左側(cè)

單片機液晶屏?xí)r鐘的程序,如何加按鍵調(diào)時?求幫助

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:639106 發(fā)表于 2021-1-27 13:25 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
一個關(guān)于液晶屏?xí)r鐘的程序,沒有按鍵調(diào)時,因為小白不會......哪位大神能指導(dǎo)一下,加在哪里?

單片機源程序如下:
  1. /********************************************************************************************
  2. 程序名:    1602液晶屏?xí)r鐘
  3. 硬件支持:  LCD1602液晶屏  STC12C2052+外部12MHZ晶振 DS1302+32.768KHZ晶振
  4. 說明備注:    使用2402液晶屏程序,與1602液晶屏程序完全兼容
  5. /********************************************************************************************/
  6. #include <STC12C2052AD.h>                                                // 包含頭文件 //
  7. /********************************************************************************************/
  8. typedef unsigned char      uint8;          // 無符號8位整型變量 //

  9. /********************************************************************************************
  10. // 引腳定義 // (使用者根據(jù)實際更改)
  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的測忙線(與LCM2402_DB0_DB7關(guān)聯(lián))
  17. data unsigned char TIME_DD,TIME_MO,TIME_YY,TIME_WW,TIME_HH,TIME_MM,TIME_SS;//設(shè)置日、月、年、星期、時、分、秒存放區(qū)
  18. data unsigned char DIS_BIT = 0; //多種信息的切換顯示
  19. /********************************************************************************************
  20. // 定義LCM2402指令集 // (詳細請見技術(shù)手冊)
  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             // 開顯示_開光標_開光標閃爍
  27. #define                        CMD_dis_gb2                0x0e             // 開顯示_開光標_關(guān)光標閃爍
  28. #define                        CMD_dis_gb3                0x0c             // 開顯示_關(guān)光標_關(guān)光標閃爍
  29. #define                        CMD_OFF_dis                0x08             // 關(guān)顯示_關(guān)光標_關(guān)光標閃爍
  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é)議都無需關(guān)注)
  38. // LCM2402測忙,若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個指令集的入口參數(shù) //
  51. /********************************************************************************************/
  52. void LCM2402_WriteCMD(uint8 LCM2402_command) {
  53.           LCM2402_TestBusy();
  54.           LCM2402_RS = 0;
  55.           LCM2402_RW = 0;
  56.           LCM2402_DB0_DB7 = (LCM2402_command/16)*16;
  57.           LCM2402_E = 1;
  58.           LCM2402_E = 0;
  59.           LCM2402_DB0_DB7 = (LCM2402_command%16)*16;
  60.           LCM2402_E = 1;
  61.           LCM2402_E = 0;
  62. }
  63. /********************************************************************************************
  64. // 寫數(shù)據(jù)程序 //
  65. // 向LCM2402寫數(shù)據(jù) //
  66. /********************************************************************************************/
  67. void LCM2402_WriteData(uint8 LCM2402_data){
  68.     LCM2402_TestBusy();
  69.           LCM2402_RS = 1;
  70.           LCM2402_RW = 0;
  71.         LCM2402_DB0_DB7 = (LCM2402_data/16)*16;
  72.           LCM2402_E = 1;
  73.           LCM2402_E = 0;
  74.         LCM2402_DB0_DB7 = (LCM2402_data%16)*16;
  75.           LCM2402_E = 1;
  76.           LCM2402_E = 0;
  77. }
  78. /********************************************************************************************
  79. // 打印字符串程序 // (本函數(shù)調(diào)用指針函數(shù))
  80. // 向LCM發(fā)送一個字符串,長度48字符之內(nèi)
  81. // 第一行位置 0x00~0x17  第二行位置 0x40~0x57
  82. /********************************************************************************************/
  83. void print(uint8 a,uint8 *str){
  84.         LCM2402_WriteCMD(a | 0x80);
  85.         while(*str != '\0'){
  86.                 LCM2402_WriteData(*str++);
  87.         }
  88.         *str = 0;
  89. }
  90. /********************************************************************************************
  91. // 打印單字符程序 //
  92. // 第一行位置 0x00~0x17  第二行位置 0x40~0x57
  93. // 向LCM發(fā)送一個字符,以十六進制(0x00)表示
  94. // 應(yīng)用舉例:print(0xc0,0x30); //在第二行第一位處打印字符“0”
  95. /********************************************************************************************/
  96. void print2(uint8 a,uint8 t){
  97.                 LCM2402_WriteCMD(a | 0x80);
  98.                 LCM2402_WriteData(t);
  99. }
  100. /********************************************************************************************
  101. // 定義小漢字 //
  102. // 可寫入8個自字義字符,寫入后可用其CGRAM代碼直接提取顯示。
  103. // 字符定義方法請參考技術(shù)手冊
  104. /********************************************************************************************/
  105. uint8 code Xword[]={
  106.     0x18,0x18,0x07,0x08,0x08,0x08,0x07,0x00,        //℃,代碼 0x00
  107.     0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,        //一,代碼 0x01
  108.     0x00,0x00,0x00,0x0e,0x00,0xff,0x00,0x00,        //二,代碼 0x02
  109.     0x00,0x00,0xff,0x00,0x0e,0x00,0xff,0x00,        //三,代碼 0x03
  110.     0x00,0x00,0xff,0xf5,0xfb,0xf1,0xff,0x00,        //四,代碼 0x04
  111.     0x00,0xfe,0x08,0xfe,0x0a,0x0a,0xff,0x00,        //五,代碼 0x05
  112.     0x00,0x04,0x00,0xff,0x00,0x0a,0x11,0x00,        //六,代碼 0x06
  113.     0x00,0x1f,0x11,0x1f,0x11,0x11,0x1f,0x00,        //日,代碼 0x07
  114. };
  115. void CgramWrite(void) {        // 裝入CGRAM //
  116.     uint8 i;
  117.         LCM2402_WriteCMD(0x06);                        // CGRAM地址自動加1
  118.         LCM2402_WriteCMD(0x40);                        // CGRAM地址設(shè)為00處
  119.     for(i=0;i<64;i++) {
  120.             LCM2402_WriteData(Xword[i]);// 按數(shù)組寫入數(shù)據(jù)
  121.     }
  122. }
  123. /********************************************************************************************
  124. // LCM2402初始化 //(使用者可自定義,加 * 號程序行必須保留但可修改)
  125. /********************************************************************************************/
  126. void LCM2402_Init(void){
  127.           LCM2402_WriteCMD(CMD_set42);        //* 顯示模式設(shè)置:顯示2行,每個字符為5*7個像素
  128.           LCM2402_WriteCMD(CMD_set42);        //* 顯示模式設(shè)置:顯示2行,每個字符為5*7個像素
  129.           LCM2402_WriteCMD(CMD_clear);        //  顯示清屏
  130.           LCM2402_WriteCMD(CMD_back);                //* 數(shù)據(jù)指針指向第1行第1個字符位置
  131.           LCM2402_WriteCMD(CMD_add1);                //  顯示光標移動設(shè)置:文字不動,光標右移
  132.           LCM2402_WriteCMD(CMD_dis_gb3);         //  顯示開及光標設(shè)置:顯示開,光標開,閃爍開
  133.         CgramWrite();                                        //  向CGRAM寫入自定義字符
  134. }
  135. /********************************************************************************************/
  136. //                        以上是LCM2402驅(qū)動程序                        //
  137. /*********************************************************************************************/

  138. /*****************************************************************************/
  139. //注釋DS1302寄存器
  140. // DS1302內(nèi)部RAM分址:00 = 0xc0(寫) = 0xc1(讀)  奇數(shù)是讀,偶數(shù)是寫

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

  159. /*****************************************************************************/
  160. //1302驅(qū)動程序(底層協(xié)議)
  161. void clock_out(unsigned char dd){
  162.         ACC=dd;
  163.         clock_dat=a0; clock_clk=1; clock_clk=0;
  164.         clock_dat=a1; clock_clk=1; clock_clk=0;
  165.         clock_dat=a2; clock_clk=1; clock_clk=0;
  166.         clock_dat=a3; clock_clk=1; clock_clk=0;
  167.         clock_dat=a4; clock_clk=1; clock_clk=0;
  168.         clock_dat=a5; clock_clk=1; clock_clk=0;
  169.         clock_dat=a6; clock_clk=1; clock_clk=0;
  170.         clock_dat=a7; clock_clk=1; clock_clk=0;
  171. }
  172. /*****************************************************************************/
  173. //DS1302寫入字節(jié)(底層協(xié)議)
  174. unsigned char clock_in(void){
  175.         clock_dat=1;
  176.         a0=clock_dat;
  177.         clock_clk=1; clock_clk=0; a1=clock_dat;
  178.         clock_clk=1; clock_clk=0; a2=clock_dat;
  179.         clock_clk=1; clock_clk=0; a3=clock_dat;
  180.         clock_clk=1; clock_clk=0; a4=clock_dat;
  181.         clock_clk=1; clock_clk=0; a5=clock_dat;
  182.         clock_clk=1; clock_clk=0; a6=clock_dat;
  183.         clock_clk=1; clock_clk=0; a7=clock_dat;
  184.         return(ACC);
  185. }
  186. /*****************************************************************************/
  187. //DS1302寫數(shù)據(jù)(底層協(xié)議)
  188. void write_clock(unsigned char ord, unsigned char dd){
  189.         clock_clk=0;
  190.         clock_Rst=0;
  191.         clock_Rst=1;
  192.         clock_out(ord);
  193.         clock_out(dd);
  194.         clock_Rst=0;
  195.         clock_clk=1;
  196. }
  197. /*****************************************************************************/
  198. //DS1302讀數(shù)據(jù)(底層協(xié)議)
  199. unsigned char read_clock(unsigned char ord){
  200.         unsigned char dd=0;
  201.         clock_clk=0;
  202.         clock_Rst=0;
  203.         clock_Rst=1;
  204.         clock_out(ord);
  205.         dd=clock_in();
  206.         clock_Rst=0;
  207.         clock_clk=1;
  208.         return(dd);
  209. }
  210. /*****************************************************************************/
  211. /*****************************************************************************/
  212. //檢測時鐘芯片是否未被初始化,如是則設(shè)置1302的初始時間
  213. void Init_1302(void){//(2007年1月1日00時00分00秒星期一)

  214.         if(read_clock(0xc1) != 0xaa){
  215.                 write_clock(0x8e,0x00);//允許寫操作
  216.                 write_clock(0x8c,0x21);//年
  217.                 write_clock(0x8a,0x07);//星期
  218.                 write_clock(0x88,0x01);//月
  219.                 write_clock(0x86,0x10);//日
  220.                 write_clock(0x84,0x09);//小時
  221.                 write_clock(0x82,0x00);//分鐘
  222.                 write_clock(0x80,0x00);//秒
  223.                 write_clock(0x90,0xa5);//充電        
  224.                 write_clock(0xc0,0xaa);//寫入初始化標志RAM(第00個RAM位置)
  225.                 write_clock(0x8e,0x80);//禁止寫操作
  226.         
  227.         }
  228. }
  229. /********************************************************************************************/
  230. /**********************************************************************************************/        
  231. void init (void){ //上電初始化
  232.         TMOD = 0x11;         // 定時/計數(shù)器0,1工作于方式1   
  233.     TH0 = 0x3c;          // 預(yù)置產(chǎn)生50ms時基信號   
  234.     TL0 = 0xb0;   
  235.     EA = 1;              // 開總中斷   
  236.     ET0 = 1;             // 定時/計數(shù)器0允許中斷   
  237.     TR0 = 1;             // 開閉定時/計數(shù)器0   
  238. ////
  239. /*
  240.         TIME_DD = 6; //時間在首次使用的值,之后會在EEPROM自動記錄上一天的值
  241.         TIME_MO        = 7; //初始時間:2009年5月18日周一,20時13分40秒
  242.         TIME_YY = 9;
  243.         TIME_WW = 1;
  244.         TIME_HH        = 0;
  245.         TIME_MM = 0;
  246.         TIME_SS = 0;
  247. */
  248. }
  249. /********************************************************************************************
  250. //顯示項目 時間部分 在第一行全行顯示時間
  251. *********************************************************************************************/   
  252. void RealTime_Display(void){
  253.             print(0x80,"20");
  254.             print2(0x82,(read_clock(0x8d)/16)+0x30);
  255.             print2(0x83,(read_clock(0x8d)%16)+0x30);
  256.                 print(0x84,"/");            // 顯示年
  257.                 //
  258.             print2(0x85,(read_clock(0x89)/16)+0x30);
  259.             print2(0x86,(read_clock(0x89)%16)+0x30);
  260.                 print(0x87,"/");            // 顯示月
  261.                 //
  262.             print2(0x88,(read_clock(0x87)/16)+0x30);
  263.             print2(0x89,(read_clock(0x87)%16)+0x30);

  264.             print2(0x40,(read_clock(0x85)/16)+0x30);//小時
  265.             print2(0x41,(read_clock(0x85)%16)+0x30);
  266.                 print(0x42,":");            // 顯示cgram第一個字模":"
  267.                 //
  268.             print2(0x43,(read_clock(0x83)/16)+0x30);//分鐘
  269.             print2(0x44,(read_clock(0x83)%16)+0x30);
  270.                 print(0x45,".");            // 顯示cgram第一個字模"."
  271.                 //
  272.             print2(0x46,(read_clock(0x81)/16)+0x30);//秒
  273.             print2(0x47,(read_clock(0x81)%16)+0x30);
  274.                 //
  275.                 print(0x49," ");//在主顯示區(qū)空白處寫入空格 防止亂碼
  276.                 print(0x4a," ");

  277. }
  278. /********************************************************************************************/
  279. // 測試用函數(shù) //
  280. void main (void){
  281.         init();//初始化                           
  282.         LCM2402_Init();//LCM2402初始化                                          
  283.     Init_1302();//DS1302初始化                       
  284.         while(1){ //主線程//
  285. //           print(0x40,"www.torrancerestoration.com"); //在第一行第一位處從左向右打印www.torrancerestoration.com字符串
  286.                  RealTime_Display();            
  287.              TIME_WW=read_clock(0x8b)%16;
  288.          switch (TIME_WW){               
  289.                    case 1:print(0x8c,"Mon.");break;                        
  290.                    case 2:print(0x8c,"Tues.");break;                        
  291.                    case 3:print(0x8c,"Wed.");break;                        
  292.                    case 4:print(0x8c,"Thur.");break;                        
  293.                    case 5:print(0x8c,"Fri.");break;                        
  294.                    case 6:print(0x8c,"Sat.");break;                        
  295.                    case 7:print(0x8c,"Sun.");break;                        
  296.                    default: print(0x8b,"Error");break;                                          
  297.                 }
  298.                   
  299.         }
  300. }

  301. /*********************************************************************************************/
復(fù)制代碼


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

使用道具 舉報

沙發(fā)
ID:390416 發(fā)表于 2021-1-27 15:29 | 只看該作者
回復(fù)

使用道具 舉報

板凳
ID:584814 發(fā)表于 2021-1-27 17:21 | 只看該作者
你的程序沒抄全?稍诒菊舅阉1602時鐘就可以找到大把的例子。
回復(fù)

使用道具 舉報

地板
ID:752974 發(fā)表于 2021-1-28 10:24 | 只看該作者
單片機應(yīng)用中,按鍵大都較簡單,一般的是3~4個獨立按鍵。硬件簡單,軟件就復(fù)雜,所有的按鍵功能都是軟件完成的,具體代碼因設(shè)計人員而異,沒有通用的,給你一個現(xiàn)成的也嵌不到你的代碼中。因此,還是找個別人調(diào)通的自己移植,這樣能解決問題,又能學(xué)到東西。
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表