【PCF8563 时钟芯片驱动代码】//C文件
/*************************************************************************************************************
* 文件名:PCF8563.c
* 功能:STM32 PCF8563 高精度 RTC 芯片驱动
* 作者:cp1300@139.com
* 创建时间:2017-07-10
* 最后修改时间: 2017-07-10
* 详细:使用软件IIC接口驱动
2017-07-13:通过写入PCF8563_REG_CLKOUT与读取PCF8563_REG_CLKOUT寄存器,发现某些不用的位会乱跳,最终发现时间寄存器也有同样的问题,需要把不用的位都屏蔽掉
*************************************************************************************************************/
#include "system.h"
#include "delay.h"
#include "PCF8563.h"
#include "stdio.h"
#include "SoftwareIIC.h"//月修正数据表
static u8 const table_week[12] = {0,3,3,6,1,4,6,2,5,0,3,5};
//平年的月份日期表
static u8 const mon_table[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
static bool Is_Leap_Year(u16 year);
rtc_timer ext_timer;
//外部RTC时钟
static SIIC_HANDLE IIC_Handel;
#define PCF8563_SDA_GPIOxGPIOC
#define PCF8563_SCL_GPIOxGPIOC
#define PCF8563_SDA_Bit1
#define PCF8563_SCL_Bit13//调试宏开关
#define PCF8563_DBUG 1
#if PCF8563_DBUG
#include "system.h"
#define PCF8563_Debug(format,...) uart_printf(format,##__VA_ARGS__)
#else
#define PCF8563_Debug(format,...) /\
/
#endif //PCF8563_DBUG//PCF8563 iic总线地址
#define PCF8563_IIC_W_ADDR0xA2
#define PCF8563_IIC_R_ADDR0xA3static u8 GetWeek(u16 year,u8 month,u8 day);
//获取2000-2099年之间的日期对应的星期
static u32 DECtoBCD( u8 DEC);
//将数字转换为压缩BCD格式,最大支持99
static u32 BCDtoDEC(u8 BCD);
//将压缩BCD转为DEC,最大支持99
bool PCF8563_ReadReg(PCF8563_REG_TYPE RegIndex, u8 *pData, u8 RegNum) ;
//读取PCF8563寄存器
bool PCF8563_WriteReg(PCF8563_REG_TYPE RegIndex, u8 *pData, u8 RegNum) ;
//写入PCF8563寄存器
bool PCF8563_WriteOneReg(PCF8563_REG_TYPE RegIndex, u8 Data);
//写单个寄存器/*************************************************************************************************************************
*函数: bool PCF8563_Init(void)
*功能: 初始化PCF8563
*参数: 无
*返回: FALSE:失败;
TRUE:成功
*依赖:底层宏定义
*作者: cp1300@139.com
*时间: 2017-07-10
*最后修改时间 : 2017-07-10
*说明: 无
*************************************************************************************************************************/
bool PCF8563_Init(void)
{
u8 data;
memset(&ext_timer,0,sizeof(rtc_timer));
if(SIIC_Init(&IIC_Handel,PCF8563_SDA_GPIOx, PCF8563_SCL_GPIOx, PCF8563_SDA_Bit, PCF8563_SCL_Bit, 1) == FALSE)
{
PCF8563_Debug("**********************PCF8563 初始化失败,IIC接口初始化失败!\r\n");
return FALSE;
}
if(PCF8563_WriteOneReg(PCF8563_REG_CONTROL1, 0x08) == FALSE) //启动时钟,开启掉电检测
{
PCF8563_Debug("**********************PCF8563 初始化失败,开启掉电监测功能失败!\r\n");
return FALSE;
} if(PCF8563_ReadReg(PCF8563_REG_SECONDS, &data, 1) == FALSE)
{
PCF8563_Debug("**********************PCF8563 初始化失败,读取秒寄存器失败!\r\n");
return FALSE;
}
if(data & 0x80) //秒 最高位为1,时钟芯片没有初始化 integrity of the clock information is no longer guaranteed
{
//初始化时钟芯片与时间
PCF8563_Debug("时钟芯片没有初始化,需要重新初始化时钟!\r\n");
if(PCF8563_SetTimer(2017,6,6,6,6,6)==FALSE)
{
PCF8563_Debug("时钟芯片没有初始化,需要重新初始化时钟!\r\n");
}
}
PCF8563_GetTimer();
//更新时间
return TRUE;
}/*************************************************************************************************************************
*函数: bool PCF8563_ReadReg(PCF8563_REG_TYPE RegIndex, u8 *pData, u8 RegNum)
*功能: 读取PCF8563多个寄存器
*参数: RegIndex:寄存器地址,pData:读取到的值,RegNum:读取的寄存器数量
*返回: TRUE:通信成功;FALSE:通信失败
*依赖:底层宏定义
*作者: cp1300@139.com
*时间: 2017-07-10
*最后修改时间 : 2017-07-10
*说明: 无
*************************************************************************************************************************/
bool PCF8563_ReadReg(PCF8563_REG_TYPE RegIndex, u8 *pData, u8 RegNum)
{
u8 i;
if(RegNum < 1) RegNum = 1;
if(RegNum > 16) RegNum = 16;
//限制读取的最大数量
SIIC_Start(&IIC_Handel);
//发送起始信号
if(SIIC_SendByte(&IIC_Handel, PCF8563_IIC_W_ADDR)==FALSE) //发送写地址
{
PCF8563_Debug("PCF8563 发送写地址 ACK错误\r\n");
return FALSE;
}
if(SIIC_SendByte(&IIC_Handel, RegIndex)==FALSE)//发送要读取的寄存器地址
{
PCF8563_Debug("PCF8563 发送要读取的寄存器地址2 ACK错误\r\n");
return FALSE;
}
SIIC_Start(&IIC_Handel);
//发送起始信号
if(SIIC_SendByte(&IIC_Handel, PCF8563_IIC_R_ADDR)==FALSE) //发送读取地址
{
PCF8563_Debug("PCF8563 发送读取地址 ACK错误\r\n");
return FALSE;
}
for(i = 0;
i < RegNum;
i ++)
{
if(i == (RegNum-1))//最后一字节
{
pData[i] = SIIC_ReadByte(&IIC_Handel, FALSE);
//读取数据-最后一字节不发送ACK
}
else
{
pData[i] = SIIC_ReadByte(&IIC_Handel, TRUE);
//读取数据
}
}
SIIC_Stop(&IIC_Handel);
//发送结束 return TRUE;
}/*************************************************************************************************************************
*函数: bool PCF8563_ReadOneReg(PCF8563_REG_TYPE RegIndex, u8 *pData)
*功能: 读取PCF8563单个寄存器
*参数: RegIndex:寄存器地址,pData:读取到的值
*返回: TRUE:通信成功;FALSE:通信失败
*依赖:底层宏定义
*作者: cp1300@139.com
*时间: 2017-07-10
*最后修改时间 : 2017-07-13
*说明: 无
*************************************************************************************************************************/
bool PCF8563_ReadOneReg(PCF8563_REG_TYPE RegIndex, u8 *pData)
{
SIIC_Start(&IIC_Handel);
//发送起始信号
if(SIIC_SendByte(&IIC_Handel, PCF8563_IIC_W_ADDR)==FALSE) //发送写地址
{
PCF8563_Debug("PCF8563 发送写地址 ACK错误\r\n");
return FALSE;
}
if(SIIC_SendByte(&IIC_Handel, RegIndex)==FALSE)//发送要读取的寄存器地址
{
PCF8563_Debug("PCF8563 发送要读取的寄存器地址2 ACK错误\r\n");
return FALSE;
}
SIIC_Start(&IIC_Handel);
//发送起始信号
if(SIIC_SendByte(&IIC_Handel, PCF8563_IIC_R_ADDR)==FALSE) //发送读取地址
{
PCF8563_Debug("PCF8563 发送读取地址 ACK错误\r\n");
return FALSE;
}
*pData = SIIC_ReadByte(&IIC_Handel, FALSE);
//读取数据-最后一字节不发送ACK
SIIC_Stop(&IIC_Handel);
//发送结束
return TRUE;
}/*************************************************************************************************************************
*函数: bool PCF8563_WriteReg(PCF8563_REG_TYPE RegIndex, u8 *pData, u8 RegNum)
*功能: 写PCF8563多个寄存器
*参数: RegIndex:寄存器地址,pData:写入的值,RegNum:写入的寄存器数量
*返回: TRUE:通信成功;FALSE:通信失败
*依赖:底层宏定义
*作者: cp1300@139.com
*时间: 2017-07-10
*最后修改时间 : 2017-07-10
*说明: 无
*************************************************************************************************************************/
bool PCF8563_WriteReg(PCF8563_REG_TYPE RegIndex, u8 *pData, u8 RegNum)
{
u8 i;
SIIC_Start(&IIC_Handel);
//发送起始信号
if(SIIC_SendByte(&IIC_Handel, PCF8563_IIC_W_ADDR)==FALSE) //发送写地址
{
PCF8563_Debug("PCF8563 发送写地址 ACK错误\r\n");
return FALSE;
} /*if(SIIC_SendByte(&IIC_Handel, 0)==FALSE)//发送要读取的寄存器地址
{
PCF8563_Debug("PCF8563 发送要读取的寄存器地址2 ACK错误\r\n");
return FALSE;
}*/
if(SIIC_SendByte(&IIC_Handel, RegIndex)==FALSE)//发送要写的寄存器地址
{
PCF8563_Debug("PCF8563 发送要读取的寄存器地址2 ACK错误\r\n");
return FALSE;
}
/*SIIC_Start(&IIC_Handel);
//发送起始信号
if(SIIC_SendByte(&IIC_Handel, PCF8563_IIC_W_ADDR)==FALSE) //发送写地址
{
PCF8563_Debug("PCF8563 发送读取地址 ACK错误\r\n");
return FALSE;
}*/
for(i = 0;
i < RegNum;
i ++)
{
SIIC_SendByte(&IIC_Handel, pData[i]);
//发送数据
}
SIIC_Stop(&IIC_Handel);
//发送结束 return TRUE;
}/*************************************************************************************************************************
*函数: bool PCF8563_WriteOneReg(PCF8563_REG_TYPE RegIndex, u8 Data)
*功能: 写PCF8563单个寄存器
*参数: RegIndex:寄存器地址,Data:写入的值
*返回: TRUE:通信成功;FALSE:通信失败
*依赖:底层宏定义
*作者: cp1300@139.com
*时间: 2017-07-10
*最后修改时间 : 2017-07-13
*说明: 无
*************************************************************************************************************************/
bool PCF8563_WriteOneReg(PCF8563_REG_TYPE RegIndex, u8 Data)
{
SIIC_Start(&IIC_Handel);
//发送起始信号
if(SIIC_SendByte(&IIC_Handel, PCF8563_IIC_W_ADDR)==FALSE) //发送写地址
{
PCF8563_Debug("PCF8563 发送写地址 ACK错误\r\n");
return FALSE;
}
if(SIIC_SendByte(&IIC_Handel, RegIndex)==FALSE)//发送要写的寄存器地址
{
PCF8563_Debug("PCF8563 发送要读取的寄存器地址2 ACK错误\r\n");
return FALSE;
}
SIIC_SendByte(&IIC_Handel, Data);
//发送数据
SIIC_Stop(&IIC_Handel);
//发送结束 return TRUE;
}/*************************************************************************************************************************
* 函数: bool PCF8563_GetTimer(void)
* 功能: PCF8563获取时间
* 参数: 无
* 返回: TRUE:成功,FALSE:失败
* 依赖: 底层宏定义
* 作者: cp1300@139.com
* 时间: 2017-07-11
* 最后修改时间:2017-07-11
* 说明:获取到的时间会更新到全局ext_timer
*************************************************************************************************************************/
bool PCF8563_GetTimer(void)
{
u8 data[7];
u8 retry;
u8 temp;
for(retry = 0;
retry < 3;
retry ++)
{
if(PCF8563_ReadReg(PCF8563_REG_SECONDS, data, 7) == TRUE) //设置时间
{
if(data[0] & 0x80) //时间无效
{
PCF8563_Debug("PCF8563 时间无效,需要重新初始化!\r\n");
PCF8563_SetTimer(2017,6,6,6,6,6);
//初始化设置时间
}
else
{//uart_printf("%02X,%02X,%02X,%02X,%02X,%02X,%02X\r\n",data[0],data[1],data[2],data[3],data[4],data[5],data[6]);
temp = BCDtoDEC(data[0]&0x7F);
if(temp > 59) continue;
//秒钟范围不对
ext_timer.sec = temp;
temp = BCDtoDEC(data[1]&0x7F);
if(temp > 59) continue;
//分钟范围不对
ext_timer.min = temp;
temp = BCDtoDEC(data[2]&0x3F);
if(temp > 23) continue;
//小时范围不对
ext_timer.hour = temp;
temp = BCDtoDEC(data[3]&0x3F);
if(temp > 31||temp==0) continue;
//日期范围不对
ext_timer.date = temp;
temp = BCDtoDEC(data[4]&0x07);
if(temp > 6) continue;
//星期范围不对
ext_timer.week = temp+1;
temp = BCDtoDEC(data[5]&0x1F);
if(temp > 12||temp==0) continue;
//月份范围不对
ext_timer.month = temp;
ext_timer.year = BCDtoDEC(data[6])+2000;
return TRUE;
}
}
else
{
PCF8563_Debug("PCF8563 读取时间失败!\r\n");
}
}
return FALSE;
}/*************************************************************************************************************************
* 函数: bool PCF8563_SetTimer(u16 year,u8 month,u8 date,u8 hour,u8 min,u8 sec)
* 功能: PCF8563时间设置
* 参数: year,month,date:年(2000~2099),月(1~12),日(1~31),hour,min,sec:小时24小时,分钟,秒钟
* 返回: TRUE:成功,FALSE:失败
* 依赖: 底层宏定义
* 作者: cp1300@139.com
* 时间: 2017-07-11
* 最后修改时间:2017-07-11
* 说明:
*************************************************************************************************************************/
bool PCF8563_SetTimer(u16 year,u8 month,u8 date,u8 hour,u8 min,u8 sec)
{
u8 data[7];
if(year < 2000) year = 2000;
if(year > 2099) year = 2099;
data[0] = DECtoBCD(sec);
//秒
data[1] = DECtoBCD(min);
//分
data[2] = DECtoBCD(hour);
//小时
data[3] = DECtoBCD(date);
//日
data[4] = GetWeek(year, month, date)-1;
//星期
year -= 2000;
data[5] = DECtoBCD(month);
//月
data[6] = DECtoBCD(year);
//年
PCF8563_WriteReg(PCF8563_REG_SECONDS, &data[0], 7);
//设置时间
if(PCF8563_WriteOneReg(PCF8563_REG_CONTROL1, 0x08) == FALSE) //启动时钟,开启掉电检测
{
PCF8563_Debug("**********************PCF8563 设置失败,启动时钟失败!\r\n");
return FALSE;
}
return TRUE;
}/*************************************************************************************************************************
* 函数: u32 PCF8563_TimeToSec(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec)
* 功能: PCF8563时间转换为秒(从1970开始)(注意:不可重入,请注意调用冲突)
* 参数: year,month,date:年(2000~2099),月(1~12),日(1~31),hour,min,sec:小时24小时,分钟,秒钟
* 返回: TRUE:成功,FALSE:失败
* 依赖: 底层宏定义
* 作者: cp1300@139.com
* 时间: 2017-07-11
* 最后修改时间:2017-07-17
* 说明:只能计算从2000年之后的秒,修改如果年,月,日不变,则无需重新计算,提高效率
注意:不可重入,请注意调用冲突
*************************************************************************************************************************/
u32 PCF8563_TimeToSec(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec)
{
u16 t;
u32 seccount = 0;
static u32 LastYearSec = 0;
//之前年对应的秒,如果年不变,则不用重新计算
static u32 LastMonSec = 0;
//当前年月份对应的秒数,如果月份不变,则不需要重新计算
static u32 LastDaySec = 0;
//当前日期对应的秒,如果日期不变,则不需要重新计算
static u16 LastYear = 0;
//之前的年如果不变,则只计算今年的秒
static u8 LastMon = 0;
//当前年之前的月份
static u8 LastDay = 0;
//之前的日期
if(syear < 2000 || syear > 2099)
return 0;
//年变化了才重新计算
if(LastYear != syear)//年发生了变化,重新计算
{
LastYear = syear;
//记录本次的年
LastYearSec = 0;
for(t = 1970;
t < syear;
t ++)//把所有年份的秒钟相加
{
if(Is_Leap_Year(t))
LastYearSec += 31622400;
//闰年的秒钟数
else
LastYearSec += 31536000;
//平年的秒钟数
}
} //月变化了才重新计算
if(LastMon != smon)//月份有变化
{
LastMon = smon;
//记录本次的月份
smon -= 1;
LastMonSec = 0;
for(t = 0;
t < smon;
t ++)//把前面月份的秒钟数相加
{
LastMonSec += (u32)mon_table[t] * 86400;
//月份秒钟数相加
if(Is_Leap_Year(syear) && t == 1)
LastMonSec += 86400;
//闰年2月份增加一天的秒钟数
}
}
//日期变化了才重新计算
if(LastDay != sday)
{
LastDay = sday;
//记录本次的日期
LastDaySec = (u32)(sday - 1) * 86400;
//把前面日期的秒钟数相加
}
seccount = LastYearSec+LastMonSec+LastDaySec;
//直接获取年对应的秒,不用每次计算 seccount += (u32)hour * 3600;
//小时秒钟数
seccount += (u32)min * 60;
//分钟秒钟数
seccount += sec;
//最后的秒钟加上去
return seccount;
}/*************************************************************************************************************************
* 函数: bool Is_Leap_Year(u16 year)
* 功能: 判断是否是闰年函数
* 参数: year:年份
* 返回: TRUE:是闰年,FALSE:不是闰年
* 依赖: 无
* 作者: cp1300@139.com
* 时间: 2014-05-30
* 最后修改时间 : 2014-05-30
* 说明:
月份12345678910 11 12
闰年31 29 31 30 31 30 31 31 30 31 30 31
非闰年 31 28 31 30 31 30 31 31 30 31 30 31
*************************************************************************************************************************/
static bool Is_Leap_Year(u16 year)
{
if(year % 4 == 0) //必须能被4整除
{
if(year % 100 == 0)
{
if(year % 400 == 0)
return TRUE;
//如果以00结尾,还要能被400整除
else
return FALSE;
}else
return TRUE;
}else
return FALSE;
}//获取2000-2099年之间的日期对应的星期
//功能描述:输入公历日期得到星期(只允许1901-2099年)
//year,month,day:公历年月日
//返回值:星期号(1~7,代表周1~周日)
static u8 GetWeek(u16 year,u8 month,u8 day)
{
u16 temp2;
u8 yearH,yearL;
yearH=year/100;
yearL=year%100;
// 如果为21世纪,年份数加100
if (yearH>19)yearL+=100;
// 所过闰年数只算1900年之后的
temp2=yearL+yearL/4;
temp2=temp2%7;
temp2=temp2+day+table_week[month-1];
if (yearL%4==0&&month<3)temp2--;
temp2%=7;
if(temp2==0)temp2=7;
return temp2;
} //将数字转换为压缩BCD格式,最大支持99
static u32 DECtoBCD( u8 DEC)
{
return ((u8)(DEC/10)<<4)+(DEC%10);
}//将压缩BCD转为DEC,最大支持99
static u32 BCDtoDEC(u8 BCD)
{
return (u8)(BCD>>4)*10+(BCD&0x0f);
}//使能系统命令行
#if SYS_CMD_EN_
#include "cmd.h"
#include "string.h"const CMD_TYPECMD_GET_ExtTIME= {"TIME?", 0xCC5C410A, CMD_ExtGetTime, "\t\t获取系统时间"};
const CMD_TYPECMD_GET_ExtDATE= {"DATE?", 0xB2704461, CMD_ExtGetDate, "\t\t获取系统日期"};
const CMD_TYPECMD_SET_ExtTIME= {"TIME=", 0xCC5C4108, CMD_ExtSetTime, "\t\t设置系统时间 如(12:32:54):TIME=12 32 54"};
const CMD_TYPECMD_SET_ExtDATE= {"DATE=", 0xB270445F, CMD_ExtSetDate, "\t\t设置系统日期 如(2014 6 8):TIME=2014 6 8"};
//获取时间
void CMD_ExtGetTime(char *pStr)
{
//PCF8563_GetTimer();
//更新时间
cmd_printf("[获取时间成功]:%02d:%02d:%02d\r\n",ext_timer.hour, ext_timer.min, ext_timer.sec);
}//获取日期
void CMD_ExtGetDate(char *pStr)
{
//PCF8563_GetTimer();
//更新时间
cmd_printf("[获取日期成功]:%04d-%02d-%02d\r\n",ext_timer.year, ext_timer.month, ext_timer.date);
}//设置时间
void CMD_ExtSetTime(char *pStr)
{
u8 hour,min,sec;
u8 len;
char *p;
u8 num;
len = strlen(pStr);
//获取长度
if(isStrNumAndSpc(pStr, len, 2) == FALSE)
{
cmd_printf("[时间设置错误]:格式不对或非法参数!\r\n");
return;
}
//小时
p = strstr(pStr," ");
//搜索空格
if(p == NULL)
{
cmd_printf("[时间设置错误]:格式不对或非法参数!\r\n");
return;
}
num = p - pStr;
if((num > 2) || (num == 0))
{
cmd_printf("[时间设置错误]:格式不对或非法参数!\r\n");
return;
}
hour = CMD_StringToDec(pStr, num);
if(hour>23)
{
cmd_printf("[时间设置错误]:格式不对或非法参数!\r\n");
return;
}
//分钟
pStr = p+1;
p = strstr(pStr," ");
//搜索空格
if(p == NULL)
{
cmd_printf("[时间设置错误]:格式不对或非法参数!\r\n");
return;
}
num = p - pStr;
if((num > 2) || (num == 0))
{
cmd_printf("[时间设置错误]:格式不对或非法参数!\r\n");
return;
}
min = CMD_StringToDec(pStr, num);
if(min>59)
{
cmd_printf("[时间设置错误]:格式不对或非法参数!\r\n");
return;
}
//秒钟
pStr = p+1;
num = strlen(pStr);
if((num > 2) || (num == 0))
{
cmd_printf("[时间设置错误]:格式不对或非法参数!\r\n");
return;
}
sec = CMD_StringToDec(pStr, num);
if(sec>59)
{
cmd_printf("[时间设置错误]:格式不对或非法参数!\r\n");
return;
}
PCF8563_GetTimer();
//更新时间
if(PCF8563_SetTimer(ext_timer.year, ext_timer.month, ext_timer.date,hour, min, sec) == FALSE)
{
PCF8563_GetTimer();
//更新时间
cmd_printf("[时间设置失败]:%02d:%02d:%02d\r\n",ext_timer.hour, ext_timer.min, ext_timer.sec);
}
else
{
PCF8563_GetTimer();
//更新时间
cmd_printf("[时间设置成功]:%02d:%02d:%02d\r\n",ext_timer.hour, ext_timer.min, ext_timer.sec);
}
} //设置日期
void CMD_ExtSetDate(char *pStr)
{
u16 year;
u8 month, date;
u8 len;
char *p;
u8 num;
len = strlen(pStr);
//获取长度
if(isStrNumAndSpc(pStr, len, 2) == FALSE)
{
cmd_printf("[日期设置错误]:格式不对或非法参数!\r\n");
return;
}
//年
p = strstr(pStr," ");
//搜索空格
if(p == NULL)
{
cmd_printf("[日期设置错误]:格式不对或非法参数!\r\n");
return;
}
num = p - pStr;
if((num > 4) || (num == 0))
{
cmd_printf("[日期设置错误]:格式不对或非法参数!\r\n");
return;
}
year = CMD_StringToDec(pStr, num);
if(year>9999)
{
cmd_printf("[日期设置错误]:格式不对或非法参数!\r\n");
return;
}
//月
pStr = p+1;
p = strstr(pStr," ");
//搜索空格
if(p == NULL)
{
cmd_printf("[日期设置错误]:格式不对或非法参数!\r\n");
return;
}
num = p - pStr;
if((num > 2) || (num == 0))
{
cmd_printf("[日期设置错误]:格式不对或非法参数!\r\n");
return;
}
month = CMD_StringToDec(pStr, num);
if(month>12)
{
cmd_printf("[日期设置错误]:格式不对或非法参数!\r\n");
return;
}
//日
pStr = p+1;
num = strlen(pStr);
if((num > 2) || (num == 0))
{
cmd_printf("[日期设置错误]:格式不对或非法参数!\r\n");
return;
}
date = CMD_StringToDec(pStr, num);
if(date>31)
{
cmd_printf("[日期设置错误]:格式不对或非法参数!\r\n");
return;
}
PCF8563_GetTimer();
//更新时间
if(PCF8563_SetTimer(year, month, date, ext_timer.hour, ext_timer.min, ext_timer.sec) == FALSE)
{
PCF8563_GetTimer();
//更新时间
cmd_printf("[日期设置失败]:%04d-%02d-%02d\r\n",ext_timer.year, ext_timer.month, ext_timer.date);
}
else
{
PCF8563_GetTimer();
//更新时间
cmd_printf("[日期设置成功]:%04d-%02d-%02d\r\n",ext_timer.year, ext_timer.month, ext_timer.date);
}
} #endif //SYS_CMD_EN_
//,H文件
/*************************************************************************************************************
* 文件名:PCF8563.h
* 功能:STM32 PCF8563 高精度 RTC 芯片驱动
* 作者:cp1300@139.com
* 创建时间:2017-07-10
* 最后修改时间: 2017-07-10
* 详细:使用软件IIC接口驱动
*************************************************************************************************************/
#ifndef _PCF8563_H_
#define _PCF8563_H_#include "system.h"#if(BOARD_SUPPORT) //需要板级支持
#include "board.h"
#else //默认支持#endif//时间结构体
typedefstruct
{
u8 hour;
//小时
u8 min;
//分钟
u8 sec;
//秒
u8month;
//月
u8date;
//日
u8week;
//星期
u16 year;
//年
}rtc_timer;
extern rtc_timer ext_timer;
//外部RTC时钟//PCF8563 寄存器
typedef enum
{
PCF8563_REG_CONTROL1= 0x00, //控制寄存器1
PCF8563_REG_CONTROL2= 0x01, //控制寄存器2
PCF8563_REG_SECONDS= 0x02, //秒 seconds 00 to 59 coded in BCD
PCF8563_REG_MINUTES= 0x03, //分 minutes 00 to 59 coded in BCD
PCF8563_REG_HOURS= 0x04, //小时 hours 00 to 23 coded in BCD
PCF8563_REG_DAYS= 0x05, //日 days 01 to 31 coded in BCD
PCF8563_REG_WEEK= 0x06, //星期 weekdays 0 to 6 in BCD
PCF8563_REG_MONTHS= 0x07, //月份 months 01 to 12 coded in BCD
PCF8563_REG_YEARS= 0x08, //年份 years 00 to 99 coded in BCD
PCF8563_REG_ALARM_MINUTE= 0x09, //闹钟,分钟 minute alarm 00 to 59 coded in BCD
PCF8563_REG_ALARM_HOUR= 0x0A, //闹钟,小时 hour alarm 00 to 23 coded in BCD
PCF8563_REG_ALARM_DAY= 0x0B, //闹钟,日 day alarm 01 to 31 coded in BCD
PCF8563_REG_ALARM_WEEK= 0x0C, //闹钟,星期 weekday alarm 0 to 6 in BCD
PCF8563_REG_CLKOUT= 0x0D, //时钟输出设置
PCF8563_REG_TIME_CONTROL= 0x0E, //定时器设置
PCF8563_REG_TIME= 0x0F, //定时器倒计数值
}PCF8563_REG_TYPE;
bool PCF8563_Init(void);
//PCF8563初始化
bool PCF8563_SetTimer(u16 year,u8 month,u8 date,u8 hour,u8 min,u8 sec);
//PCF8563时间设置
bool PCF8563_GetTimer(void);
//更新时间u32 PCF8563_TimeToSec(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec);
//时间转换为秒,注意:不可重入,请注意调用冲突//使能系统命令行
#if SYS_CMD_EN_
#include "cmd.h"
#include "string.h"extern const CMD_TYPECMD_GET_ExtTIME;
extern const CMD_TYPECMD_GET_ExtDATE;
extern const CMD_TYPECMD_SET_ExtTIME;
extern const CMD_TYPECMD_SET_ExtDATE;
//获取时间
void CMD_ExtGetTime(char *pStr);
//获取日期
void CMD_ExtGetDate(char *pStr);
//设置时间
void CMD_ExtSetTime(char *pStr);
//设置日期
void CMD_ExtSetDate(char *pStr);
#endif //SYS_CMD_EN_#endif /*_PCF8563_H_*/