/**
*****************************************************************************
* 时钟芯片PCF8563驱动
*
* (C) Copyright 2000-2020, ***
* All Rights Reserved
*****************************************************************************
*
* @File : pcf8563.c
* @By : Sam Chan
* @Version : V1.0
* @Date : 2012 / 08 / 28
*
*****************************************************************************
* Update
* @Version : V1.0.1
* @By : Sam Chan
* @Date : 2013 / 10 / 20
* @Brief : A、增加显示时间日期格式数组
* B、增加读取时间处理函数,读取到的时间日期信息直接转换成ASCII保存到时间格式数组中
* C、调用时间日期处理函数,显示或者打印到串口的话直接显示或者打印时间格式数组即可
*
* @Version : V1.0.2
* @By : Sam Chan
* @Date : 2014 / 02 / 26
* @Brief : 修正年结构为16位数值,数值位,比如20xx、19xx
*
* @Version : V1.0.3
* @By : Sam Chan
* @Date : 2014 / 03 / 09
* @Brief : 增加PCF8563是否存在检测函数
*
* @Version : V1.0.4
* @By : Sam Chan
* @Date : 2014 / 05 / 10
* @Brief : A、增加导入默认参数函数,方便移植
* B、增加对C++环境的支持
*
* @Version : V1.0.5
* @By : Sam Chan
* @Date : 2014 / 07 / 19
* @Brief : A、修正显示时间时bug,显示字符后有乱码现象或者显示了不该显示的字符
* B、增加直接设置时间函数,方便用类似于USMART这样的工具直接调整
*
* @Version : V2.0
* @By : Sam
* @Date : 2015 / 05 / 15
* @Brief : 全面修改代码,增加带BIN和BCD转换功能
*
*****************************************************************************
**/
#include "bsp.h"
#include "iic.h"
/******************************************************************************
定义相关的变量函数
******************************************************************************/
unsigned char buffer[4];
/**
*****************************************************************************
* @Name : 将BIN转换为BCD
*
* @Brief : none
*
* @Input : BINValue: 输入BIN
*
* @Output : none
*
* @Return : BCD格式数值
*****************************************************************************
**/
static unsigned char RTC_BinToBcd2(unsigned char BINValue)
{
unsigned char bcdhigh = 0;
while (BINValue >= 10)
{
bcdhigh++;
BINValue -= 10;
}
return ((unsigned char)(bcdhigh << 4) | BINValue);
}
/**
*****************************************************************************
* @Name : 将BCD转换为BIN
*
* @Brief : none
*
* @Input : BCDValue: 输入BCD
*
* @Output : none
*
* @Return : BIN格式数值
*****************************************************************************
**/
static unsigned char RTC_Bcd2ToBin(unsigned char BCDValue)
{
unsigned char tmp = 0;
tmp = ((unsigned char)(BCDValue & (unsigned char)0xF0) >> (unsigned char)0x04) * 10;
return (tmp + (BCDValue & (unsigned char)0x0F));
}
/**
*****************************************************************************
* @Name : PCF8563某寄存器写入一个字节数据
*
* @Brief : none
*
* @Input : REG_ADD:要操作寄存器地址
* dat: 要写入的数据
*
* @Output : none
*
* @Return : none
*****************************************************************************
**/
void PCF8563_Write_Byte(unsigned char REG_ADD, unsigned char dat)
{
IIC_Start();
if(!(IIC_Write_Byte(PCF8563_Write))) //发送写命令并检查应答位
{
IIC_Write_Byte(REG_ADD);
IIC_Write_Byte(dat); //发送数据
}
IIC_Stop();
}
/**
*****************************************************************************
* @Name : PCF8563某寄存器读取一个字节数据
*
* @Brief : none
*
* @Input : REG_ADD:要操作寄存器地址
*
* @Output : none
*
* @Return : 读取得到的寄存器的值
*****************************************************************************
**/
unsigned char PCF8563_Read_Byte(unsigned char REG_ADD)
{
unsigned char ReData;
IIC_Start();
if(!(IIC_Write_Byte(PCF8563_Write))) //发送写命令并检查应答位
{
IIC_Write_Byte(REG_ADD); //确定要操作的寄存器
IIC_Start(); //重启总线
IIC_Write_Byte(PCF8563_Read); //发送读取命令
ReData = IIC_Read_Byte(); //读取数据
IIC_Ack(1); //发送非应答信号结束数据传送
}
IIC_Stop();
return ReData;
}
/**
*****************************************************************************
* @Name : PCF8563写入多组数据
*
* @Brief : none
*
* @Input : REG_ADD:要操作寄存器起始地址
* num: 写入数据数量
* *WBuff: 写入数据缓存
*
* @Output : none
*
* @Return : none
*****************************************************************************
**/
void PCF8563_Write_nByte(unsigned char REG_ADD, unsigned char num, unsigned char *pBuff)
{
unsigned char i = 0;
IIC_Start();
if(!(IIC_Write_Byte(PCF8563_Write))) //发送写命令并检查应答位
{
IIC_Write_Byte(REG_ADD); //定位起始寄存器地址
for(i = 0;i < num;i++)
{
IIC_Write_Byte(*pBuff); //写入数据
pBuff++;
}
}
IIC_Stop();
}
/**
*****************************************************************************
* @Name : PCF8563读取多组数据
*
* @Brief : none
*
* @Input : REG_ADD:要操作寄存器起始地址
* num: 读取数据数量
*
* @Output : *WBuff: 读取数据缓存
*
* @Return : none
*****************************************************************************
**/
void PCF8563_Read_nByte(unsigned char REG_ADD, unsigned char num, unsigned char *pBuff)
{
unsigned char i = 0;
IIC_Start();
if(!(IIC_Write_Byte(PCF8563_Write))) //发送写命令并检查应答位
{
IIC_Write_Byte(REG_ADD); //定位起始寄存器地址
IIC_Start(); //重启总线
IIC_Write_Byte(PCF8563_Read); //发送读取命令
for(i = 0;i < num;i++)
{
*pBuff = IIC_Read_Byte(); //读取数据
if(i == (num - 1)) IIC_Ack(1); //发送非应答信号
else IIC_Ack(0); //发送应答信号
pBuff++;
}
}
IIC_Stop();
}
/**
*****************************************************************************
* @Name : PCF8563检测是否存在
*
* @Brief : 向定时器倒计时寄存器写入一个数值再读取出来做对比,相同正确,不同则错误
*
* @Input : none
*
* @Output : none
*
* @Return : 0: 正常
* 1: PCF8563错误或者损坏
*****************************************************************************
**/
unsigned char PCF8563_Check(void)
{
unsigned char test_value = 0;
unsigned char Time_Count = 0; //定时器倒计时数据缓存
if(PCF8563_Read_Byte(PCF8563_Address_Timer) & 0x80) //如果打开了定时器,则先关闭
{
PCF8563_Write_Byte(PCF8563_Address_Timer, PCF_Timer_Close); //先关闭定时器
Time_Count = PCF8563_Read_Byte(PCF8563_Address_Timer_VAL); //先保存计数值
}
PCF8563_Write_Byte(PCF8563_Address_Timer_VAL, PCF8563_Check_Data); //写入检测值
for(test_value = 0;test_value < 50;test_value++) {} //延时一定时间再读取
test_value = PCF8563_Read_Byte(PCF8563_Address_Timer_VAL); //再读取回来
if(Time_Count != 0) //启动了定时器功能,则恢复
{
PCF8563_Write_Byte(PCF8563_Address_Timer_VAL, Time_Count); //恢复现场
PCF8563_Write_Byte(PCF8563_Address_Timer, PCF_Timer_Open); //启动定时器
}
if(test_value != PCF8563_Check_Data) return 1; //器件错误或者损坏
return 0; //正常
}
/**
*****************************************************************************
* @Name : PCF8563启动
*
* @Brief : none
*
* @Input : none
*
* @Output : none
*
* @Return : none
*****************************************************************************
**/
void PCF8563_Start(void)
{
unsigned char temp = 0;
temp = PCF8563_Read_Byte(PCF856