找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1875|回复: 4
收起左侧

stc89c52单片机+DS1302+LCD1602无法正常显示

[复制链接]
ID:669435 发表于 2019-12-20 20:27 | 显示全部楼层 |阅读模式
150030cntyed1qqtq1qtdh.jpg.thumb.jpg

会刷新,但显示乱码,芯片stc89c52,LCD1602,DS1302,请问这是什么情况?
代码如下:
  1. #include "DS1302.h"
  2. #include "LCD1602.h"
  3. #include <reg52.h>


  4. sbit SCLK = P1^0;//时钟线
  5. sbit IO        = P1^1;         //数据输/入输出线
  6. sbit RST = P1^2; //复位脚


  7. unsigned char now_date[] = { 0 };
  8. unsigned char old_date[] = { 19, 40, 14, 16, 12, 19 };


  9. void delay_ms(unsigned int time)
  10. {
  11.         unsigned int a, b;
  12.         for (a = time; a > 0; a--)
  13.                 for (b = 114; b > 0; b--);
  14. }


  15. void main()
  16. {
  17.         DS1302_write(0x8e, 0);//关闭写保护
  18.         DS1302_write(0x80, data_to_BCD(old_date[0]));//sec
  19.         DS1302_write(0x82, data_to_BCD(old_date[1]));//min
  20.         DS1302_write(0x84, data_to_BCD(old_date[2]));//hour
  21.         DS1302_write(0x86, data_to_BCD(old_date[3]));//day
  22.         DS1302_write(0x88, data_to_BCD(old_date[4]));//month
  23.         DS1302_write(0x8c, data_to_BCD(old_date[5]));//year
  24.         DS1302_write(0x8e, 0x80);//开启写保护
  25.         LCD1602_init();//LCD1602初始化
  26.         LCD1602_write_string("Date:20", 7);
  27.         LCD1602_write_cmd(0x80 | 0x40);//第一行第一格开始写
  28.         LCD1602_write_string("Time:", 5);
  29.         while (1)
  30.         {
  31.                 DS1302_write(0x8e, 0);//关闭写保护
  32.                 now_date[0] = BCD_to_data(DS1302_read(0x81));
  33.                 now_date[1] = BCD_to_data(DS1302_read(0x83));
  34.                 now_date[2] = BCD_to_data(DS1302_read(0x85));
  35.                 now_date[3] = BCD_to_data(DS1302_read(0x87));
  36.                 now_date[4] = BCD_to_data(DS1302_read(0x89));
  37.                 now_date[5] = BCD_to_data(DS1302_read(0x8D));
  38.                 DS1302_write(0x8e, 0x80);//开启写保护


  39.                 LCD1602_write_cmd(0x80 | 0x08);
  40.                 LCD1602_write_data('0' + now_date[5]);
  41.                 LCD1602_write_data('-');
  42.                 LCD1602_write_data('0' + now_date[4]);
  43.                 LCD1602_write_data('-');
  44.                 LCD1602_write_data('0' + now_date[3]);
  45.                
  46.                 LCD1602_write_cmd(0x80 | 0x46);
  47.                 LCD1602_write_data('0' + now_date[2]);
  48.                 LCD1602_write_data(':');
  49.                 LCD1602_write_data('0' + now_date[1]);
  50.                 LCD1602_write_data(':');
  51.                 LCD1602_write_data('0' + now_date[0]);
  52.                
  53.                 delay_ms(500);      
  54.         }
  55. }


  56. void DS1302_write_byte(unsigned char dat)//写一个字节数据
  57. {
  58.         unsigned char i;
  59.         for (i = 0; i < 8; i++)
  60.         {
  61.                 SCLK = 0;                //为下次产生上升沿做准备
  62.                 IO = dat & 0x01;//从最低位开始读
  63.                 SCLK = 1;                //产生上升沿,读走数据
  64.                 dat >>= 1;                //露出屁股让它读
  65.         }
  66. }


  67. unsigned char DS1302_read_byte()//读取一个字节数据
  68. {
  69.         unsigned char i, dat;
  70.         for (i = 0; i < 8; i++)//先写命令
  71.         {
  72.                 SCLK = 0;                //为下次产生上升沿做准备
  73.                 dat >>= 1;
  74.                 IF (IO)
  75.                         dat |= 0x80;//先写到最高位,然后再移过去
  76.                 SCLK = 1;                //产生上升沿,读走数据
  77.         }
  78.         return dat;      
  79. }


  80. void DS1302_write(unsigned char cmd, unsigned char dat)
  81. {
  82.         RST = 0;
  83.         SCLK = 0;
  84.         RST = 1;//开始
  85.         DS1302_write_byte(cmd);//写命令
  86.         DS1302_write_byte(dat);//写数据
  87.         SCLK = 1;
  88.         RST = 0;
  89. }


  90. unsigned char DS1302_read(unsigned cmd)
  91. {
  92.         unsigned char dat;
  93.         RST = 0;
  94.         SCLK = 0;
  95.         RST = 1;//开始
  96.         DS1302_write_byte(cmd);//写命令
  97.         dat = DS1302_read_byte();//读取数据
  98.         SCLK = 1;
  99.         RST = 0;
  100.         return dat;
  101. }


  102. unsigned char data_to_BCD(unsigned char dat)//数据转BCD码
  103. {
  104.         unsigned char temp;
  105.         temp = dat / 10;
  106.         dat %= 10;
  107.         dat = dat + temp * 16;
  108.         return dat;
  109. }


  110. unsigned char BCD_to_data(unsigned char dat)//BCD码转数据
  111. {
  112.         unsigned char temp;
  113.         temp = dat / 16;
  114.         dat %= 16;
  115.         dat = dat + temp * 10;
  116.         return dat;
  117. }
复制代码


回复

使用道具 举报

ID:617449 发表于 2019-12-22 09:15 | 显示全部楼层
你好!重点检查一下DS1302读取时序吧
回复

使用道具 举报

ID:213173 发表于 2019-12-22 15:32 | 显示全部楼层
楼主把读取1302的十进制2位数直接保存在显示缓存中,再送到1602,造成乱码。必须把十进制位数分解保存,按单个字符送到1602才行。程序补充完整显示正常。缓存写法unsigned char now_date[12];
无标题.jpg
  1. #include <reg52.h>

  2. //sbit LCD_RW=P2^6;                                //液晶屏RS口接地
  3. sbit LCD_RS=P2^5;                                        //液晶屏RS口
  4. sbit LCD_EN=P2^4;                                        //液晶屏EN口

  5. sbit SCLK = P1^0;//时钟线
  6. sbit IO   = P1^1; //数据输/入输出线
  7. sbit RST  = P1^2; //复位脚

  8. unsigned char now_a[] = "Date:20";//第一行固定字符
  9. unsigned char now_d[] = "Time:";//第二行固定字符
  10. unsigned char now_date[12];
  11. unsigned char old_date[] = { 19, 40, 14, 16, 12, 19 };


  12. void delay_ms(unsigned int time)
  13. {
  14.         unsigned int a, b;
  15.         for (a = time; a > 0; a--)
  16.                 for (b = 114; b > 0; b--);
  17. }

  18. void DS1302_write_byte(unsigned char dat)//写一个字节数据
  19. {
  20.         unsigned char i;
  21.         for (i = 0; i < 8; i++)
  22.         {
  23.                 SCLK = 0;                //为下次产生上升沿做准备
  24.                 IO = dat & 0x01;//从最低位开始读
  25.                 SCLK = 1;                //产生上升沿,读走数据
  26.                 dat >>= 1;                //露出屁股让它读
  27.         }
  28. }


  29. unsigned char DS1302_read_byte()//读取一个字节数据
  30. {
  31.         unsigned char i, dat;
  32.         for (i = 0; i < 8; i++)//先写命令
  33.         {
  34.                 SCLK = 0;                //为下次产生上升沿做准备
  35.                 dat >>= 1;
  36.                 if (IO)
  37.                         dat |= 0x80;//先写到最高位,然后再移过去
  38.                 SCLK = 1;                //产生上升沿,读走数据
  39.         }
  40.         return dat;      
  41. }


  42. void DS1302_write(unsigned char cmd, unsigned char dat)
  43. {
  44.         RST = 0;
  45.         SCLK = 0;
  46.         RST = 1;//开始
  47.         DS1302_write_byte(cmd);//写命令
  48.         DS1302_write_byte(dat);//写数据
  49.         SCLK = 1;
  50.         RST = 0;
  51. }


  52. unsigned char DS1302_read(unsigned cmd)
  53. {
  54.         unsigned char dat;
  55.         RST = 0;
  56.         SCLK = 0;
  57.         RST = 1;//开始
  58.         DS1302_write_byte(cmd);//写命令
  59.         dat = DS1302_read_byte();//读取数据
  60.         SCLK = 1;
  61.         RST = 0;
  62.         return dat;
  63. }


  64. unsigned char data_to_BCD(unsigned char dat)//数据转BCD码
  65. {
  66.         unsigned char temp;
  67.         temp = dat / 10;
  68.         dat %= 10;
  69.         dat = dat + temp * 16;
  70.         return dat;
  71. }


  72. unsigned char BCD_to_data(unsigned char dat)//BCD码转数据
  73. {
  74.         unsigned char temp;
  75.         temp = dat / 16;
  76.         dat %= 16;
  77.         dat = dat + temp * 10;
  78.         return dat;
  79. }
  80. /*******100us延时程序********/
  81. void delay(unsigned int x)
  82. {
  83.         unsigned int a,b;
  84.         for(a=x;a>0;a--)
  85.                 for(b=10;b>0;b--);
  86. }
  87. /*******1602液晶屏写指令程序********/
  88. void LCD1602_write_cmd(unsigned char com)
  89. {
  90.         LCD_EN=0;        //初始设置LCD_EN低电平
  91.         LCD_RS=0;        //允许写指令
  92.         P0=com;                //传递指令
  93.         delay(10);        //延时1ms
  94.         LCD_EN=1;        //使能写入
  95.         delay(10);        //延时1ms
  96.         LCD_EN=0;        //低跳变执行
  97.        
  98. }
  99. /*******1602液晶屏写数据程序********/
  100. void LCD1602_write_data(unsigned char date)
  101. {
  102. //        LCD_EN=0;        //初始设置LCD_EN低电平
  103.         LCD_RS=1;        //允许写数据
  104.         P0 =date;        //传递数据
  105.         delay(10);        //延时1ms
  106.         LCD_EN=1;        //使能写入
  107.         delay(10);        //延时1ms
  108.         LCD_EN=0;        //低跳变执行
  109.        
  110. }
  111. /*******1602液晶屏初始化程序********/
  112. void LCD1602_init()                //设置显示模式、
  113. {
  114.         LCD1602_write_cmd(0x38);//设置16*2显示,5*7点阵,8位数据接口
  115.         LCD1602_write_cmd(0x01);//显示清零,数据指针清零
  116. //        write_com(0x0f);//设置开显示,显示光标,光标闪烁
  117. //        write_com(0x0e);//设置开显示,显示光标,光标不闪
  118.         LCD1602_write_cmd(0x0c);//设置开显示,不显光标
  119.         LCD1602_write_cmd(0x06);//设置写一个字符后地址指针加1
  120. //        write_com(0x07);//设置写一个字符后整屏左移
  121.         LCD1602_write_cmd(0x80);//数据指针初始化,设置显示初始位置
  122. }
  123. void main()
  124. {
  125.         unsigned char i;
  126.        DS1302_write(0x8e, 0);//关闭写保护
  127.         DS1302_write(0x80, data_to_BCD(old_date[0]));//sec
  128.         DS1302_write(0x82, data_to_BCD(old_date[1]));//min
  129.         DS1302_write(0x84, data_to_BCD(old_date[2]));//hour
  130.         DS1302_write(0x86, data_to_BCD(old_date[3]));//day
  131.         DS1302_write(0x88, data_to_BCD(old_date[4]));//month
  132.         DS1302_write(0x8c, data_to_BCD(old_date[5]));//year
  133.         DS1302_write(0x8e, 0x80);//开启写保护

  134.         LCD1602_init();//LCD1602初始化
  135.         LCD1602_write_cmd(0x80);//第一行第一格开始写
  136.                         for(i=0;i<7;i++)
  137.                                 LCD1602_write_data(now_a[i]);
  138. //        LCD1602_write_string("Date:20", 7);
  139.         LCD1602_write_cmd(0xc0);//第二行第一格开始写
  140.                         for(i=0;i<5;i++)
  141.                                 LCD1602_write_data(now_d[i]);
  142. //        LCD1602_write_string("Time:", 5);
  143.         while (1)
  144.         {
  145.                                         DS1302_write(0x8e, 0);//关闭写保护
  146.                                         i = BCD_to_data(DS1302_read(0x81));
  147.                                         now_date[0] = i%10;
  148.                                         now_date[1] = i/10;
  149.                                         i = BCD_to_data(DS1302_read(0x83));
  150.                                         now_date[2] = i%10;
  151.                                         now_date[3] = i/10;
  152.                                         i = BCD_to_data(DS1302_read(0x85));
  153.                                         now_date[4] = i%10;
  154.                                         now_date[5] = i/10;
  155.                                         i = BCD_to_data(DS1302_read(0x87));
  156.                                         now_date[6] = i%10;
  157.                                         now_date[7] = i/10;
  158.                                         i = BCD_to_data(DS1302_read(0x89));
  159.                                         now_date[8] = i%10;
  160.                                         now_date[9] = i/10;
  161.                                         i = BCD_to_data(DS1302_read(0x8D));
  162.                                         now_date[10] = i%10;
  163.                                         now_date[11] = i/10;
  164.                DS1302_write(0x8e, 0x80);//开启写保护

  165.                                         LCD1602_write_cmd(0x80 | 0x07);
  166.                                        
  167.                                         LCD1602_write_data(now_date[11]+'0');
  168.                                         LCD1602_write_data(now_date[10]+'0');
  169.                                         LCD1602_write_data('-');
  170.                                         LCD1602_write_data(now_date[9]+'0');
  171.                                         LCD1602_write_data(now_date[8]+'0');
  172.                                         LCD1602_write_data('-');
  173.                                         LCD1602_write_data(now_date[7]+'0');
  174.                                         LCD1602_write_data(now_date[6]+'0');

  175.                                         LCD1602_write_cmd(0x80 | 0x45);                                       
  176.                                         LCD1602_write_data(now_date[5]+'0');
  177.                                         LCD1602_write_data(now_date[4]+'0');
  178.                                         LCD1602_write_data(':');
  179.                                         LCD1602_write_data(now_date[3]+'0');
  180.                                         LCD1602_write_data(now_date[2]+'0');
  181.                                         LCD1602_write_data(':');
  182.                                         LCD1602_write_data(now_date[1]+'0');
  183.                                         LCD1602_write_data(now_date[0]+'0');
  184.                                        
  185.                delay_ms(500);      
  186.         }
  187. }
复制代码



回复

使用道具 举报

ID:327029 发表于 2019-12-23 07:59 | 显示全部楼层
unsigned char now_date[] = { 0 };
unsigned char old_date[] = { 19, 40, 14, 16, 12, 19 };   这里的问题,单片机不能直接读取十进制数,把它分组转换为16进制即可
回复

使用道具 举报

ID:584814 发表于 2019-12-23 10:12 | 显示全部楼层
日期和时间应该每个都是两位可你的显示只有一位的空档,问题应该很清楚了,正如楼上所言。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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