找回密码
 立即注册

QQ登录

只需一步,快速开始

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

ds1302驱动程序+lcd12864串行显示,使用结构体写,可读性更强

  [复制链接]
跳转到指定楼层
楼主
ID:170498 发表于 2019-5-13 19:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
ds1302.c
  1. #include "ds1302.h"


  2. // 定义RTC初始化结构体,决定了初始化时间
  3. RTC_TIME rtc_time = {
  4.     25,     // 秒
  5.     35,     // 分
  6.     02,     // 时
  7.     25,     // 日
  8.     4,      // 月
  9.     4,      // 星期
  10.     19      // 年
  11. };

  12. /*******************************************************************************
  13. * 函 数 名         : bcd_to_hex
  14. * 函数功能           : 从时钟芯片中读出的时间数据,需转换为十进制数。
  15. * 输    入         : val:需要转换的值
  16. * 输    出         : 无
  17. *******************************************************************************/
  18. static uint8_t bcd_to_hex(uint8_t val)
  19. {
  20.    uint8_t temp;
  21.    
  22.     temp = val & 0x0f;
  23.     val >>= 4;
  24.     val &= 0x0f;
  25.     val *= 10;
  26.     temp += val;
  27.    
  28.     return temp;
  29. }


  30. /*******************************************************************************
  31. * 函 数 名         : hex_to_bcd
  32. * 函数功能           : 往时钟芯片写入数据时,需将待写的十进制数转换为8421码。
  33. * 输    入         : val:需要转换的值
  34. * 输    出         : 无
  35. *******************************************************************************/
  36. static uint8_t hex_to_bcd(uint8_t val)
  37. {
  38.     uint8_t i,j,k;
  39.    
  40.     i = val / 10;
  41.     j = val % 10;
  42.      k= j + (i << 4);
  43.    
  44.     return k;
  45. }


  46. /*******************************************************************************
  47. * 函 数 名         : DS1302_Write
  48. * 函数功能           : 向DS1302命令(地址+数据)
  49. * 输    入         : addr,dat
  50. * 输    出         : 无
  51. *******************************************************************************/

  52. static void DS1302_Write(uint8_t addr, uint8_t dat)
  53. {
  54.     uint8_t n;
  55.    
  56.     RST = 0;
  57.     _nop_();

  58.     SCLK = 0;//先将SCLK置低电平。
  59.     _nop_();
  60.     RST = 1; //然后将RST(CE)置高电平。
  61.     _nop_();

  62.     for (n=0; n<8; n++)//开始传送八位地址命令
  63.     {
  64.         DSIO = addr & 0x01;//数据从低位开始传送
  65.         addr >>= 1;
  66.         SCLK = 1;//数据在上升沿时,DS1302读取数据
  67.         _nop_();
  68.         SCLK = 0;
  69.         _nop_();
  70.     }
  71.    
  72.     for (n=0; n<8; n++)//写入8位数据
  73.     {
  74.         DSIO = dat & 0x01;
  75.         dat >>= 1;
  76.         SCLK = 1;//数据在上升沿时,DS1302读取数据
  77.         _nop_();
  78.         SCLK = 0;
  79.         _nop_();   
  80.     }   
  81.          
  82.     RST = 0;//传送数据结束
  83.     _nop_();
  84. }

  85. /*******************************************************************************
  86. * 函 数 名         : DS1302_Read
  87. * 函数功能           : 读取一个地址的数据
  88. * 输    入         : addr
  89. * 输    出         : dat
  90. *******************************************************************************/

  91. static uint8_t DS1302_Read(uint8_t addr)
  92. {
  93.     uint8_t n;
  94.     uint8_t dat;
  95.     uint8_t dat1;
  96.    
  97.     RST = 0;
  98.     _nop_();

  99.     /* 先将SCLK置低电平 */
  100.     SCLK = 0;
  101.     _nop_();
  102.    
  103.     /* 然后将RST(CE)置高电平 */
  104.     RST = 1;
  105.     _nop_();

  106.     /* 开始传送八位地址命令 */
  107.     for(n=0; n<8; n++)
  108.     {
  109.         DSIO = addr & 0x01; /* 数据从低位开始传送 */
  110.         addr >>= 1;
  111.         SCLK = 1;   /* 数据在上升沿时,DS1302读取数据 */
  112.         _nop_();
  113.         SCLK = 0;   /* DS1302下降沿时,放置数据 */
  114.         _nop_();
  115.     }
  116.     _nop_();
  117.    
  118.     /* 读取8位数据 */
  119.     for(n=0; n<8; n++)
  120.     {
  121.         dat1 = DSIO; /* 从最低位开始接收 */
  122.         dat = (dat>>1) | (dat1<<7);
  123.         SCLK = 1;
  124.         _nop_();
  125.         SCLK = 0;   /* DS1302下降沿时,放置数据 */
  126.         _nop_();
  127.     }
  128.    
  129.     /* 以下为DS1302复位的稳定时间,必须的 */
  130.     RST = 0;
  131.     _nop_();   
  132.     SCLK = 1;
  133.     _nop_();   
  134.     DSIO = 0;
  135.     _nop_();   
  136.     DSIO = 1;
  137.     _nop_();
  138.    
  139.     return dat;   
  140. }

  141. /*******************************************************************************
  142. * 函 数 名         : DS1302_ReadTime
  143. * 函数功能           : 读取时钟信息
  144. * 输    入         : RTC_TIME类型的结构体指针,RTC_TIME的成员有:
  145.                         rtc_sec    秒
  146.                         rtc_min    分钟
  147.                         rtc_hour   小时
  148.                         rtc_date   日
  149.                         rtc_month  月
  150.                         rtc_day    星期
  151.                         rtc_year   年
  152. * 输    出         : 无
  153. *******************************************************************************/
  154. void DS1302_ReadTime(RTC_TIME *rtc_time)
  155. {
  156.     unsigned temp;
  157.    
  158.     temp = DS1302_Read(SEC_ADDR | 0x01);
  159.     rtc_time->rtc_sec = bcd_to_hex(temp);
  160.    
  161.     temp = DS1302_Read(MIN_ADDR | 0x01);
  162.     rtc_time->rtc_min = bcd_to_hex(temp);
  163.    
  164.     temp = DS1302_Read(HR_ADDR | 0x01);
  165.     rtc_time->rtc_hour = bcd_to_hex(temp);
  166.    
  167.     temp = DS1302_Read(DATE_ADDR | 0x01);
  168.     rtc_time->rtc_date = bcd_to_hex(temp);
  169.    
  170.     temp = DS1302_Read(MON_ADDR | 0x01);
  171.     rtc_time->rtc_month = bcd_to_hex(temp);
  172.    
  173.     temp = DS1302_Read(DAY_ADDR | 0x01);
  174.     rtc_time->rtc_day = bcd_to_hex(temp);
  175.    
  176.     temp = DS1302_Read(YEAR_ADDR | 0x01);
  177.     rtc_time->rtc_year = bcd_to_hex(temp);
  178. }
  179. /*******************************************************************************
  180. * 函 数 名         : DS1302_SetTime
  181. * 函数功能           : 向DS1302写入时间
  182. * 输    入         : RTC_TIME类型的结构体指针,RTC_TIME的成员有:
  183.                         rtc_sec    秒
  184.                         rtc_min    分钟
  185.                         rtc_hour   小时
  186.                         rtc_date   日
  187.                         rtc_month  月
  188.                         rtc_day    星期
  189.                         rtc_year   年
  190. * 输    出         : 无
  191. *******************************************************************************/
  192. void DS1302_SetTime(RTC_TIME *rtc_time)
  193. {
  194.     uint8_t temp;
  195.    
  196.     DS1302_Write(0x8E,0X00);         //禁止写保护,就是关闭写保护功能
  197.    
  198.     temp = hex_to_bcd(rtc_time->rtc_sec);
  199.     DS1302_Write(SEC_ADDR, temp);
  200.    
  201.     temp = hex_to_bcd(rtc_time->rtc_min);
  202.     DS1302_Write(MIN_ADDR, temp);
  203.    
  204.     temp = hex_to_bcd(rtc_time->rtc_hour);
  205.     DS1302_Write(HR_ADDR, temp);
  206.    
  207.     temp = hex_to_bcd(rtc_time->rtc_date);
  208.     DS1302_Write(DATE_ADDR, temp);
  209.    
  210.     temp = hex_to_bcd(rtc_time->rtc_month);
  211.     DS1302_Write(MON_ADDR, temp);
  212.    
  213.     temp = hex_to_bcd(rtc_time->rtc_day);
  214.     DS1302_Write(DAY_ADDR, temp);
  215.    
  216.     temp = hex_to_bcd(rtc_time->rtc_year);
  217.     DS1302_Write(YEAR_ADDR, temp);

  218.     DS1302_Write(0x8E,0x80);         //打开写保护功能
  219. }

  220. /*******************************************************************************
  221. * 函 数 名         : DS1302_Init
  222. * 函数功能           : 初始化DS1302,初始化时间时由RTC初始化结构体决定的
  223. * 输    入         : addr
  224. * 输    出         : dat
  225. *******************************************************************************/
  226. void DS1302_Init(void)
  227. {
  228.     DS1302_SetTime(&rtc_time);
  229. }
复制代码
ds1302.h
  1. #ifndef __DS1302_H_
  2. #define __DS1302_H_

  3. #include "config.h"

  4. // DS1302的寄存器地址
  5. #define SEC_ADDR        0x80    // 秒
  6. #define MIN_ADDR        0x82    // 分
  7. #define HR_ADDR         0x84    // 时
  8. #define DATE_ADDR       0x86    // 日
  9. #define MON_ADDR        0x88    // 月
  10. #define DAY_ADDR        0x8a    // 星期
  11. #define YEAR_ADDR       0x8c    // 年


  12. //定义ds1302使用的IO口
  13. sbit DSIO = P1^1;
  14. sbit RST = P1^2;
  15. sbit SCLK = P1^3;

  16. typedef struct rtc_time{
  17.     uint8_t rtc_sec;
  18.     uint8_t rtc_min;
  19.     uint8_t rtc_hour;
  20.     uint8_t rtc_date;
  21.     uint8_t rtc_month;
  22.     uint8_t rtc_day;
  23.     uint8_t rtc_year;
  24. }RTC_TIME;

  25. extern RTC_TIME rtc_time;  // 声明RTC初始化结构体,以便外部文件使用


  26. void DS1302_SetTime(RTC_TIME *rtc_time);    // 设置时间
  27. void DS1302_ReadTime(RTC_TIME *rtc_time);   // 读取时间
  28. void DS1302_Init(void); // 初始化DS1302



  29. #endif
复制代码
lcd12864.c


  1. #include "lcd12864.h"

  2. //sbit LCD_CS = P2^5;            //片选信号 (cs可以直接接高电平)
  3. sbit LCD_SID = P3^5;                //数据信号
  4. sbit LCD_SCLK = P3^6;                //时钟信号
  5. //sbit LCD_RST = P2^2;                //复位信号 (可以不接)

  6. /********************************************************************
  7. * 名称 : LCD12864_Delay()
  8. * 功能 : 延时,延时时间为 100us * t。这是通过软件延时,有一定误差。
  9. * 输入 : t
  10. * 输出 : 无
  11. ***********************************************************************/
  12. static void LCD12864_Delay(unsigned int t)
  13. {
  14.             unsigned int i,j;
  15.             for (i=0; i<t;  i++)
  16.         for (j=0; j<10; j++);
  17. }

  18. /********************************************************************
  19. * 名称 : LCD12864_SendByte
  20. * 功能 : 按照液晶的串口通信协议,发送数据
  21. * 输入 : zdata
  22. * 输出 : 无
  23. ***********************************************************************/
  24. static void LCD12864_SendByte(unsigned char zdata)
  25. {
  26.             unsigned int i;
  27.             for(i=0; i<8; i++)
  28.            {
  29.                         if((zdata << i) & 0x80)
  30.                        {
  31.                                     LCD_SID = 1;
  32.                         }
  33.                       else
  34.                       {
  35.                                         LCD_SID = 0;
  36.         }
  37.                            LCD_SCLK = 0;
  38.                           LCD_SCLK = 1;
  39.             }
  40. }

  41. /********************************************************************
  42. * 名称 : LCD12864_Write_Com
  43. * 功能 : 写串口指令
  44. * 输入 : cmdcode:指令
  45. * 输出 : 无
  46. ***********************************************************************/
  47. void LCD12864_Write_Com(unsigned char cmdcode)
  48. {
  49.         //        LCD_CS = 1;
  50.                 LCD12864_SendByte(0xf8);
  51.                 LCD12864_SendByte(cmdcode & 0xf0);
  52.                 LCD12864_SendByte((cmdcode << 4) & 0xf0);
  53.                 LCD12864_Delay(2);
  54. }

  55. /********************************************************************
  56. * 名称 : LCD12864_Write_Data
  57. * 功能 : 写串口指令
  58. * 输入 : cmdcode:数据
  59. * 输出 : 无
  60. ***********************************************************************/
  61. void LCD12864_Write_Data(unsigned char Dispdata)
  62. {
  63.         //        LCD_CS = 1;
  64.                 LCD12864_SendByte(0xfa);
  65.                 LCD12864_SendByte(Dispdata & 0xf0);
  66.                 LCD12864_SendByte((Dispdata << 4) & 0xf0);
  67.                 LCD12864_Delay(2);
  68. }



  69. /********************************************************************
  70. * 名称 : LCD12864_SetLocation
  71. * 功能 : 设置显示位置
  72. * 输入 : pos_x: (0~15)
  73.          pos_y: (0~3)
  74. * 输出 : 无
  75. ***********************************************************************/
  76. static void LCD12864_SetLocation(uint8_t pos_x, uint8_t pos_y)
  77. {
  78.             if (pos_y == 0x00)
  79.     {
  80.                 pos_x += 0x80;
  81.     }
  82.     else if (pos_y == 0x01)
  83.     {
  84.                 pos_x += 0x90;
  85.     }
  86.     else if (pos_y == 0x02)
  87.     {
  88.                 pos_x += 0x88;
  89.     }
  90.     else
  91.     {
  92.                 pos_x += 0x98;
  93.     }
  94.    
  95.         LCD12864_Write_Com(pos_x);
  96. }

  97. /********************************************************************
  98. * 名称 : LCD12864_ShowStr
  99. * 功能 : LCD12864显示字符串
  100. * 输入 : pos_x: (0~15)
  101.          pos_y: (0~3)
  102.          str:字符串
  103. * 输出 : 无
  104. ***********************************************************************/
  105. void LCD12864_ShowStr(uint8_t pos_x, uint8_t pos_y, char *str)
  106. {
  107.     LCD12864_SetLocation(pos_x, pos_y); // 设置显示位置
  108.    
  109.     while (*str != '\0')
  110.     {
  111.         LCD12864_Write_Data(*str++);
  112.     }
  113. }

  114. /********************************************************************
  115. * 名称 : LCD12864_Init
  116. * 功能 : 初始化函数
  117. * 输入 : cmdcode
  118. * 输出 : 无
  119. ***********************************************************************/
  120. void LCD12864_Init(void)
  121. {  
  122. //        LCD_RST = 0;
  123.         LCD12864_Delay(100);
  124. //        LCD_RST = 1;
  125.         LCD12864_Delay(20000);
  126.         LCD12864_Write_Com(0x30);
  127.         LCD12864_Delay(50);
  128.         LCD12864_Write_Com(0x0c);
  129.         LCD12864_Delay(50);
  130.     LCD12864_Write_Com(0x01); // 清屏指令
  131.         LCD12864_Delay(50);
  132.     LCD12864_Write_Com(0x02);
  133.         LCD12864_Delay(50);
  134.     LCD12864_Write_Com(0x80);
  135.         LCD12864_Delay(50);
  136. }

复制代码
lcd12864.h
  1. #ifndef _12864_H_
  2. #define _12864_H_
  3. #include <STC12C5A60S2.H>
  4. #include "config.h"



  5. void LCD12864_Write_Com(unsigned char cmdcode);
  6. void LCD12864_Write_Data(unsigned char Dispdata);
  7. void LCD12864_ShowStr(uint8_t pos_x, uint8_t pos_y, char *str);
  8. void LCD12864_Init(void);

  9. //void LCD12864_Clear(void);

  10. #endif /* MSP430_C_X_12864_H_ */
复制代码
config.h
  1. #ifndef __CONFIG_H
  2. #define __CONFIG_H

  3. #include <STC12C5A60S2.H>
  4. #include <intrins.h>
  5. #include <string.h>        

  6. typedef unsigned       char  uint8_t;
  7. typedef unsigned short int   uint16_t;
  8. typedef unsigned       int   uint32_t;

  9. #define KEY_SET  KEY5


  10. #endif
复制代码

main.c

  1. <div>#include <STC12C5A60S2.H>
  2. #include "lcd12864.h"
  3. #include "ds1302.h"

  4. void main(void)
  5. {
  6.     LCD12864_Init();    // 初始化LCD12864
  7.     DS1302_Init();      // 初始化DS1302时钟芯片
  8.    
  9.     while (1)
  10.     {
  11.         DS1302_ReadTime(&rtc_time);     // 读取时间
  12.         
  13.         LCD12864_ShowStr(0, 1, "日期:");
  14.         LCD12864_Write_Data('0' + rtc_time.rtc_year / 10);
  15.         LCD12864_Write_Data('0' + rtc_time.rtc_year % 10);
  16.         LCD12864_Write_Data('-');
  17.         LCD12864_Write_Data('0' + rtc_time.rtc_month / 10);
  18.         LCD12864_Write_Data('0' + rtc_time.rtc_month % 10);
  19.         LCD12864_Write_Data('-');
  20.         LCD12864_Write_Data('0' + rtc_time.rtc_date / 10);
  21.         LCD12864_Write_Data('0' + rtc_time.rtc_date % 10);
  22.         
  23.         LCD12864_ShowStr(0, 2, "时间:");
  24.         LCD12864_Write_Data('0' + rtc_time.rtc_hour / 10);
  25.         LCD12864_Write_Data('0' + rtc_time.rtc_hour % 10);
  26.         LCD12864_Write_Data('-');
  27.         LCD12864_Write_Data('0' + rtc_time.rtc_min / 10);
  28.         LCD12864_Write_Data('0' + rtc_time.rtc_min % 10);
  29.         LCD12864_Write_Data('-');
  30.         LCD12864_Write_Data('0' + rtc_time.rtc_sec / 10);
  31.         LCD12864_Write_Data('0' + rtc_time.rtc_sec % 10);
  32.     }
  33. }   

复制代码




评分

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

查看全部评分

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

使用道具 举报

沙发
ID:516871 发表于 2019-5-25 10:24 | 只看该作者
学习了
回复

使用道具 举报

板凳
ID:381853 发表于 2019-5-25 11:04 | 只看该作者
不错,谢谢
回复

使用道具 举报

地板
ID:59151 发表于 2020-1-23 00:33 | 只看该作者
好资料,谢谢分享,正在学习中
回复

使用道具 举报

5#
ID:505400 发表于 2020-2-21 22:12 | 只看该作者
谢谢分享,学习中!
回复

使用道具 举报

6#
ID:243394 发表于 2020-2-22 11:03 | 只看该作者
<div>#include <STC12C5A60S2.H>
是什么意思?
回复

使用道具 举报

7#
ID:170498 发表于 2020-11-23 13:27 | 只看该作者
szzxl10 发表于 2020-2-22 11:03
#include
是什么意思?

复制的时候没注意,<div>应该是没有的。
回复

使用道具 举报

8#
ID:609524 发表于 2021-5-19 10:37 | 只看该作者
楼主能打包一下提供下载吗
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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