找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1352|回复: 3
收起左侧

单片机液晶屏时钟的程序,如何加按键调时?求帮助

[复制链接]
ID:639106 发表于 2021-1-27 13:25 | 显示全部楼层 |阅读模式
一个关于液晶屏时钟的程序,没有按键调时,因为小白不会......哪位大神能指导一下,加在哪里?

单片机源程序如下:
  1. /********************************************************************************************
  2. 程序名:    1602液晶屏时钟
  3. 硬件支持:  LCD1602液晶屏  STC12C2052+外部12MHZ晶振 DS1302+32.768KHZ晶振
  4. 说明备注:    使用2402液晶屏程序,与1602液晶屏程序完全兼容
  5. /********************************************************************************************/
  6. #include <STC12C2052AD.h>                                                // 包含头文件 //
  7. /********************************************************************************************/
  8. typedef unsigned char      uint8;          // 无符号8位整型变量 //

  9. /********************************************************************************************
  10. // 引脚定义 // (使用者根据实际更改)
  11. /********************************************************************************************/
  12. #define                LCM2402_DB0_DB7                P1                        // 定义LCM2402的数据总线
  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关联)
  17. data unsigned char TIME_DD,TIME_MO,TIME_YY,TIME_WW,TIME_HH,TIME_MM,TIME_SS;//设置日、月、年、星期、时、分、秒存放区
  18. data unsigned char DIS_BIT = 0; //多种信息的切换显示
  19. /********************************************************************************************
  20. // 定义LCM2402指令集 // (详细请见技术手册)
  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             // 开显示_开光标_关光标闪烁
  28. #define                        CMD_dis_gb3                0x0c             // 开显示_关光标_关光标闪烁
  29. #define                        CMD_OFF_dis                0x08             // 关显示_关光标_关光标闪烁
  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忙程序 [底层协议] // (所有底层协议都无需关注)
  38. // LCM2402测忙,若LCM2402处于忙状态,本函数将等待至非忙状态 //
  39. /********************************************************************************************/
  40. void LCM2402_TestBusy(void){
  41.            LCM2402_DB0_DB7 = 0xff;                //设备读状态
  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写命令 本函数需要1个指令集的入口参数 //
  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. // 写数据程序 //
  65. // 向LCM2402写数据 //
  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. // 打印字符串程序 // (本函数调用指针函数)
  80. // 向LCM发送一个字符串,长度48字符之内
  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发送一个字符,以十六进制(0x00)表示
  94. // 应用举例: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. // 字符定义方法请参考技术手册
  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地址设为00处
  119.     for(i=0;i<64;i++) {
  120.             LCM2402_WriteData(Xword[i]);// 按数组写入数据
  121.     }
  122. }
  123. /********************************************************************************************
  124. // LCM2402初始化 //(使用者可自定义,加 * 号程序行必须保留但可修改)
  125. /********************************************************************************************/
  126. void LCM2402_Init(void){
  127.           LCM2402_WriteCMD(CMD_set42);        //* 显示模式设置:显示2行,每个字符为5*7个像素
  128.           LCM2402_WriteCMD(CMD_set42);        //* 显示模式设置:显示2行,每个字符为5*7个像素
  129.           LCM2402_WriteCMD(CMD_clear);        //  显示清屏
  130.           LCM2402_WriteCMD(CMD_back);                //* 数据指针指向第1行第1个字符位置
  131.           LCM2402_WriteCMD(CMD_add1);                //  显示光标移动设置:文字不动,光标右移
  132.           LCM2402_WriteCMD(CMD_dis_gb3);         //  显示开及光标设置:显示开,光标开,闪烁开
  133.         CgramWrite();                                        //  向CGRAM写入自定义字符
  134. }
  135. /********************************************************************************************/
  136. //                        以上是LCM2402驱动程序                        //
  137. /*********************************************************************************************/

  138. /*****************************************************************************/
  139. //注释DS1302寄存器
  140. // DS1302内部RAM分址:00 = 0xc0(写) = 0xc1(读)  奇数是读,偶数是写

  141. /*****************************************************************************/
  142. //定义DS1302时钟接口
  143. sbit clock_clk = P3 ^ 5;//ds1302_clk(时钟线)
  144. sbit clock_dat = P1 ^ 0;//ds1302_dat(数据线)
  145. sbit clock_Rst = P1 ^ 1;//ds1302_Rst(复位线)
  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驱动程序(底层协议)
  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写入字节(底层协议)
  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写数据(底层协议)
  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读数据(底层协议)
  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. //检测时钟芯片是否未被初始化,如是则设置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;         // 定时/计数器0,1工作于方式1   
  233.     TH0 = 0x3c;          // 预置产生50ms时基信号   
  234.     TL0 = 0xb0;   
  235.     EA = 1;              // 开总中断   
  236.     ET0 = 1;             // 定时/计数器0允许中断   
  237.     TR0 = 1;             // 开闭定时/计数器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," ");//在主显示区空白处写入空格 防止乱码
  276.                 print(0x4a," ");

  277. }
  278. /********************************************************************************************/
  279. // 测试用函数 //
  280. void main (void){
  281.         init();//初始化                           
  282.         LCM2402_Init();//LCM2402初始化                                          
  283.     Init_1302();//DS1302初始化                       
  284.         while(1){ //主线程//
  285. //           print(0x40,"www.51hei.com"); //在第一行第一位处从左向右打印www.51hei.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. /*********************************************************************************************/
复制代码


回复

使用道具 举报

ID:390416 发表于 2021-1-27 15:29 | 显示全部楼层
回复

使用道具 举报

ID:584814 发表于 2021-1-27 17:21 | 显示全部楼层
你的程序没抄全。可在本站搜索1602时钟就可以找到大把的例子。
回复

使用道具 举报

ID:752974 发表于 2021-1-28 10:24 | 显示全部楼层
单片机应用中,按键大都较简单,一般的是3~4个独立按键。硬件简单,软件就复杂,所有的按键功能都是软件完成的,具体代码因设计人员而异,没有通用的,给你一个现成的也嵌不到你的代码中。因此,还是找个别人调通的自己移植,这样能解决问题,又能学到东西。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表