找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1894|回复: 0
收起左侧

单片机+DS1302 LCD1602时间显示程序

[复制链接]
ID:925265 发表于 2021-9-4 12:59 | 显示全部楼层 |阅读模式
效果和接法看图吧,只是简单用时钟芯片显示时间
屏幕截图 2021-09-04 125226.png

单片机源程序如下:
  1.   #include <reg51.h>
  2.         #include <string.h>
  3.         #include <intrins.h>
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. #define delayNOP() {_nop_();_nop_();_nop_();_nop_();}
  7. sbit SDA=P2^6;  // DS1302数据线
  8. sbit CLK=P2^5;  //         DS1302时钟线
  9. sbit RST=P2^4;  // DS1302复位线
  10. //DS18B20数据端口定义
  11. sbit DQ=P2^4;    //DS18B20数据端口
  12. sbit LCD_RS=P2^0;   // LCD寄存器选择
  13. sbit LCD_RW=P2^1;   //         LCD读写/写控制
  14. sbit LCD_EN=P2^2;   //  LCD启用

  15. uchar tCount=0;
  16. //一年中每个月的天数,2月的天数由年份决定
  17. uchar MonthsDays[]={0,31,0,31,30,31,30,31,31,30,31,30,31};
  18. //周日,每周一到周六(0,1-6)【读取DS1302时分别是1-7】
  19. uchar *WEEK[]={"SUN","MON","TUS","WEN","THU","FRI","SAT"};

  20. //LCD显示缓冲
  21. uchar LCD_DSY_BUFFER1[]={"00-00-00        "};
  22. uchar LCD_DSY_BUFFER2[]={"00-00-00      "};
  23. uchar DateTime[7];  //所读取的日期时间
  24. uchar Adjust_flag=0; //当前调节的时间对像:秒,分,时,日,月,年(1,2,3,4,5,6)
  25. uchar Change_Flag[]=" YMDHM";//(分,时,日,月,年)(不调节秒与周)


  26. void DelayMS(uchar x)//延时
  27. {uchar i;
  28. while(x--)
  29. for(i=0;i<120;i++);
  30. }


  31. void Write_A_Byte_TO_DS1302(uchar x)//向DS1302写入一个字节
  32. {uchar i;
  33. for(i=0;i<8;i++)
  34. {SDA=x&1;  CLK=1;  CLK=0; x>>=1;
  35. }
  36. }


  37. uchar Get_A_Byte_FROM_DS1302()//读取一个字节
  38. {uchar i,b,t;
  39. for(i=0;i<8;i++)
  40. {b>>=1; t=SDA; b|=t<<7;  CLK=1;CLK=0;
  41. }

  42. return b/16*10+b%16;//BCD码转换
  43. }

  44. uchar Read_Data(uchar addr)//指定位置读数据
  45. {uchar dat;
  46. RST=0; CLK=0; RST=1;
  47. Write_A_Byte_TO_DS1302(addr);
  48. dat=Get_A_Byte_FROM_DS1302();
  49. CLK=1;RST=0;
  50. return dat;
  51. }

  52. void Write_DS1302(uchar addr,uchar dat)//向某地址写入数据
  53. {CLK=0;RST=1;
  54. Write_A_Byte_TO_DS1302(addr);
  55. Write_A_Byte_TO_DS1302(dat);
  56. CLK=0;RST=0;
  57. }

  58. void SET_DS1302()//设置时间
  59. { uchar i;
  60. Write_DS1302(0x8e,0x00);

  61. for(i=0;i<7;i++)
  62. {

  63. Write_DS1302(0X80+2*i,(DateTime[i]/10<<4)|(DateTime[i]%10));//日,月,周,年,写入 地址每次增2
  64. }
  65. Write_DS1302(0x8e,0x80);//加保护
  66. }


  67. void GetTime()//读取本地的时间
  68. {
  69.   uchar i;
  70.   for(i=0;i<7;i++)
  71.    {
  72.      DateTime[i]=Read_Data(0x81+2*i);
  73.    }
  74. }

  75. //LCD驱动代码
  76. bit LCD_Busy_Check()//LCD忙
  77. {bit result;
  78. LCD_RS=0;
  79. LCD_RW=1;
  80. LCD_EN=1;
  81. delayNOP();
  82. result=(bit)(P0&0x80);
  83. LCD_EN=0;
  84. return result;
  85. }


  86. void Write_LCD_Command(uchar cmd) //写指令
  87. {while(LCD_Busy_Check());
  88. LCD_RS=0;LCD_RW=0;LCD_EN=0;        _nop_();         _nop_();
  89. P0=cmd;
  90. delayNOP();
  91. LCD_EN=1;
  92. delayNOP();
  93. LCD_EN=0;
  94. }

  95. void Write_LCD_Data(uchar dat)//写数据
  96. {while(LCD_Busy_Check());
  97. LCD_RS=1;LCD_RW=0;LCD_EN=0;
  98. P0=dat;
  99. delayNOP();
  100. LCD_EN=1;
  101. delayNOP();
  102. LCD_EN=0;
  103. }


  104. void Init_LCD()//LCD初始化
  105. {Write_LCD_Command(0x01);DelayMS(5);
  106. Write_LCD_Command(0x38);DelayMS(5);
  107. Write_LCD_Command(0x0c);DelayMS(5);
  108. Write_LCD_Command(0x06);DelayMS(5);
  109. }

  110. void Set_LCD_POS(uchar pos)//设置显示位置
  111. {        Write_LCD_Command(pos|0x80);
  112.   }


  113. void Display_LCD_String(uchar p,uchar *s)//在LCD上显示字符串
  114. {uchar i;
  115. Set_LCD_POS(p);
  116. for(i=0;i<16;i++)
  117. {Write_LCD_Data(s[i]);
  118. DelayMS(1);
  119. }
  120. }


  121. void Format_DateTime(uchar d,uchar *a)//日期与时间值转换为数字字符
  122. {a[0]=d/10+'0';
  123. a[1]=d%10+'0';
  124. }


  125. uchar isLeapYear(uint y)//判断是否为闰年
  126. {return (y%4==0&&y%100!=0)||(y%400==0);
  127. }


  128. void RefreshWeekDay()
  129. {uint i,d,w=5; //
  130. for(i=2021;i<2021+DateTime[6];i++)
  131. { d=isLeapYear(i)?366:365;
  132. w=(w+d)%7;
  133. }
  134. d=0;
  135. for(i=1;i<DateTime[4];i++)
  136. d+=MonthsDays[i];
  137. d+=DateTime[3];
  138. DateTime[5]=(w+d)%7+1;
  139. }


  140. //定时器0每秒刷新LCD显示
  141. void T0_INT() interrupt 1
  142. { uchar i;
  143. if(++tCount!=2) return;
  144. tCount=0;//刷新

  145. Format_DateTime(DateTime[6],LCD_DSY_BUFFER1);//年
  146. Format_DateTime(DateTime[4],LCD_DSY_BUFFER1+3);//月
  147. Format_DateTime(DateTime[3],LCD_DSY_BUFFER1+6);//日

  148. Format_DateTime(DateTime[2],LCD_DSY_BUFFER2);//时
  149. Format_DateTime(DateTime[1],LCD_DSY_BUFFER2+3);//分
  150. Format_DateTime(DateTime[0],LCD_DSY_BUFFER2+6);//秒

  151. Display_LCD_String(0x03,LCD_DSY_BUFFER1);//显示年月日,星期,时分秒
  152. Set_LCD_POS(0x43);
  153. for(i=0;i<14;i++)
  154. {
  155. Write_LCD_Data(LCD_DSY_BUFFER2[i]);
  156. DelayMS(1);
  157. }
  158. }

  159. //主程序
  160. void main()
  161. {
  162. Init_LCD();//液晶初始化
  163. IE=0X87;//允许INT0,T0中断
  164. TR0=1;
  165. while(1)
  166. {GetTime();
  167.   
  168. }}
复制代码

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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