我是来结贴的:
问题有点奇葩,但是解决方法很简单。
主要问题在电路上,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]
|