PCF8653 RTC时钟模块时间异常问题修复

1.问题描述:

时间设置到2020-01-01 00:00:00之前,时间不能跳到2020-01-01 00:00:00;

https://www.nxp.com.cn/docs/zh/data-sheet/PCF8563.pdf

  1 #include "stdio.h"
  2 #include "lib_i2c.h"
  3 //==============================================================================
  4 //
  5 //                              DEFINES
  6 //
  7 //==============================================================================
  8
  9 #define I2C_ADDR        (0xA2>>1)
 10
 11 //==============================================================================
 12 //
 13 //                              EXTERNAL VARIABLES REFERENCE
 14 //
 15 //==============================================================================
 16
 17 //==============================================================================
 18 //
 19 //                              EXTERNAL FUNCTION PROTOTYPES
 20 //
 21 //==============================================================================
 22
 23 //==============================================================================
 24 //
 25 //                              VARIABLES
 26 //
 27 //==============================================================================
 28
 29 //==============================================================================
 30 //
 31 //                              FUNCTIONS
 32 //
 33 //==============================================================================
 34 s32 gm_pcf8563_check()
 35 {
 36     s32 REG0,REG1,REG2;
 37     REG0 = gm_i2c_read(I2C_ADDR,0x02);
 38     REG1 = gm_i2c_read(I2C_ADDR,0x03);
 39     REG2 = gm_i2c_read(I2C_ADDR,0x04);
 40     printf("0:%d,1:%d,2:%d\n",REG0,REG1,REG2);
 41     if((REG0 < 0) || (REG1 < 0) || (REG2 < 0) || (REG0 == 0xFF) || (REG1 == 0xFF) || (REG2 == 0xFF))
 42     {
 43         printf("pcf8563 not exist\n");
 44       return -1;
 45     }
 46     else
 47     {
 48         printf("pcf8563 exist\n");
 49         return 0;
 50     }
 51 }
 52
 53
 54 s32 gm_pcf8563_gettime(u32 *year, u32 *mon, u32 *mday,
 55                        u32 *hour, u32 *min, u32 *sec)
 56 {
 57 #if 1
 58    struct i2c_msg  msgs[2];
 59    unsigned char   tmp[2], tmp2[7];
 60
 61    tmp[0]        = 0x2 & 0xFF;
 62    msgs[0].addr  = I2C_ADDR;
 63    msgs[0].flags = 0;
 64    msgs[0].len   = 1;
 65    msgs[0].buf   = tmp;
 66
 67    tmp2[0]       = 0;
 68    msgs[1].addr  = I2C_ADDR;
 69    msgs[1].flags = 1;
 70    msgs[1].len   = 7;
 71    msgs[1].buf   = tmp2;
 72
 73    if (gm_i2c_transfer(msgs, 2) != 2){
 74        printf("PCF8563 Get Fail\n");
 75         return FAIL;
 76    }
 77 #if 0
 78 {
 79    int i;
 80    printf("\n\n");
 81    for(i=0; i<7; i++){
 82        printf("%d, ", tmp2[i]);
 83    }
 84    printf("\n\n");
 85 }
 86 #endif
 87    *sec = (u32)(((tmp2[0]>>4)&0x7)*10 + (tmp2[0]&0x0F));
 88    *min = (u32)(((tmp2[1]>>4)&0x7)*10 + (tmp2[1]&0x0F));
 89    *hour = (u32)(((tmp2[2]>>4)&0x3)*10 + (tmp2[2]&0x0F));
 90    *mday = (u32)(((tmp2[3]>>4)&0x3)*10 + (tmp2[3]&0x0F));
 91    *mon = (u32)(((tmp2[5]>>4)&0x1)*10 + (tmp2[5]&0x0F) + ((tmp2[5]&BIT7)? 1 : 0));
 92    *year = (u32)(((tmp2[6]>>4)&0xF)*10 + (tmp2[6]&0x0F)) + 2000;
 93     printf("hi,gm_pcf8563_gettime:%04d/%02d/%02d, %02d:%02d:%02d\n", *year, *mon, *mday, *hour, *min, *sec);
 94     return SUCCESS;
 95
 96 #else
 97     s32 value;
 98
 99     //lib_I2C_SetAddressMode(I2C_ADDR_MODE_8BIT);
100
101     if ((value = gm_i2c_read(I2C_ADDR, 0x02)) < 0)
102     {
103         goto pcf8563_get_fail;
104     }
105     else
106     {
107         *sec = (int)(((value>>4)&0x7)*10 + (value&0x0F));
108     }
109
110     if ((value = gm_i2c_read(I2C_ADDR, 0x03)) < 0)
111     {
112         goto pcf8563_get_fail;
113     }
114     else
115     {
116         *min = (int)(((value>>4)&0x7)*10 + (value&0x0F));
117     }
118
119     if ((value = gm_i2c_read(I2C_ADDR, 0x04)) < 0)
120     {
121         goto pcf8563_get_fail;
122     }
123     else
124     {
125         *hour = (int)(((value>>4)&0x3)*10 + (value&0x0F));
126     }
127
128     if ((value = gm_i2c_read(I2C_ADDR, 0x05)) < 0)
129     {
130         goto pcf8563_get_fail;
131     }
132     else
133     {
134         *mday = (int)(((value>>4)&0x3)*10 + (value&0x0F));
135     }
136
137     if ((value = gm_i2c_read(I2C_ADDR, 0x07)) < 0)
138     {
139         goto pcf8563_get_fail;
140     }
141     else
142     {
143         *mon = (int)(((value>>4)&0x1)*10 + (value&0x0F) + ((value&BIT7)? 1 : 0));
144     }
145
146     if ((value = gm_i2c_read(I2C_ADDR, 0x08)) < 0)
147     {
148         goto pcf8563_get_fail;
149     }
150     else
151     {
152         *year = (int)(((value>>4)&0xF)*10 + (value&0x0F)) + 1900;  /* years since 1900 */
153     }
154
155     printf("gm_pcf8563_gettime: %d-%d-%d %d:%d:%d\n", *year, *mon, *mday, *hour, *min, *sec);
156
157     return SUCCESS;
158
159 pcf8563_get_fail:
160     printf("PCF8563 Get Fail\n");
161     return FAIL;
162     #endif
163 }
164
165 s32 gm_pcf8563_settime(u32 year, u32 mon, u32 mday,
166                        u32 hour, u32 min, u32 sec)
167 {
168     if (year < 2000 || year > 2100 || mon > 12 || mday > 31 ||    //steven 20130410
169         hour > 23 || min > 59 || sec > 59)
170     {
171         return FAIL;
172     }
173     else
174     {
175         //lib_I2C_SetAddressMode(I2C_ADDR_MODE_8BIT);
176
177         if (gm_i2c_write(I2C_ADDR, 0x02, (((sec/10)&0x7)<<4)|((sec%10)&0xF)) < 0)
178         {
179             goto pcf8563_set_fail;
180         }
181
182         if (gm_i2c_write(I2C_ADDR, 0x03, (((min/10)&0x7)<<4)|((min%10)&0xF)) < 0)
183         {
184             goto pcf8563_set_fail;
185         }
186
187         if (gm_i2c_write(I2C_ADDR, 0x04, (((hour/10)&0x3)<<4)|((hour%10)&0xF)) < 0)
188         {
189             goto pcf8563_set_fail;
190         }
191
192         if (gm_i2c_write(I2C_ADDR, 0x05, (((mday/10)&0x3)<<4)|((mday%10)&0xF)) < 0)
193         {
194             goto pcf8563_set_fail;
195         }
196
197         if (gm_i2c_write(I2C_ADDR, 0x07, (((mon/10)&0x1)<<4)|((mon%10)&0xF)) < 0)
198         {
199             goto pcf8563_set_fail;
200         }
201
202         if (gm_i2c_write(I2C_ADDR, 0x08, ((((year-2000)/10)&0xF)<<4)|(((year-2000)%10)&0xF)) < 0)
203         {
204             goto pcf8563_set_fail;
205         }
206     }
207      printf("\n\n\ngm_pcf8563_settime22:%04d/%02d/%02d, %02d:%02d:%02d\n\n\n\n", year, mon, mday, hour, min, sec);
208     return SUCCESS;
209
210 pcf8563_set_fail:
211     printf("PCF8563 Set Fail\n");
212     return FAIL;
213 }

原文地址:https://www.cnblogs.com/feige1314/p/12422395.html

时间: 2024-10-10 00:56:05

PCF8653 RTC时钟模块时间异常问题修复的相关文章

张高兴的 Windows 10 IoT 开发笔记:RTC 时钟模块 DS3231

原文:张高兴的 Windows 10 IoT 开发笔记:RTC 时钟模块 DS3231 GitHub:https://github.com/ZhangGaoxing/windows-iot-demo/tree/master/DS3231 注意:不包含闹钟设置

树莓派配置RTC时钟(DS3231,I2C接口)

1.购买基于DS3231的RTC时钟模块,并且支持3.3V的那种 2.配置树莓派 a.打开树莓派的i2c接口 sudo raspi-config -->Interfacing Options -->I2C,全部选择yes b.添加i2c模块     sudo nano /etc/modules     然后添加以下两行内容:         i2c-bcm2708         i2c-dev c.安装i2c工具,查看i2c设备b sudo apt-get install i2c-tools

Linux应用层系统时间写入RTC时钟的方法

Linux内核版本:linux-3.0.35 开发板:i.MX6S MY-IMX6-EK200 系统:Ubuntu12 前言:之前写过一篇关于如何通过应用层程序读取系统时间的blog,今天再写一篇如何写入并保存RTC时钟的blog吧. 一.写入时间 1.预备知识: a.mktime 头文件:#include <time.h> 函数:time_t mktime(struct tm *timeptr) 函数说明:mktime()用来将timeptr所指的tm结构体数据换成从公元1970年1月1日0

玩转 RTC时钟库 DS1302

1.前言 ????最近博主在弄8266编程的时候,偶然发现两个全新时钟模块压仓货: DS1302 DS3231 ????为了避免资源浪费以及重复编写代码,博主还是抱着尝试的心态去寻找能够同时兼容 DS1302.DS3231甚至其他的时钟模块的第三方库.终于,还是被我找到了 -- Rtc 时钟库. 2.RTC 2.1 简介 Arduino Real Time Clock library(Arduino平台的实时时钟库) 支持DS1302.DS1307.DS3231.DS3234 英文文档参考 wi

玩转 RTC时钟库 DS3231

1.前言 ????接着博主的上一篇 玩转 RTC时钟库 + DS1302,这一篇我们重点讲解DS3231时钟模块.没有看过上一篇的同学,麻烦先去阅读一下,因为很多理论基础已经在上一篇做了详细讲解,这里不再重复. DS3231 2.DS3231介绍 2.1 为什么使用DS3231 ????常用的DS1302需要使用外置晶振,且没有温度补偿,误差较大.这就促使了更高精度的时钟芯片 -- DS3231. ????DS3231内置晶振且有内部温度补偿,误差可做到1分钟每年.说白了,精度更高. 2.2 D

DS3231高精度时钟模块,IIC,C51 8051单片机I2C 测试程序 【开源】

实物图 原理图 效果图 程序烧录: /*****************************************************************************  *文件名称:main.c *版    本:Keil uVision4 *控 制 器:STC89C52RC/12M 功能:显示时间到串口 *说    明: 1,DS3231实时时钟模块测试程序  2,1T的单片机用不了 3,晶振12M 4,串口波特率2400 编译结果: Rebuild target 'D

(转)FPGA异步时序和多时钟模块

http://bbs.ednchina.com/BLOG_ARTICLE_3019907.HTM   第六章   时钟域 有一个有趣的现象,众多数字设计特别是与FPGA设计相关的教科书都特别强调整个设计最好采用唯一的时钟域.换句话说,只有一个独立的网络可以驱动一个设计中所有触发器的时钟端口.虽然这样可以简化时序分析以及减少很多与多时钟域有关的问题,但是由于FPG**外各种系统限制,只使用一个时钟常常又不现实.FPGA时常需要在两个不同时钟频率系统之间交换数据,在系统之间通过多I/O接口接收和发送

点阵大屏语音感应时计&mdash;&mdash;DS3231高精度时钟模块

DS3231高精度时钟模块倒是又便宜又好用,SDA/SCL两个IO口就能搞定基本功能,不过在使用闹铃中断输出的时候遇到了问题,那就是闹铃中断只会输出一次,之后始终保持低电平. 这个问题数据手册上没有明说,在网上搜索了很久,一点信息都没有找到,只好自己折腾. 经过反复尝试,最终确认DS3231的闹铃中断输出正确使用方式如下: 首先是初始化,设定闹铃时间和允许中断输出 void DS3231_Init_Alarm2()    {        I2C_Start();         I2C_Put

GEC2440的RTC时钟

引用:http://www.cnblogs.com/Neddy/archive/2011/12/07/2278761.html 2440的RTC时钟 移植linux到2440上发现没有时钟信息,解决方法如下: 1.在linux kernel里面用make menuconfig打开配置画面,进Device Drivers选项 找到Real Time Clock画面,按下space键选择为“*”,再进入这个选项 选中Samsung S3C series SoC RTC 在Exit退出后保存 2.修改