239 lines
4.4 KiB
C
239 lines
4.4 KiB
C
#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);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|