找回密码
 立即注册

QQ登录

只需一步,快速开始

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

DS1302液晶显示单片机程序

[复制链接]
跳转到指定楼层
楼主
制作出来的实物图如下:

  1. /*********************************************************************
  2. 模块名称:DS1302
  3. 模块功能: RTC               
  4. 硬件接线:无。
  5. 注意事项:(1) DS1302的SPI接口用到了P3.4、P3.5、P3.6,若程序运行有问题查
  6.                           硬件问题时可以从这三个引脚复用部分查起
  7.                   (2) DS1302的初始化时间是随便给的,之所以给23.59.50,是为了在10
  8.                             秒后即可看到24.59.59到00.00.00的跳变。
  9.                   (3) DS1302寄存器读写的函数编写时要注意时序和LSB这2个要点。                                                                  
  10. **********************************************************************/

  11. /*
  12. **********************************************************************
  13. *                         头文件包含
  14. **********************************************************************
  15. */
  16. #include "ds1302.h"


  17. /*
  18. **********************************************************************
  19. *                         本地全局变量
  20. **********************************************************************
  21. */
  22. // 以下为DS1302相关定义
  23. sbit DSIO = P1^0;                 // DS1302的SPI接口IO线,输入输出都走这里
  24. sbit CE   = P1^1;                // chip enable,读写ds1302前要使能,读写完要禁止
  25. sbit SCLK = P1^2;                   // serial clock,串行时钟线


  26. extern u8 gTime[7];                // 定义在mian.c中,用来存储DS1302中7个时间的BCD码值
  27. extern u8 gDigValue[8];                // 定义在main.c中,用LCD2864上显示的8个数值
  28. extern u8 YTD[];
  29. extern u8 week[];

  30. // DS1302内部时间寄存器地址常量定义,这些地址值可查DS1302数据手册获取
  31. u8 code DS1302_READ_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};                 //读地址
  32. u8 code DS1302_WRITE_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};                //写地址


  33. /*
  34. **********************************************************************
  35. *                         内部函数原型声明
  36. **********************************************************************
  37. */
  38. static void Ds1302WriteReg(u8 addr, u8 dat);
  39. static u8 Ds1302ReadReg(u8 addr);
  40. static void Ds1302WriteTime(void);



  41. /*********************************************************************
  42. * 函 数 名       : Ds1302WriteReg
  43. * 函数功能                 : 向DS1302中地址为addr的寄存器写入数值dat
  44. * 参数列表       : addr - 待写入数值的寄存器地址
  45.                                    dat  - 待写入addr寄存器的数值
  46. * 函数输出             : 无
  47. *********************************************************************/
  48. static void Ds1302WriteReg(u8 addr, u8 dat)
  49. {
  50.         u8 i = 0;

  51.         CE = 0;
  52.         _nop_();                                // 空指令,延时

  53.         SCLK = 0;                                // 先将SCLK置低电平
  54.         _nop_();

  55.         CE = 1;                                 // CE拉高以使能对DS1302的读写权限
  56.         _nop_();

  57.         for (i=0; i<8; i++)                // 循环逐位发送addr的8个bit,注意低位在前
  58.         {
  59.                 DSIO = addr & 0x01;        // 数据从LSB低位开始传送
  60.                 addr >>= 1;                        // 发完后addr右移一位原来的次低位变成新的低位
  61.                 SCLK = 1;                        // 拉高SCLK制造一个上升沿,通知DS1302读取数据
  62.                 _nop_();                        // 延时等待DS1302读取DSIO线上的1位数据

  63.                 SCLK = 0;                        // 读完后,拉低SCLK为下一个位的传输做准备
  64.                 _nop_();
  65.         }
  66.                                                         // 循环结束后1字节的寄存器地址传给DS1302
  67.         for (i=0; i<8; i++)                // 循环写入8位数据,注意低位在前
  68.         {
  69.                 DSIO = dat & 0x01;
  70.                 dat >>= 1;
  71.                 SCLK = 1;                        //制造上升沿通知DS1302读取数据
  72.                 _nop_();
  73.                 SCLK = 0;
  74.                 _nop_();        
  75.         }                                                   // 循环结束后1字节值成功传给DS1302
  76.                  
  77.         CE = 0;                                        // 写入完毕拉低CE以禁止对DS1302的读写,防止意外改写事故
  78.         _nop_();
  79. }


  80. /*********************************************************************
  81. * 函 数 名       : Ds1302ReadReg
  82. * 函数功能                 : 向DS1302中地址为addr的寄存器写入数值dat
  83. * 参数列表       : addr - 待读出的寄存器的地址
  84. * 函数输出             : 读出的寄存器addr的数值
  85. *********************************************************************/
  86. static u8 Ds1302ReadReg(u8 addr)
  87. {
  88.         u8 i = 0, dat = 0, dat1 = 0;

  89.         CE = 0;                                                          // CE设置为初始状态
  90.         _nop_();

  91.         SCLK = 0;                                                // SCLK设置为初始状态
  92.         _nop_();

  93.         CE = 1;                                                        // 拉高CE使能对DS1302的寄存器读写权限
  94.         _nop_();

  95.         for (i=0; i<8; i++)                                // 循环发送8bit寄存器地址值
  96.         {
  97.                 DSIO = addr & 0x01;                        // DS1302的SPI接口从LSB开始发送
  98.                 addr >>= 1;

  99.                 SCLK = 1;                                        // 制造上升沿,DS1302在上升沿完成读取动作
  100.                 _nop_();

  101.                 SCLK = 0;                                        // 拉低SCLK为下个bit发送做准备
  102.                 _nop_();
  103.         }
  104.         
  105.         for (i=0; i<8; i++)                                // 循环读取8bit寄存器值数据
  106.         {
  107.                 dat1 = DSIO;//从最低位开始接收
  108.                 dat = (dat>>1) | (dat1<<7);
  109.                 SCLK = 1;
  110.                 _nop_();
  111.                 SCLK = 0;//DS1302下降沿时,放置数据
  112.                 _nop_();
  113.         }

  114.         CE = 0;
  115.         _nop_();        //以下为DS1302复位的稳定时间,必须的。

  116.         SCLK = 1;
  117.         _nop_();

  118.         DSIO = 0;
  119.         _nop_();

  120.         DSIO = 1;
  121.         _nop_();

  122.         return dat;        
  123. }


  124. /*********************************************************************
  125. * 函 数 名       : Ds1302WriteTime
  126. * 函数功能                 : 将全局变量gTime中的时间写入DS1302中以重置DS1302时间
  127. * 参数列表       : 无
  128. * 函数输出             : 无
  129. *********************************************************************/
  130. static void Ds1302WriteTime(void)
  131. {
  132.         u8 i = 0;

  133.         Ds1302WriteReg(0x8E,0x00);                 // 禁用WP以获取写时间寄存器的权限
  134.         for (i=0; i<7; i++)                         // 依次写入7个时间,顺序依次:秒分时日月周年
  135.         {
  136.                 Ds1302WriteReg(DS1302_WRITE_ADDR[i],gTime[i]);        
  137.         }
  138.         Ds1302WriteReg(0x8E,0x80);                 // 使能WP以禁止对时间寄存器的读写,防止意外改写事故
  139. }


  140. /*********************************************************************
  141. * 函 数 名       : Ds1302InitTime
  142. * 函数功能                 : 以给定的初始时间来重置DS1302时间值
  143. * 参数列表       : 无
  144. * 函数输出             : 无
  145. *********************************************************************/
  146. void Ds1302InitTime(void)
  147. {
  148.         // 先给个初始化时间
  149.         gTime[0] = 0x50;        // 初始化时间,秒,注意是BCD码不是10进制也不是16进制
  150.         gTime[1] = 0x59;        // 初始化时间,分,注意是BCD码不是10进制也不是16进制
  151.         gTime[2] = 0x23;        // 初始化时间,时,注意是BCD码不是10进制也不是16进制
  152.         gTime[3] = 0x31;        // 初始化时间,日,注意是BCD码不是10进制也不是16进制
  153.         gTime[4] = 0x12;        // 初始化时间,月,注意是BCD码不是10进制也不是16进制
  154.         gTime[5] = 0x07;        // 初始化时间,周,注意是BCD码不是10进制也不是16进制
  155.         gTime[6] = 0x18;        // 初始化时间,年,注意是BCD码不是10进制也不是16进制,以2000为基数
  156.         // 将给定时间写入DS1302内部时间寄存器以完成初始化
  157.         Ds1302WriteTime();
  158. }


  159. /*********************************************************************
  160. * 函 数 名       : Ds1302ReadTime
  161. * 函数功能                 : 读出DS1302内部时间放入全局变量gTime中
  162. * 参数列表       : 无
  163. * 函数输出             : 无
  164. *********************************************************************/
  165. void Ds1302ReadTime(void)
  166. {
  167.         u8 i = 0;

  168.         for (i=0; i<7; i++)//读取7个字节的时钟信号:秒分时日月周年
  169.         {
  170.                 gTime[i] = Ds1302ReadReg(DS1302_READ_ADDR[i]);
  171.         }
  172. }
  173. /*********************************************************************
  174. * 函 数 名       : UpdateDigValue
  175. * 函数功能                 : 显示时间
  176. * 参数列表       : 无
  177. * 函数输出             : 无
  178. *********************************************************************/
  179. void UpdateDigValue(void)
  180. {
  181.         Ds1302ReadTime();                  // 从DS1302读取时间存入gTime中

  182.         gDigValue[0] = ((gTime[2] >> 4) & 0x0f)+48;                // Hour的高4位
  183.         gDigValue[1] = ((gTime[2] >> 0) & 0x0f)+48;                // Hour的低4位
  184.         gDigValue[2] = ':';                                                                // 分隔符
  185.         
  186.         gDigValue[3] = ((gTime[1] >> 4) & 0x0f)+48;                // Minute的高4位
  187.         gDigValue[4] = ((gTime[1] >> 0) & 0x0f)+48;                // Minute的低4位
  188.         gDigValue[5] = ':';                                                                // 分隔符

  189.         gDigValue[6] = ((gTime[0] >> 4) & 0x0f)+48;                // Second的高4位
  190.         gDigValue[7] = ((gTime[0] >> 0) & 0x0f)+48;                // Second的低4位
  191.         
  192. }
  193. /*********************************************************************
  194. * 函 数 名       : DisplayDay
  195. * 函数功能                 : 显示年月日
  196. * 参数列表       : 无
  197. * 函数输出             : 无
  198. *********************************************************************/
  199. void DisplayDay(void)
  200. {
  201.           Ds1302ReadTime();                  // 从DS1302读取时间存入gTime中

  202.         YTD[2] = ((gTime[6] >> 4) & 0x0f)+48;                // Hour的高4位
  203.         YTD[3] = ((gTime[6] >> 0) & 0x0f)+48;                // Hour的低4位
  204.         YTD[6] = ((gTime[4] >> 4) & 0x0f)+48;                // Minute的高4位
  205.         YTD[7] = ((gTime[4] >> 0) & 0x0f)+48;                // Minute的低4位
  206.         YTD[10] = ((gTime[3] >> 4) & 0x0f)+48;                // Second的高4位
  207.         YTD[11] = ((gTime[3] >> 0) & 0x0f)+48;                // Second的低4位
  208. }
复制代码
全部资料51hei下载地址:
代码.zip (53.48 KB, 下载次数: 5)

评分

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

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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