feat(rtc): add PCF8563 full date read/write (day/month/year/weekday)
PCF8563's second/minute/hour/day/weekday/month/year registers are contiguous (0x02-0x08), so PCF8563_ReadDateTime() bursts all 7 bytes in one transaction. PCF8563_ReadTime() becomes a thin wrapper that discards the date fields. WriteTime() is kept as its own 3-byte-only implementation (writing only sec/min/hour) rather than routed through the new WriteDateTime(), since forcing it through a 7-byte write would require synthesizing date values and risk corrupting the stored date; WriteDateTime() is added as a separate full 7-byte write for callers that actually have real date+weekday values to persist.
This commit is contained in:
@@ -256,11 +256,11 @@ void PCF8563_ScanDiagnostic(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 从 PCF8563 读取当前时间
|
||||
* @brief 从 PCF8563 连续读取时间与日期 (秒/分/时/日/星期/月/年,寄存器 0x02~0x08 地址连续)
|
||||
*/
|
||||
bit PCF8563_ReadTime(u8 *hour, u8 *min, u8 *sec)
|
||||
bit PCF8563_ReadDateTime(u8 *hour, u8 *min, u8 *sec, u8 *day, u8 *month, u8 *year)
|
||||
{
|
||||
u8 raw_sec, raw_min, raw_hour;
|
||||
u8 raw_sec, raw_min, raw_hour, raw_day, raw_weekday, raw_month, raw_year;
|
||||
|
||||
I2C_Start();
|
||||
I2C_SendByte(PCF8563_ADDR_WRITE);
|
||||
@@ -276,26 +276,51 @@ bit PCF8563_ReadTime(u8 *hour, u8 *min, u8 *sec)
|
||||
if (!I2C_WaitAck()) return 0;
|
||||
|
||||
raw_sec = I2C_ReadByte();
|
||||
I2C_SendAck(1); // 发送 ACK
|
||||
I2C_SendAck(1);
|
||||
|
||||
raw_min = I2C_ReadByte();
|
||||
I2C_SendAck(1); // 发送 ACK
|
||||
I2C_SendAck(1);
|
||||
|
||||
raw_hour = I2C_ReadByte();
|
||||
I2C_SendAck(1);
|
||||
|
||||
raw_day = I2C_ReadByte();
|
||||
I2C_SendAck(1);
|
||||
|
||||
raw_weekday = I2C_ReadByte(); // 星期寄存器不使用,芯片自身的星期在改日期后可能与实际不符
|
||||
I2C_SendAck(1);
|
||||
(void)raw_weekday;
|
||||
|
||||
raw_month = I2C_ReadByte();
|
||||
I2C_SendAck(1);
|
||||
|
||||
raw_year = I2C_ReadByte();
|
||||
I2C_SendAck(0); // 发送 NACK 结束连续读取
|
||||
|
||||
I2C_Stop();
|
||||
|
||||
// 解析 BCD 数据 (掩码屏蔽无效位)
|
||||
*sec = BCD2DEC(raw_sec & 0x7F);
|
||||
*min = BCD2DEC(raw_min & 0x7F);
|
||||
*hour = BCD2DEC(raw_hour & 0x3F);
|
||||
*sec = BCD2DEC(raw_sec & 0x7F);
|
||||
*min = BCD2DEC(raw_min & 0x7F);
|
||||
*hour = BCD2DEC(raw_hour & 0x3F);
|
||||
*day = BCD2DEC(raw_day & 0x3F);
|
||||
*month = BCD2DEC(raw_month & 0x1F); // 忽略 bit7 世纪位,固定按 2000~2099 处理
|
||||
*year = BCD2DEC(raw_year);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 将时间精准写入 PCF8563 RTC 芯片
|
||||
* @brief 从 PCF8563 读取当前时间 (兼容旧接口,只取时分秒,丢弃日期部分)
|
||||
*/
|
||||
bit PCF8563_ReadTime(u8 *hour, u8 *min, u8 *sec)
|
||||
{
|
||||
u8 day, month, year;
|
||||
return PCF8563_ReadDateTime(hour, min, sec, &day, &month, &year);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 将时间精准写入 PCF8563 RTC 芯片 (只写时分秒三个寄存器,不触碰日期寄存器)
|
||||
*/
|
||||
bit PCF8563_WriteTime(u8 hour, u8 min, u8 sec)
|
||||
{
|
||||
@@ -324,6 +349,44 @@ bit PCF8563_WriteTime(u8 hour, u8 min, u8 sec)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 将时间与日期一次性连续写入 PCF8563 RTC 芯片 (寄存器 0x02~0x08 共 7 字节连续写入)
|
||||
*/
|
||||
bit PCF8563_WriteDateTime(u8 hour, u8 min, u8 sec, u8 day, u8 month, u8 year, u8 weekday)
|
||||
{
|
||||
I2C_Start();
|
||||
I2C_SendByte(PCF8563_ADDR_WRITE);
|
||||
if (!I2C_WaitAck()) return 0;
|
||||
|
||||
I2C_SendByte(REG_VL_SECONDS);
|
||||
if (!I2C_WaitAck()) return 0;
|
||||
|
||||
I2C_SendByte(DEC2BCD(sec & 0x7F));
|
||||
if (!I2C_WaitAck()) return 0;
|
||||
|
||||
I2C_SendByte(DEC2BCD(min & 0x7F));
|
||||
if (!I2C_WaitAck()) return 0;
|
||||
|
||||
I2C_SendByte(DEC2BCD(hour & 0x3F));
|
||||
if (!I2C_WaitAck()) return 0;
|
||||
|
||||
I2C_SendByte(DEC2BCD(day & 0x3F));
|
||||
if (!I2C_WaitAck()) return 0;
|
||||
|
||||
I2C_SendByte(weekday & 0x07); // 星期不是 BCD,直接写 0~6
|
||||
if (!I2C_WaitAck()) return 0;
|
||||
|
||||
I2C_SendByte(DEC2BCD(month & 0x1F)); // bit7 世纪位固定写 0,不处理跨世纪
|
||||
if (!I2C_WaitAck()) return 0;
|
||||
|
||||
I2C_SendByte(DEC2BCD(year));
|
||||
if (!I2C_WaitAck()) return 0;
|
||||
|
||||
I2C_Stop();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bit PCF8563_TryReadDiagnostic(void)
|
||||
{
|
||||
u8 val = 0;
|
||||
|
||||
@@ -42,6 +42,31 @@ bit PCF8563_ReadTime(u8 *hour, u8 *min, u8 *sec);
|
||||
*/
|
||||
bit PCF8563_WriteTime(u8 hour, u8 min, u8 sec);
|
||||
|
||||
/**
|
||||
* @brief 从 PCF8563 芯片连续读取时间与日期 (时/分/秒/日/月/年)
|
||||
* @param hour 小时指针 (0~23)
|
||||
* @param min 分钟指针 (0~59)
|
||||
* @param sec 秒钟指针 (0~59)
|
||||
* @param day 日指针 (1~31)
|
||||
* @param month 月指针 (1~12)
|
||||
* @param year 年指针 (0~99,代表 2000~2099,不处理世纪位)
|
||||
* @return bit 1: 读取成功, 0: 通讯失败
|
||||
*/
|
||||
bit PCF8563_ReadDateTime(u8 *hour, u8 *min, u8 *sec, u8 *day, u8 *month, u8 *year);
|
||||
|
||||
/**
|
||||
* @brief 将指定的时间与日期一次性连续写入 PCF8563 芯片
|
||||
* @param hour 小时 (0~23)
|
||||
* @param min 分钟 (0~59)
|
||||
* @param sec 秒钟 (0~59)
|
||||
* @param day 日 (1~31)
|
||||
* @param month 月 (1~12)
|
||||
* @param year 年 (0~99,代表 2000~2099)
|
||||
* @param weekday 星期 (0~6,需与软件侧约定的星期数值一致,芯片本身不做校验)
|
||||
* @return bit 1: 写入成功, 0: 通讯失败
|
||||
*/
|
||||
bit PCF8563_WriteDateTime(u8 hour, u8 min, u8 sec, u8 day, u8 month, u8 year, u8 weekday);
|
||||
|
||||
/**
|
||||
* @brief I2C 总线器件扫描诊断函数
|
||||
* @details 逐个发送 I2C 写地址,检测总线上是否有响应的器件,并在串口打印发现的设备地址
|
||||
|
||||
Reference in New Issue
Block a user