PCF8563与AT24C02一样,是典型的IIC通信器件,这里就以它为例,编写基于LPC1768硬件IIC的通信代码:
上图是PCF8563各个寄存器地址,PCF8563的IIC地址是0xA2
#include "lpc17xx_i2c.h"
#include "lpc17xx_libcfg.h"
#include "lpc17xx_pinsel.h"
#include "pcf8563.h"
#define PCF8563_SLVADDR (0xa2>>1)
#define Status1_Address 0x00
#define Status2_Address 0x01
#define SECOND_ADDRESS 0x02
//从地址2开始一次是:秒 分 时 日 星期 月 年
#define Minute_Alarm_Address 0x09
#define Hour_Alarm_Address 0x0a
#define Day_Alarm_Address 0x0b
#define Weekday_Alarm_Address 0x0c
#define CLKOUT_Address 0x0d
TIME_RTC RTC_time;
uint8_t Bcd2Hex(uint8_t bcd_data)
{
uint8_t hex_data;
hex_data=((bcd_data&0xf0)>>4)*10+(bcd_data&0x0f);
return hex_data;
}
uint8_t Hex2Bcd(uint8_t hex_data)
{
uint8_t temp;
temp=((hex_data/10)<<4)+(hex_data%10);
return temp;
}
void Time_Cover(uint8_t *p, int type)
{
int i;
if(type==0) //读出时间 BCD->Hex
{
for(i=0;i<sizeof(TIME_RTC);i++)
p[i]=Bcd2Hex(p[i]);
}
else //写入时间
{
for(i=0;i<sizeof(TIME_RTC);i++)
p[i]=Hex2Bcd(p[i]);
}
}
int PCF8563_Read(void)
{
I2C_M_SETUP_Type rxsetup;
uint8_t tx_addr=SECOND_ADDRESS;
rxsetup.sl_addr7bit = PCF8563_SLVADDR;
rxsetup.tx_data = (volatile uint8_t *)&tx_addr; // Get address to read at writing address
rxsetup.tx_length = 1;
rxsetup.rx_data = (volatile uint8_t *)&RTC_time;
rxsetup.rx_length = sizeof(RTC_time);
rxsetup.retransmissions_max = 3;
if (I2C_MasterTransferData(RTC_IIC, &rxsetup, I2C_TRANSFER_POLLING) == SUCCESS){
return (0);
} else {
return (-1);
}
}
int PCF8563_Write(uint8_t *p,uint8_t len)
{
I2C_M_SETUP_Type txsetup;
txsetup.sl_addr7bit = PCF8563_SLVADDR;
txsetup.tx_data = p;
txsetup.tx_length = len;
txsetup.rx_data = NULL;
txsetup.rx_length = 0;
txsetup.retransmissions_max = 3;
if (I2C_MasterTransferData(RTC_IIC, &txsetup, I2C_TRANSFER_POLLING) == SUCCESS){
return (0);
} else {
return (-1);
}
}
int SettingTime(TIME_RTC *r)
{
Time_Cover((uint8_t *)r,1);
return PCF8563_Write((uint8_t *)r,sizeof(TIME_RTC));
}
int Init_RTC(void)
{
if(PCF8563_Read()==0)
{
Time_Cover((uint8_t *)&RTC_time,0);
if(RTC_time.Year<19 || RTC_time.Year>99)
{
RTC_time.Year = 19;
RTC_time.Month = 3;
RTC_time.Day = 12;
RTC_time.Hour = 7;
RTC_time.Minute= 59;
RTC_time.Second= 56;
SettingTime(&RTC_time);
return 1;
}
return 0;
}
return -1;
}
void ReFresh_Time(void)
{
if(PCF8563_Read()==0)
{
Time_Cover((uint8_t *)&RTC_time,0);
}
}
#ifndef __PCF8563_H__
#define __PCF8563_H__
#define RTC_IIC LPC_I2C2
typedef struct{
unsigned char Second;
unsigned char Minute;
unsigned char Hour;
unsigned char Day;
unsigned char Week;
unsigned char Month;
unsigned char Year;
} TIME_RTC;
extern TIME_RTC RTC_time;
int PCF8563_Read(void);
int Init_RTC(void);
void ReFresh_Time(void);
#endif
实际测试发现硬件版IIC也挺简单,最大支持400kHz速率。