📄 rtc.c
字号:
#include "config.h"
/********************************************************************
**02H 秒 03H分 04H小时
**05H 日 06H星期07H月/世纪 08H年
**报警
**09 分钟 0A小时 0B日 0C星期
********************************************************************/
#define PCF8563 0xA2 // 定义器件地址
void DelayNS2(uint32 dly)
{ uint32 i;
for(; dly>0; dly--)
{
for(i=0; i<50; i++);
}
}
void RTC_init(uint32 rate)
{
//uint8 data_buf[2];
if(rate>400000) rate = 400000;
PINSEL0 = (PINSEL0&0xFFFFFF0F) | 0x50; // 设置I2C控制口有效
I2SCLH = (Fpclk/rate + 1) / 2; // 设置I2C时钟为fi2c
I2SCLL = (Fpclk/rate) / 2;
I2CONCLR = 0x2C;
I2CONSET = 0x40; // 使能主I2C
// 设置I2C中断允许
VICIntSelect = 0x00000000; // 设置所有通道为IRQ中断
VICVectCntl4 = 0x29; // I2C通道分配到IRQ slot 0,即优先级最高
VICVectAddr4 = (int)IRQ_I2C; // 设置I2C中断向量地址
VICIntEnable|=0x0200; // 使能I2C中断
DelayNS2(10);
}
void RTC_shutdown(void)
{
PINSEL0 = (PINSEL0&0xFFFFFF0F);
}
uint8 BCDTOHEX(uint8 bcd)
{
uint8 i;
i=((bcd>>4)&0x0f)*10+(bcd&0x0f);
return i;
}
uint8 HEXTOBCD(uint8 hex)
{
uint8 i;
i=hex%100;
i=(((i/10)<<4)&0xf0)+i%10;
return i;
}
/******************************
**读取实时时钟时间
**返回时间,按 type_RTC_time_rec结构返回
******************************/
uint32 RTC_read_time(void)
{
type_RTC_time_rec time_rec;
uint8 data_buf[3];
//uint8 tmp;
RTC_init(100000);
IRcvStr(PCF8563, 0x02, data_buf, 3);
time_rec.fields.second=BCDTOHEX(data_buf[0]&0x7f);
time_rec.fields.minute=BCDTOHEX(data_buf[1]&0x7f);
time_rec.fields.hour=BCDTOHEX(data_buf[2]&0x3f);
RTC_shutdown();
return time_rec.l_word;
}
/******************************
**设置实时时钟时间
**入口参数为type_RTC_time_rec结构时间
**返回-1则失败,其他则成功
******************************/
int16 RTC_set_time(uint32 time_rec)
{
uint8 data_buf[5];
type_RTC_time_rec time_tmp;
time_tmp.l_word=time_rec;
RTC_init(100000);
data_buf[0]=0x00;
data_buf[1]=0x00;
data_buf[2]=HEXTOBCD(time_tmp.fields.second);
data_buf[2]=data_buf[2]&0x7f;
data_buf[3]=HEXTOBCD(time_tmp.fields.minute);
data_buf[3]=data_buf[3]&0x7f;
data_buf[4]=HEXTOBCD(time_tmp.fields.hour);
data_buf[4]=data_buf[4]&0x3f;
ISendStr(PCF8563, 0x00, data_buf, 5);
RTC_shutdown();
return 1;
}
/******************************
**读取实时时钟日期
**返回日期,按 type_RTC_date_rec结构返回
******************************/
uint32 RTC_read_date(void)
{
type_RTC_date_rec date_rec;
uint8 data_buf[4];
RTC_init(100000);
IRcvStr(PCF8563, 0x05, data_buf, 4);
date_rec.fields.day=BCDTOHEX(data_buf[0]&0x3f);
date_rec.fields.week=BCDTOHEX(data_buf[1]&0x07);
date_rec.fields.month=BCDTOHEX(data_buf[2]&0x1f);
if((data_buf[2]&0x80)!=0)//19xx
date_rec.fields.year=BCDTOHEX(data_buf[3])+1900;
else//20xx
date_rec.fields.year=BCDTOHEX(data_buf[3])+2000;
RTC_shutdown();
return date_rec.l_word;
}
/******************************
**设置实时时钟日期
**入口参数为type_RTC_date_rec结构日期
**返回-1则失败,其他则成功
******************************/
int16 RTC_set_date(uint32 date_rec)
{
uint8 dat_buf[4];
type_RTC_date_rec date_tmp;
date_tmp.l_word=date_rec;
RTC_init(100000);
dat_buf[0]=HEXTOBCD(date_tmp.fields.day);
dat_buf[0]=dat_buf[0]&0x3f;
dat_buf[1]=HEXTOBCD(date_tmp.fields.week);
dat_buf[1]=dat_buf[1]&0x07;
dat_buf[2]=HEXTOBCD(date_tmp.fields.month);
dat_buf[2]=dat_buf[2]&0x1f;
if(date_tmp.fields.year<2000)
dat_buf[2]=dat_buf[2]|0x80;
dat_buf[3]=HEXTOBCD(date_tmp.fields.year%100);
ISendStr(PCF8563, 0x05, dat_buf, 4);
RTC_shutdown();
return 1;
}
/*********************************************************************************************************
** End Of File
********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -