OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 21436|回复: 41

时钟芯片R8025AC跑的不准

[复制链接]

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
发表于 2015-1-17 09:04:50 | 显示全部楼层 |阅读模式
5金钱
听说R8025这块时钟芯片跑的很准就试了下,前1、2天可以说做到分秒不差,今天三天多了,快了30秒。又没用用过的,说说是什么情况?

电路:



程序:

Sys_RTC.c

4.57 KB, 下载次数: 657

R8025AC.c

7.53 KB, 下载次数: 890

Sys_RTC.h

272 Bytes, 下载次数: 580

R8025AC.h

239 Bytes, 下载次数: 1107

最佳答案

查看完整内容[请看2#楼]

从图上看你I2C总线上拉电阻电源不应该接在VBAT+上,应该接在系统电源3.3V上。你那样接会不会加速锂电池放电啊。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

22

主题

110

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
295
金钱
295
注册时间
2012-11-11
在线时间
24 小时
发表于 2015-1-17 09:04:51 | 显示全部楼层
从图上看你I2C总线上拉电阻电源不应该接在VBAT+上,应该接在系统电源3.3V上。你那样接会不会加速锂电池放电啊。
回复

使用道具 举报

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
 楼主| 发表于 2015-1-17 09:04:51 | 显示全部楼层
我是来结贴的:

问题有点奇葩,但是解决方法很简单。

主要问题在电路上,8楼提到过,只是当时没有意料到影响会如此严重。。。汗颜



主要原因在SDA、SCL的上拉电源上,之前是接在电源和电池上了,可能在上下电时影响了信号输入,具体也说不太清楚,如果有个示波器什么的倒是可以分析下,现在就这样吧。
1、改SDA、SCL的上拉电源为系统电源,不接电池
2、两个二极管改成普通的1N4148,原先用的双肖特基二极管反向电流比较大,貌似对电池不太好。
3、时钟电源两边加个10uf的电容,手册上说了电源波动不能太大,这个还是别省了。

最后,完善了一下程序,这样基本上就OK了。嗯,R8025AC是挺准的,5、6天了1秒的误差,这个貌似跟外界温度关系比较大。

[mw_shl_code=c,true]#include <time.h> #include <stdio.h> #include "stm32f2xx.h" #include "FreeRTOS.h" #include "task.h" #include "croutine.h" #include "semphr.h" #include "portmacro.h" #include "R8025AC.h" #include "Sys_RTC.h" static u8 BCD2HEX(u8 bcd_data);//BCD转为HEX static u8 HEX2BCD(u8 hex_data);//HEX转为BCD /******************************************************************************* * 函数名 : STM32_RTC_Init * 描述 : RTC初始化函数 * 参数 : 无 * 返回值 : 无 *******************************************************************************/ u8 R8025_RTC_Init(void) { u8 buf[7]; RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//使能PWR和BKP外设时钟 PWR_BackupAccessCmd(ENABLE); //使能后备寄存器访问 R8025AC_Read(0x0E, buf, 2);//读0x0E、0x0F寄存器的值 printf("0x0E:%.2X;0x0F:%.2X\r\n",buf[0],buf[1]); //检查是不是第一次配置时钟 if (RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x5050)//从指定的后备寄存器中读出数据:读出了与写入的指定数据不相乎 { Reset_Time();//设置时间出厂时间 RTC_WriteBackupRegister(RTC_BKP_DR0, 0X5050);//向指定的后备寄存器中写入用户程序数据 return 1;//返回1,第一次初始化 } return 0;//返回0,已经初始化过 } /******************************************************************************* * 函数名 : Reset_Time * 描述 : 设置出厂时间 * 参数 : 无 * 返回值 : 无 *******************************************************************************/ void Reset_Time(void) { u8 buf[7]; buf[0] = 0x00; R8025AC_Write(0x07, buf, 1);//不使用 buf[0] = 0x23;//0010 0110,bit5:1 24小时制,bit2:1,bit1:1,bit0:0 /INTA输出模式1小时/脉冲 R8025AC_Write(0x0E, buf, 1);//设置24小时制 //写入出厂时间2014-06-01 16:34:56 星期日(0x00) buf[6] = 0x14;//年 buf[5] = 0x06;//月 buf[4] = 0x01;//日 buf[3] = 0x00;//星期 buf[2] = 0x16;//时 buf[1] = 0x34;//分 buf[0] = 0x56;//秒 R8025AC_Write(0, buf, 7);//写入R8025AC } /******************************************************************************* * 函数名 : Read_Sec * 描述 : 传入BCD格式时间,获取秒 * 参数 : *buf,传入字符形式的时间 * 返回值 : 返回秒 *******************************************************************************/ u32 Read_Sec(u8 *buf) { struct tm t; t.tm_year = BCD2HEX(buf[6])+100;//年 t.tm_mon = BCD2HEX(buf[5])-1; //月 t.tm_mday = BCD2HEX(buf[4]); //日 t.tm_hour = BCD2HEX(buf[2]); //时 t.tm_min = BCD2HEX(buf[1]); //分 t.tm_sec = BCD2HEX(buf[0]); //秒 return mktime(&t); } /******************************************************************************* * 函数名 : set_time * 描述 : 设置时间 * 参数 : -format:0x00-12小时制,0x20-24小时制 * - *buf :传入字符形式的时间 * 返回值 : 无 *******************************************************************************/ void set_time(u8 format, u8 *buf) { u8 data[7]; //写入时间 data[6] = HEX2BCD(buf[6]);//年 data[5] = HEX2BCD(buf[5]);//月 data[4] = HEX2BCD(buf[4]);//日 data[3] = HEX2BCD(buf[3]);//星期 data[2] = HEX2BCD(buf[2]);//时 data[1] = HEX2BCD(buf[1]);//分 data[0] = HEX2BCD(buf[0]);//秒 R8025AC_Write(0, data, 7);//写入R8025AC } /******************************************************************************* * 函数名 : read_time * 描述 : 读时间 * 参数 : - *buf * 返回值 : 无 *******************************************************************************/ void read_time(u8 *buf) { R8025AC_Read(0, buf, 7); buf[6] = BCD2HEX(buf[6]);//年 buf[5] = BCD2HEX(buf[5]);//月 buf[4] = BCD2HEX(buf[4]);//日 buf[2] = BCD2HEX(buf[2]);//时 buf[1] = BCD2HEX(buf[1]);//分 buf[0] = BCD2HEX(buf[0]);//秒 } /******************************************************************************* * 函数名 : get_time * 描述 : get_time * 参数 : 无 * 返回值 : 返回秒 *******************************************************************************/ u32 get_time(void) { u8 buf[7]; R8025AC_Read(0, buf, 7);//获取当前时间 return Read_Sec(buf); } /******************************************************************************* * 函数名 : BCD2HEX * 描述 : BCD转为HEX * 参数 : -bcd_data:传入BCD格式的数据 * 返回值 : 十六进制数 *******************************************************************************/ static u8 BCD2HEX(u8 bcd_data) { u8 temp; temp=(bcd_data>>4)*10 + (bcd_data&0x0f); return temp; } /******************************************************************************* * 函数名 : HEX2BCD * 描述 : HEX转为BCD * 参数 : -hex_data:传入十六进制格式的数据 * 返回值 : BCD码 *******************************************************************************/ static u8 HEX2BCD(u8 hex_data) { u8 temp; temp=((hex_data/10)<<4) + (hex_data%10); return temp; } [/mw_shl_code]


回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2015-1-17 23:17:32 | 显示全部楼层
这个晶振都不要的么?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
 楼主| 发表于 2015-1-19 08:12:06 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
内置的,出厂校准。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2015-1-19 23:35:00 | 显示全部楼层
回复【3楼】solo:
---------------------------------
果然牛逼
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
 楼主| 发表于 2015-1-20 08:19:18 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
第三天了,分秒不差,猜测后备电源有问题。电池两端电压不足3V。。。
回复

使用道具 举报

28

主题

1489

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1656
金钱
1656
注册时间
2013-7-24
在线时间
1 小时
发表于 2015-1-20 08:50:56 | 显示全部楼层
相当准的。带定时中断也相当方便。
于20150522停用该账号:http://www.microstar.club
回复

使用道具 举报

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
 楼主| 发表于 2015-1-20 13:02:51 | 显示全部楼层
回复【6楼】styleno1:
---------------------------------
准是很准,为毛掉电再上电就不准了呢?每次上电都会快好多
回复

使用道具 举报

28

主题

1489

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1656
金钱
1656
注册时间
2013-7-24
在线时间
1 小时
发表于 2015-1-20 14:11:36 | 显示全部楼层
我也是纽扣电池供电,它工作电压很宽,3V完全没问题。
于20150522停用该账号:http://www.microstar.club
回复

使用道具 举报

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
 楼主| 发表于 2015-1-20 15:18:33 | 显示全部楼层
回复【9楼】狼烟四起:
---------------------------------
此话有理
回复

使用道具 举报

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
 楼主| 发表于 2015-1-20 15:20:48 | 显示全部楼层
每次重上电,有时正常,有时不正常。不正常现象很明显,秒位出错,如果当前30秒,会变成60多秒,然后一直加到80溢出分钟进位,造成时间快30多秒。
回复

使用道具 举报

22

主题

110

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
295
金钱
295
注册时间
2012-11-11
在线时间
24 小时
发表于 2015-1-20 16:24:44 | 显示全部楼层
回复【11楼】solo:
是不是上电程序问题,上电后要不要重写时钟寄存器。我用的是DS3231很准的,内置晶体激光校正,把STM32F103的RTC给踢了,不过多花了好些RMB。
回复

使用道具 举报

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
 楼主| 发表于 2015-1-20 16:42:13 | 显示全部楼层
回复【12楼】狼烟四起:
---------------------------------
有重写,就是不知道对不对。。。
回复

使用道具 举报

1

主题

6

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2014-11-12
在线时间
0 小时
发表于 2015-1-22 18:24:20 | 显示全部楼层
要看你用的R8025AC 还是R8025T    带T的是带温度补偿,我用这个 基本都是分秒不差的。
回复

使用道具 举报

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
 楼主| 发表于 2015-1-23 08:22:38 | 显示全部楼层
回复【15楼】djf5x5:
---------------------------------
R8025AC,原理图上写错了
回复

使用道具 举报

1

主题

17

帖子

1

精华

初级会员

Rank: 2

积分
198
金钱
198
注册时间
2014-11-12
在线时间
1 小时
发表于 2015-3-13 08:39:42 | 显示全部楼层
回复【16楼】solo:
---------------------------------
建议 用带温补的时钟芯片,也就是R8025T  这样就很准了,一个月也就差一两秒!
回复

使用道具 举报

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
 楼主| 发表于 2015-3-13 12:47:49 | 显示全部楼层
回复【17楼】djf5x5:
--------------------------------
价格更贵了。。。
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2015-12-19 09:20:46 | 显示全部楼层
本帖最后由 jiutianshenjian 于 2015-12-30 09:27 编辑

I2C_SendByte(sadd<<4|0x01);这个 | 0x01 是什么意思呢?
小小蜗牛
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2015-12-30 09:42:40 | 显示全部楼层
本帖最后由 jiutianshenjian 于 2015-12-30 09:46 编辑

大侠,看了你的初始化代码,很困惑:
u8 R8025_RTC_Init(void)
{
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//使能PWR和BKP外设时钟   
        PWR_BackupAccessCmd(ENABLE);                           //使能后备寄存器访问
        
    //检查是不是第一次配置时钟
        if (RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x5050)//从指定的后备寄存器中读出数据:读出了与写入的指定数据不相乎
        {                                 
                Reset_Time();//设置时间出厂时间
                RTC_WriteBackupRegister(RTC_BKP_DR0, 0X5050);//向指定的后备寄存器中写入用户程序数据
                return 1;//返回1,第一次初始化
        }

    return 0;//返回0,已经初始化过
}

初始化这么点吗?
不用使能后备时钟吗?
不用LSE吗?
难道底下这些都不用了?我的怎么跑步起来呢?
                BKP_DeInit(); /* 复位备份区域 */                        
                 RCC_LSEConfig(RCC_LSE_ON); /* 设置外部低速晶振(LSE),使用外设低速晶振 */
               
                 while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) /* 检查指定的 RCC 标志位设置与否,等待低速晶振就绪 */
                 {                        
                         Delay_ms(10);                                       
                 }
               
                RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); /* 设置 RTC 时钟(RTCCLK),选择 LSE 作为 RTC 时钟 */               
                RCC_RTCCLKCmd(ENABLE); /* 使能 RTC 时钟 */
                 
                RTC_WaitForLastTask(); /* 等待最近一次对 RTC 寄存器的写操作完成 */               
                RTC_WaitForSynchro(); /* 等待 RTC 寄存器同步 */
               
                RTC_ITConfig(RTC_IT_SEC, ENABLE); /* 使能 RTC 秒中断 */               
                RTC_WaitForLastTask(); /* 等待最近一次对 RTC 寄存器的写操作完成 */
                 
                RTC_SetPrescaler(RTC_PRE_VAL); /* 设置 RTC 预分频的值 */               
                 RTC_WaitForLastTask(); /* 等待最近一次对 RTC 寄存器的写操作完成 */


小小蜗牛
回复

使用道具 举报

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
 楼主| 发表于 2015-12-30 10:04:38 | 显示全部楼层
jiutianshenjian 发表于 2015-12-30 09:42
大侠,看了你的初始化代码,很困惑:
u8 R8025_RTC_Init(void)
{

R8025是外部时钟芯片,晶振芯片内置,你初始化是话32的RTC干嘛?
回复

使用道具 举报

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
 楼主| 发表于 2015-12-30 10:04:55 | 显示全部楼层
jiutianshenjian 发表于 2015-12-30 09:42
大侠,看了你的初始化代码,很困惑:
u8 R8025_RTC_Init(void)
{

R8025是外部时钟芯片,晶振芯片内置,你初始化是话32的RTC干嘛?
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2015-12-30 10:45:20 | 显示全部楼层
本帖最后由 jiutianshenjian 于 2015-12-30 10:46 编辑

我改了下,你帮我看看
http://www.openedv.com/forum.php ... mp;extra=#pid371712
小小蜗牛
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2015-12-30 10:48:06 | 显示全部楼层
solo 发表于 2015-12-30 10:04
R8025是外部时钟芯片,晶振芯片内置,你初始化是话32的RTC干嘛?

I2C_SendByte(sadd<<4|0x01);这个 | 0x01 是什么意思呢?
小小蜗牛
回复

使用道具 举报

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
 楼主| 发表于 2015-12-30 10:49:06 | 显示全部楼层

软件IIC用的原子的,没细研究
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2015-12-30 10:51:28 | 显示全部楼层
solo 发表于 2015-12-30 10:49
软件IIC用的原子的,没细研究

这是芯片的还是iic的
还有那个寄存器地址哪里看到的要左移4位,开始我一直直接写都不行。左移才对,但没发现哪里有说这个。
小小蜗牛
回复

使用道具 举报

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
100
金钱
100
注册时间
2015-11-4
在线时间
14 小时
发表于 2016-5-19 21:06:40 | 显示全部楼层
jiutianshenjian 发表于 2015-12-30 10:51
这是芯片的还是iic的
还有那个寄存器地址哪里看到的要左移4位,开始我一直直接写都不行。左移才对,但没 ...

好好看手册,读写时序,上面有写@solo @jiutianshenjian
QQ截图20160519210135.png
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
23
金钱
23
注册时间
2014-1-18
在线时间
0 小时
发表于 2016-7-25 09:58:05 | 显示全部楼层
最看不惯这种GND朝天的画法,你当时天线呢?乱七八糟的硬件图纸!
回复

使用道具 举报

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
 楼主| 发表于 2016-7-25 15:39:27 | 显示全部楼层
useisbb 发表于 2016-7-25 09:58
最看不惯这种GND朝天的画法,你当时天线呢?乱七八糟的硬件图纸!

不喜勿喷,免得低了的人品。
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2016-8-13 18:04:30 | 显示全部楼层
本帖最后由 jiutianshenjian 于 2016-8-13 18:06 编辑

R8025AC时序,里面有个数据建立时间最小时间是200us。我怀疑应该是ns。不知道楼主这里怎么处理的。
延时使用几us时正常,加入200us有点问题。C:\Users\Administrator\Desktop
QQ图片20160813180037.png
小小蜗牛
回复

使用道具 举报

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
 楼主| 发表于 2016-8-15 08:14:05 | 显示全部楼层
jiutianshenjian 发表于 2016-8-13 18:04
R8025AC时序,里面有个数据建立时间最小时间是200us。我怀疑应该是ns。不知道楼主这里怎么处理的。
延时使 ...

你可以看看我上面贴的代码
回复

使用道具 举报

0

主题

2

帖子

0

精华

初级会员

Rank: 2

积分
63
金钱
63
注册时间
2014-10-16
在线时间
10 小时
发表于 2016-11-24 13:32:56 | 显示全部楼层
我用PIC18F67K90读时间,为毛读出来都是0xff,
回复

使用道具 举报

32

主题

286

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1366
金钱
1366
注册时间
2014-3-27
在线时间
358 小时
发表于 2017-4-6 16:58:06 | 显示全部楼层
不错,可以参考一下
回复

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
9
金钱
9
注册时间
2017-7-6
在线时间
1 小时
发表于 2017-7-6 18:29:08 | 显示全部楼层
本帖最后由 蒿纪星 于 2017-7-6 18:42 编辑

[mw_shl_code=c,true] u8 BCD2HEX(u8 bcd_data) ;
//3&#245;ê&#188;&#187;ˉIIC
void IIC_Init(void)
{                        
  GPIO_InitTypeDef  GPIO_InitStructure;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB

  //GPIOB6,B7初始化设置
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
        IIC_SCL=1;
        IIC_SDA=1;
}
//产生IIC起始信号
void IIC_Start(void)
{
        SDA_OUT();     //sda线输出
        IIC_SDA=1;                    
        IIC_SCL=1;
        delay_us(4);
         IIC_SDA=0;//START:when CLK is high,DATA change form high to low
        delay_us(4);
        IIC_SCL=0;
}         
//产生IIC停止信号
void IIC_Stop(void)
{
        IIC_SCL=0;
        SDA_OUT();//sda线输出
        
        IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
         delay_us(4);
        IIC_SCL=1;
        
        delay_us(4);
        IIC_SDA=1;                                                                  
}
//等待应答信号
//返回值 1,接收应答失败
//      0, 接受应答成功
u8 IIC_Wait_Ack(void)
{
        u8 ucErrTime=0;
        SDA_IN();      //SDA设置为输入
        IIC_SDA=1;
        delay_us(1);           
        IIC_SCL=1;
        delay_us(1);         
        while(READ_SDA)
        {
                ucErrTime++;
                if(ucErrTime>250)
                {
                        IIC_Stop();
                        return 1;
                }
        }
        IIC_SCL=0;//时钟输出0
        return 0;  
}
//产生ACK应答
void IIC_Ack(void)
{
        IIC_SCL=0;
        SDA_OUT();
        IIC_SDA=0;
        delay_us(2);
        IIC_SCL=1;
        delay_us(2);
        IIC_SCL=0;
}
//不产生ACK应答               
void IIC_NAck(void)
{
        IIC_SCL=0;
        SDA_OUT();
        IIC_SDA=1;
        delay_us(2);
        IIC_SCL=1;
        delay_us(2);
        IIC_SCL=0;
}                                                                              
//IIC发送一个字节
//返回从机有无应答
//1有应答
//0无应答                     
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
        SDA_OUT();            
    IIC_SCL=0;//拉低时钟开始传输数据
    for(t=0;t<8;t++)
    {              
        IIC_SDA=(txd&0x80)>>7;
        txd<<=1;           
                delay_us(2);  
                IIC_SCL=1;
                delay_us(2);
                IIC_SCL=0;        
                delay_us(2);
    }         
}            
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 IIC_Read_Byte(unsigned char ack)
{
        unsigned char i,receive=0;
        SDA_IN();//SDA设置为输入
    for(i=0;i<8;i++ )
        {
        IIC_SCL=0;
        delay_us(2);
                IIC_SCL=1;
        receive<<=1;
        if(READ_SDA)receive++;   
                delay_us(1);
    }                                         
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return receive;
}


#define ADDRTC 0x64   //Rx8025

//RX8025
u8 RX8025_Read(u8 register_address)
{
  u8 ret;
  IIC_Start();
  IIC_Send_Byte(ADDRTC);
        IIC_Wait_Ack();
  IIC_Send_Byte((register_address));
        IIC_Wait_Ack();
  IIC_Start();
  IIC_Send_Byte(ADDRTC+1);
  IIC_Wait_Ack();
  ret=IIC_Read_Byte(1);
        SDA_OUT();         
        IIC_SDA=1;
  IIC_Stop();
  return ret;
}

//RX8025
u8 RX8025_Write(u8 register_address,u8 val)
{
IIC_Start();
IIC_Send_Byte(ADDRTC);
        IIC_Wait_Ack();
IIC_Send_Byte((register_address));
        IIC_Wait_Ack();
IIC_Send_Byte(val);
        IIC_Wait_Ack();
IIC_Stop();
        return 0;
}

//Rx8025
void Rx8025_Init(void)
{
   IIC_Start();
   IIC_Send_Byte(ADDRTC);
   IIC_Send_Byte(0xe0);
   IIC_Send_Byte(0x23);
   IIC_Stop();
}





u8 BCD2HEX(u8 bcd_data)  
{   
    u8 temp;   
    temp=(bcd_data>>4)*10 + (bcd_data&0x0f);
    return temp;
}
[/mw_shl_code]
回复

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
9
金钱
9
注册时间
2017-7-6
在线时间
1 小时
发表于 2017-7-6 18:44:49 | 显示全部楼层
蒿纪星 发表于 2017-7-6 18:29
[mw_shl_code=c,true] u8 BCD2HEX(u8 bcd_data) ;
//3&#245;ê&#188;&#187;ˉIIC
void IIC_Init(void)

我知不知道问题出在哪里,
sec:44
min:3
hour:125
date:3
week:125
month:3
year:125
hour,week,year三个寄存器我没法写。读出来的数一直是125.  秒一直正常。每秒跳动一次,但是满一分钟不往上累加。好头疼啊。下面我贴一下主程序。
回复

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
9
金钱
9
注册时间
2017-7-6
在线时间
1 小时
发表于 2017-7-6 18:45:43 | 显示全部楼层
[mw_shl_code=c,true]int main(void)
{
        u32 t=0;
        u8 sec=0;
        u8 min=0;
        u8 hour=0;
        u8 date=0;
        u8 week=0;
        u8 month=0;
        u8 year=0;
        uart_init(115200);
        delay_init(84);
        IIC_Init();
        Rx8025_Init();
        RX8025_Write(0x00,0x03);
        RX8025_Write(0x01,0x03);
        RX8025_Write(0x02,0x03);
        RX8025_Write(0x03,0x03);
        RX8025_Write(0x04,0x03);
        RX8025_Write(0x05,0x03);
        RX8025_Write(0x06,0x03);
       
  while(1){
    printf("t:%d\r\n",t);
                sec=RX8025_Read(0);
            sec=BCD2HEX(sec) ;
                printf("sec:%d\r\n",sec);
                min=RX8025_Read(0x01);
            min=BCD2HEX(min) ;
                printf("min:%d\r\n",min);
                hour=RX8025_Read(0x02);
            hour=BCD2HEX(hour) ;
                printf("hour:%d\r\n",hour);
                date=RX8025_Read(0x03);
            date=BCD2HEX(date) ;
                printf("date:%d\r\n",date);
                week=RX8025_Read(0x04);
            week=BCD2HEX(week) ;
                printf("week:%d\r\n",week);
                month=RX8025_Read(0x05);
            month=BCD2HEX(month) ;
                printf("month:%d\r\n",month);
                year=RX8025_Read(0x06);
            year=BCD2HEX(year) ;
                printf("year:%d\r\n",year);
                delay_ms(2000);
                t++;
        }
}[/mw_shl_code]
回复

使用道具 举报

2

主题

13

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2017-5-15
在线时间
22 小时
发表于 2017-7-15 19:00:20 | 显示全部楼层
蒿纪星 发表于 2017-7-6 18:45
[mw_shl_code=c,true]int main(void)
{
        u32 t=0;

我感觉你的读取时序不太对,你看看是不是这个问题?
QQ截图20170715185859.png
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
4
金钱
4
注册时间
2017-7-8
在线时间
0 小时
发表于 2017-7-22 16:59:03 | 显示全部楼层
绿洲 发表于 2017-7-15 19:00
我感觉你的读取时序不太对,你看看是不是这个问题?

谢谢。我好好看看
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
4
金钱
4
注册时间
2017-7-8
在线时间
0 小时
发表于 2017-7-22 17:08:19 | 显示全部楼层
绿洲 发表于 2017-7-15 19:00
我感觉你的读取时序不太对,你看看是不是这个问题?

刚刚仔细看了我的读取程序,您觉得有问题应该是觉得我少了第10步,没有发送ACK给8025.您可能对我的IIC_Read_Byte(1);不熟悉,参数为1就是代表读取之后发送一个ACK。好头疼。实在想不明白问题在哪儿。谢谢你的回复啊
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
2
金钱
2
注册时间
2017-8-2
在线时间
0 小时
发表于 2017-8-2 15:16:31 | 显示全部楼层
6 7 脚为什么要并起来?
回复

使用道具 举报

0

主题

7

帖子

0

精华

新手上路

积分
45
金钱
45
注册时间
2013-9-6
在线时间
2 小时
发表于 2017-12-26 15:25:11 | 显示全部楼层
mark
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
20
金钱
20
注册时间
2019-11-5
在线时间
4 小时
发表于 2019-12-14 14:28:56 | 显示全部楼层
为啥都不用 waitACK  ?????
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-22 00:20

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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