Files
RC/RTC.c
2025-10-21 20:34:06 +08:00

239 lines
4.4 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "MAIN.H"
unsigned char bySta = 0;
void SDAOut(bit c)
{
SFR_PAGE(_pp0, noSST); // switch to page 0
P4_DIR = P4_DIR | 0x08;//修改P4.3为输出
P4_3 = c;
}
void SCLOut(bit c)
{
P1_5 = c;
}
void iic_start(void)
{
SDAOut(1);
_nop_();
SCLOut(1);
somenop;
SDAOut(0);
somenop;
SCLOut(0);
}
void iic_stop(void)
{
SDAOut(0);
_nop_();
SCLOut(1);
somenop;
SDAOut(1);
}
void iic_ack(bit ackbit)
{
if(ackbit)
SDAOut(0);
else
SDAOut(1);
somenop;
SCLOut(1);
somenop;
SCLOut(0);
SDAOut(1);
somenop;
}
bit iic_waitack(void)
{
SDAOut(1);
somenop;
SCLOut(1);
SFR_PAGE(_pp0, noSST); // switch to page 0
P4_DIR = P4_DIR & 0xF7;//修改P4.3为输入
somenop;
if(P4_3)
{
SCLOut(0);
iic_stop();
return 0;
}
else
{
SCLOut(0);
return 1;
}
}
void iic_sendbyte(unsigned char byt)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(byt&0x80)
SDAOut(1);
else
SDAOut(0);
somenop;
SCLOut(1);
byt <<= 1;
somenop;
SCLOut(0);
}
}
unsigned char iic_recbyte(void)
{
unsigned char da;
unsigned char i;
SFR_PAGE(_pp0, noSST); // switch to page 0
P4_DIR = P4_DIR & 0xF7;//修改P4.3为输入
for(i=0;i<8;i++)
{
SCLOut(1);
somenop;
da <<= 1;
// P1_IOCR01 = 0x0020; // load port control register 1
if(P4_3)
da |= 0x01;
SCLOut(0);
somenop;
}
return da;
}
// 十进制转 BCD 码
unsigned char DecToBcd(unsigned char dec)
{
return ((dec / 10) << 4) | (dec % 10);
}
// BCD 码转十进制
unsigned char BcdToDec(unsigned char bcd)
{
return ((bcd >> 4) * 10) + (bcd & 0x0F);
}
// BM8563 写寄存器函数
void BM8563_WriteReg(unsigned char reg, unsigned char rdata)
{
iic_start();
iic_sendbyte(BM8563_ADDR); // 发送 BM8563 的 I2C 地址,写操作
iic_waitack();
iic_sendbyte(reg); // 发送寄存器地址
iic_waitack();
iic_sendbyte(rdata); // 发送数据
iic_waitack();
iic_stop();
}
// BM8563 读寄存器函数
unsigned char BM8563_ReadReg(unsigned char reg)
{
unsigned char rdata;
iic_start();
iic_sendbyte(BM8563_ADDR); // 发送 BM8563 的 I2C 地址,写操作
iic_waitack();
iic_sendbyte(reg); // 发送寄存器地址
iic_waitack();
iic_start();
iic_sendbyte(BM8563_ADDR | 0x01); // 发送 BM8563 的 I2C 地址,读操作
iic_waitack();
rdata = iic_recbyte();
iic_ack(0);
iic_stop();
return rdata;
}
// 初始化 BM8563 的时间
void BM8563_InitTime()
{
BM8563_WriteReg(BM8563_SEC, 0x00); // 秒
BM8563_WriteReg(BM8563_MIN, 0x00); // 分
BM8563_WriteReg(BM8563_HOUR, 0x00); // 小时
BM8563_WriteReg(BM8563_DAY, 0x01); // 日
BM8563_WriteReg(BM8563_WEEK, 0x01); // 周
BM8563_WriteReg(BM8563_MONTH, 0x01); // 月
BM8563_WriteReg(BM8563_YEAR, DecToBcd(0x25)); // 年,假设为 2025 年
}
// 配置 BM8563 的定时器,实现间隔 4 小时的倒计时唤醒
void BM8563_Set4HourCountdown()
{
// BM8563_WriteReg(BM8563_CONTROL, 0x01);
//
//
// bySta = BM8563_ReadReg(BM8563_CONTROL);
// 4 小时的秒数4 * 60 * 60 = 14400 秒
unsigned int fourHoursInSeconds = 5;
// 选择时钟频率为 1/60 Hz
unsigned char timerControl = 0x02; // 11 for 1/60 Hz
// 计算所需的计数值
unsigned char timerValue = fourHoursInSeconds * 10; // 因为 1/60 Hz 意味着 1 count per minute
// 先将定时器控制寄存器设置为 0停止定时器
BM8563_WriteReg(BM8563_CONTROL, 0x00);
// 写入定时器计数值
BM8563_WriteReg(BM8563_TIMER_VALUE, timerValue);
// 配置定时器控制寄存器,使能定时器,且定时器到时产生中断
BM8563_WriteReg(BM8563_CONTROL, (timerControl | 0x80));
BM8563_WriteReg(BM8563_CSR2, 0x01);
}
// 配置 BM8563 的闹钟,实现间隔 4 小时的唤醒
void BM8563_Set4HourAlarm()
{
unsigned char alarmMin = BcdToDec( BM8563_ReadReg(BM8563_MIN) );
unsigned char alarmMinBcd = 0;
//------------------------------------------------------------
alarmMin = (alarmMin + 2) % 60;//计算 4 小时后的小时数
alarmMinBcd = DecToBcd(alarmMin);
BM8563_WriteReg(BM8563_ALARM_MIN,alarmMinBcd&0x7F);// 闹钟分钟设置
BM8563_WriteReg(BM8563_ALARM_HOUR, 0x80); // 无效
BM8563_WriteReg(BM8563_ALARM_DAY , 0x80); // 无效
BM8563_WriteReg(BM8563_ALARM_WEEK, 0x80); // 无效
// 配置闹钟控制寄存器,使能闹钟中断
BM8563_WriteReg(BM8563_CSR2, 0x02);
}