#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); }