找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1896|回复: 6
打印 上一主题 下一主题
收起左侧

这个单片机LCD1602时钟程序到底哪里出问题了?

[复制链接]
跳转到指定楼层
楼主
为什么我程序里定义了星期,这上面却不显示?显示用的是LCD1602,时钟用的是DS1302.求解


单片机源程序如下:
  1. /********************************************************************************************
  2. 程序名:    1602液晶屏时钟驱动程序
  3. 硬件支持:  LCD1602液晶屏  STC12C2052 外部12MHZ晶振
  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 DIS_BIT = 0; //多种信息的切换显示
  18. data unsigned char day = 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_DB0_DB7 = LCM2402_command;
  55.           LCM2402_RS = 0;
  56.           LCM2402_RW = 0;
  57.           LCM2402_E = 1;
  58.           LCM2402_E = 0;
  59. }
  60. /********************************************************************************************
  61. // 写数据程序 //
  62. // 向LCM2402写数据 //
  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. // 打印字符串程序 // (本函数调用指针函数)
  74. // 向LCM发送一个字符串,长度48字符之内
  75. // 第一行位置 0x00~0x17  第二行位置 0x40~0x57
  76. // 应用举例: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发送一个字符,以十六进制(0x00)表示
  89. // 应用举例: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个自字义字符,写入后可用其CGRAM代码直接提取显示。
  98. // 字符定义方法请参考技术手册
  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地址自动加1
  113.         LCM2402_WriteCMD(0x40);                        // CGRAM地址设为00处
  114.     for(i=0;i<64;i++) {
  115.             LCM2402_WriteData(Xword[i]);// 按数组写入数据
  116.     }
  117. }
  118. /********************************************************************************************
  119. // LCM2402初始化 //(使用者可自定义,加 * 号程序行必须保留但可修改)
  120. /********************************************************************************************/
  121. void LCM2402_Init(void){
  122.           LCM2402_WriteCMD(CMD_set82);        //* 显示模式设置:显示2行,每个字符为5*7个像素
  123.           LCM2402_WriteCMD(CMD_clear);        //  显示清屏
  124.           LCM2402_WriteCMD(CMD_back);                //* 数据指针指向第1行第1个字符位置
  125.           LCM2402_WriteCMD(CMD_add1);                //  显示光标移动设置:文字不动,光标右移
  126.           LCM2402_WriteCMD(CMD_dis_gb3);         //  显示开及光标设置:显示开,光标开,闪烁开
  127.         CgramWrite();                                        //  向CGRAM写入自定义字符
  128. }
  129. /********************************************************************************************/
  130. //                        以上是LCM2402驱动程序                        //
  131. /*********************************************************************************************/

  132. /*****************************************************************************/
  133. //定义DS1302时钟接口
  134. sbit clock_clk = P3 ^ 7;//ds1302_clk(时钟线)
  135. sbit clock_dat = P3 ^ 1;//ds1302_dat(数据线)
  136. sbit clock_Rst = P3 ^ 5;//ds1302_Rst(复位线)
  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;//定义时间映射全局变量(专用寄存器)

  150. bit w = 0; //调时标志位
  151. /*****************************************************************************/
  152. //1302驱动程序(底层协议)
  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写入字节(底层协议)
  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写数据(底层协议)
  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读数据(底层协议)
  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. //检测时钟芯片是否未被初始化,如是则设置1302的初始时间
  204. void Init_1302(void){//(2020年10月31日00时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);//小时
  212.                 write_clock(0x82,0x00);//分钟
  213.                 write_clock(0x80,0x00);//秒
  214.                 write_clock(0x90,0xa5);//充电        
  215.                 write_clock(0xc0,0xaa);//写入初始化标志RAM(第00个RAM位置)
  216.                 write_clock(0x8e,0x80);//禁止写操作
  217.         }
  218. }
  219. /********************************************************************************************/
  220. /**********************************************************************************************/        
  221. void init (void){ //上电初始化
  222.         TMOD = 0x11;         // 定时/计数器0,1工作于方式1   
  223.     TH0 = 0x3c;          // 预置产生50ms时基信号   
  224.     TL0 = 0xb0;   
  225.     EA = 1;              // 开总中断   
  226.     ET0 = 1;             // 定时/计数器0允许中断   
  227.     TR0 = 1;             // 开闭定时/计数器0   
  228. }
  229. /********************************************************************************************
  230. //显示项目 时间部分 在第一行全行显示时间
  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);//小时
  258.             print2(0x42,(read_clock(0x85)%16)+0x30);
  259.                 print(0x43,":");            // 显示cgram第一个字模":"
  260.                 //
  261.             print2(0x44,(read_clock(0x83)/16)+0x30);//分钟
  262.             print2(0x45,(read_clock(0x83)%16)+0x30);
  263.                 print(0x46,".");            // 显示cgram第一个字模"."
  264.                 //
  265.             print2(0x47,(read_clock(0x81)/16)+0x30);//秒
  266.             print2(0x48,(read_clock(0x81)%16)+0x30);
  267.                 //
  268.                 print(0x49," ");//在主显示区空白处写入空格 防止乱码
  269.                 print(0x52," ");
  270.                 print(0x52," ");
  271.                
  272. }
  273. /********************************************************************************************/
  274. // 测试用函数 //
  275. void main (void){
  276.         init();//初始化                           
  277.         LCM2402_Init();//LCM2402初始化   
  278.   Init_1302();//DS1302初始化  
  279.         while(1){ //主线程//
  280.                 RealTime_Display();            
  281. //        print(0x40,"www.51hei.com"); //在第一行第一位处从左向右打印www.51hei.com字符串
  282.                 day=(read_clock(0x8b)%16)+0x30; //星期

  283.   }
  284. }
  285. /********************************************************************************************/   
复制代码



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

来自 2#
ID:88256 发表于 2020-10-31 20:58 | 只看该作者
你这程序是拼凑的吗?你的年月日等为了显示都是+30转换成ASCII码,但星期的显示方式却是不一样,是字符串直接显示,而判断却是1到7,但是从1302提取数据后却习惯性+30(286行的day=(read_clock(0x8b)%16)+0x30; //星期),这样肯定造成判断错误而不会显示星期的英文字母串,把+30去掉试试吧

评分

参与人数 1黑币 +5 收起 理由
gqzjl + 5 谢谢,问题已解决!

查看全部评分

回复

使用道具 举报

板凳
ID:568565 发表于 2020-10-31 20:35 来自手机 | 只看该作者
switch (day)里面加一个default测试一下有没有显示,如果有显示就是day有问题

评分

参与人数 1黑币 +4 收起 理由
gqzjl + 4 赞一个!

查看全部评分

回复

使用道具 举报

地板
ID:592261 发表于 2020-10-31 22:44 | 只看该作者
加一个default测试一下
回复

使用道具 举报

5#
ID:639106 发表于 2020-11-1 10:17 | 只看该作者
谢谢大佬们的帮助,问题解决了
回复

使用道具 举报

6#
ID:88256 发表于 2020-11-1 17:54 | 只看该作者
gqzjl 发表于 2020-11-1 10:17
谢谢大佬们的帮助,问题解决了

你的程序都贴在这里了,不管问题怎么解决的,说一下哪里出错怎么解决的,也给大家学习一下吧。
回复

使用道具 举报

7#
ID:639106 发表于 2023-5-3 07:22 | 只看该作者
hhdsdy 发表于 2020-11-1 17:54
你的程序都贴在这里了,不管问题怎么解决的,说一下哪里出错怎么解决的,也给大家学习一下吧。

Emmm,一眨眼就过了三年。刚刚翻了下以前的程序,第286行的day=(read_clock(0x8b)%16)+0x30;只要改成day=read_clock(0x8b);就行了(+0x30是转成ASCII,%16是取低位)
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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