/* * 模块名称:SD2506API-G RTC 实时时钟驱动 * 模块功能:SD2506API-G 高精度温补实时时钟模块 I2C 驱动,提供时间读写、 * 温度读取、电池电压检测、ID 读取等功能 * 适用平台:STM32F407ZGT6,I2C1 接口 (PB6-SCL, PB7-SDA) * 作者:王建锋 * 创建日期:2026-07-17 * 修改记录: * 2026-07-17 王建锋 创建初始版本,参考 SD2506API-G Ver2.0 手册 */ #ifndef __SD2506_H #define __SD2506_H #ifdef __cplusplus extern "C" { #endif #include "main.h" /* ======================== I2C 地址 ======================== */ /* * SD2506API-G 7位器件地址: 0x32 * HAL库使用8位地址: 写 0x64, 读 0x65 */ #define SD2506_I2C_ADDR 0x32U #define SD2506_I2C_ADDR_WRITE 0x64U #define SD2506_I2C_ADDR_READ 0x65U /* ======================== 寄存器地址定义 ======================== */ /* 实时时钟寄存器 (00H~06H) */ #define SD2506_REG_SEC 0x00U /* 秒 00~59 BCD */ #define SD2506_REG_MIN 0x01U /* 分 00~59 BCD */ #define SD2506_REG_HOUR 0x02U /* 时 00~23 BCD, bit7=12/24 */ #define SD2506_REG_WEEK 0x03U /* 星期 00~06 BCD */ #define SD2506_REG_DAY 0x04U /* 日 01~31 BCD */ #define SD2506_REG_MON 0x05U /* 月 01~12 BCD */ #define SD2506_REG_YEAR 0x06U /* 年 00~99 BCD */ /* 报警寄存器 (07H~0EH) */ #define SD2506_REG_AL_SEC 0x07U /* 秒报警 */ #define SD2506_REG_AL_MIN 0x08U /* 分报警 */ #define SD2506_REG_AL_HOUR 0x09U /* 时报警 */ #define SD2506_REG_AL_WEEK 0x0AU /* 星期报警 */ #define SD2506_REG_AL_DAY 0x0BU /* 日报警 */ #define SD2506_REG_AL_MON 0x0CU /* 月报警 */ #define SD2506_REG_AL_YEAR 0x0DU /* 年报警 */ #define SD2506_REG_AL_EN 0x0EU /* 报警允许寄存器 */ /* 控制寄存器 */ #define SD2506_REG_CTR1 0x0FH /* 控制寄存器1 */ #define SD2506_REG_CTR2 0x10U /* 控制寄存器2 */ #define SD2506_REG_CTR3 0x11U /* 控制寄存器3 */ /* 倒计时寄存器 (13H~15H) */ #define SD2506_REG_CNT0 0x13U /* 倒计时字节0 (LSB) */ #define SD2506_REG_CNT1 0x14U /* 倒计时字节1 */ #define SD2506_REG_CNT2 0x15U /* 倒计时字节2 (MSB) */ /* 温度寄存器 */ #define SD2506_REG_TEMP 0x16U /* 温度值 (bit7=符号位) */ #define SD2506_REG_AGTC 0x17U /* IIC控制寄存器 AGTC */ #define SD2506_REG_CHARGE 0x18U /* 充电选择寄存器 */ #define SD2506_REG_CTR4 0x19U /* 扩展控制寄存器 CTR4 */ #define SD2506_REG_CTR5 0x1AU /* 控制寄存器 CTR5 */ #define SD2506_REG_BAT_VAL 0x1BU /* 电池电压低8位 */ /* 温度报警及历史 */ #define SD2506_REG_TEMP_AL 0x1CU /* 低温报警温度值 */ #define SD2506_REG_TEMP_AH 0x1DU /* 高温报警温度值 */ #define SD2506_REG_TEMP_HIS_L 0x1EU /* 历史低温 */ #define SD2506_REG_TEMP_HIS_H 0x1FU /* 历史高温 */ /* 用户 SRAM (2CH~71H) */ #define SD2506_REG_SRAM_START 0x2CU #define SD2506_REG_SRAM_END 0x71U #define SD2506_SRAM_SIZE 70U /* 70字节 */ /* ID 码 (72H~79H) */ #define SD2506_REG_ID_START 0x72U #define SD2506_REG_ID_END 0x79U #define SD2506_ID_SIZE 8U /* 8字节 */ /* ======================== 控制位定义 ======================== */ /* 控制寄存器 1 (0FH) */ #define SD2506_CTR1_ARST (1U << 5) /* 自动复位使能 */ #define SD2506_CTR1_INTAF (1U << 3) /* 报警中断标志 */ #define SD2506_CTR1_INTDF (1U << 2) /* 倒计时中断标志 */ #define SD2506_CTR1_BLF (1U << 0) /* 电池欠压标志 */ /* 控制寄存器 2 (10H) */ #define SD2506_CTR2_INTAE (1U << 5) /* 报警中断允许 */ #define SD2506_CTR2_INTFE (1U << 4) /* 频率中断允许 */ #define SD2506_CTR2_INTDE (1U << 3) /* 倒计时中断允许 */ #define SD2506_CTR2_IM (1U << 2) /* 中断模式: 0=单事件, 1=周期 */ #define SD2506_CTR2_INTS1 (1U << 1) /* INT输出选择 bit1 */ #define SD2506_CTR2_INTS0 (1U << 0) /* INT输出选择 bit0 */ /* 报警允许寄存器 (0EH) */ #define SD2506_AL_EN_EAY (1U << 6) /* 年报警允许 */ #define SD2506_AL_EN_EAMO (1U << 5) /* 月报警允许 */ #define SD2506_AL_EN_EAD (1U << 4) /* 日报警允许 */ #define SD2506_AL_EN_EAW (1U << 3) /* 星期报警允许 */ #define SD2506_AL_EN_EAH (1U << 2) /* 时报警允许 */ #define SD2506_AL_EN_EAMN (1U << 1) /* 分报警允许 */ #define SD2506_AL_EN_EAS (1U << 0) /* 秒报警允许 */ /* 24/12小时制位 */ #define SD2506_HOUR_24 (1U << 7) /* bit7=1 表示24小时制 */ /* ======================== 充电配置 ======================== */ /* 充电寄存器 (18H) 建议上电写入值: 0x82 (开启充电, 断开) */ #define SD2506_CHARGE_EN (1U << 7) /* 充电允许位 */ #define SD2506_CHARGE_2K (0U << 0) /* 2K电阻 */ #define SD2506_CHARGE_5K (1U << 0) /* 5K电阻 */ /* ======================== 写保护配置 ======================== */ /* 写允许时 0FH 寄存器建议值: 0xFF (WRTC1=1, WRTC2=1, WRTC3=1) */ #define SD2506_CTR1_WRITE_ON 0xFFU /* 写禁止时 0FH 寄存器建议值: 0x7B (WRTC1=0, WRTC2=0, WRTC3=0, ARST=1) */ #define SD2506_CTR1_WRITE_OFF 0x7BU /* ======================== 返回值定义 ======================== */ #define SD2506_OK 0 #define SD2506_ERROR -1 #define SD2506_I2C_ERROR -2 /* ======================== 超时时间 ======================== */ #define SD2506_I2C_TIMEOUT_MS 100 /* ======================== 数据结构 ======================== */ /* * RTC 时间日期结构体 * year: 2000~2099 * month: 1~12 * day: 1~31 * hour: 0~23 (24小时制) * minute: 0~59 * second: 0~59 * week: 0~6 (0=星期天, 1=星期一, ..., 6=星期六) */ typedef struct { uint16_t year; uint8_t month; uint8_t day; uint8_t hour; uint8_t minute; uint8_t second; uint8_t week; } sd2506_time_t; /* ======================== 函数声明 ======================== */ /* * 函数功能:初始化 SD2506API-G RTC * 入口参数:无 * 返回值:0 - 成功,-2 - I2C 通信错误 * 限定条件:CubeMX 已完成 I2C1 初始化 * 函数说明:1. 读取芯片 ID 验证通信 * 2. 上电重置充电寄存器 18H=82H * 3. 配置 24 小时制、开自动复位 */ int sd2506_init(void); /* * 函数功能:设置 RTC 时间日期 * 入口参数:time - 时间结构体指针,包含要设置的时间 * 返回值:0 - 成功,-2 - I2C 通信错误 * 限定条件:sd2506_init() 已调用 * 函数说明:1. 先开写保护 * 2. 一次性写入 7 字节时间数据 (00H~06H) * 3. 关闭写保护 * 注意:不可单独写某一个时间寄存器 */ int sd2506_set_time(const sd2506_time_t *time); /* * 函数功能:读取 RTC 时间日期 * 入口参数:time - 时间结构体指针,用于存储读取结果 * 返回值:0 - 成功,-2 - I2C 通信错误 * 限定条件:sd2506_init() 已调用 * 函数说明:1. 一次读取 7 字节时间数据 (00H~06H) * 2. BCD 转十进制 * 3. 屏蔽小时 bit7 (12/24标志位) */ int sd2506_get_time(sd2506_time_t *time); /* * 函数功能:读取芯片内部温度 * 入口参数:temp - 温度输出指针 (整数部分, 有符号) * 返回值:0 - 成功,-2 - I2C 通信错误 * 限定条件:sd2506_init() 已调用 * 函数说明:读取 16H 寄存器,bit7 为符号位,范围 -40~+85 */ int sd2506_get_temperature(int8_t *temp); /* * 函数功能:读取电池电压 (毫伏) * 入口参数:voltage - 电压输出指针 (单位: mV) * 返回值:0 - 成功,-2 - I2C 通信错误 * 限定条件:sd2506_init() 已调用 * 函数说明:1. 读取 1AH bit7 (BAT8_VAL) 和 1BH (BAT_VL) * 2. 组合 9 位数据得到电压值 (如 0x135 = 309 = 3.09V) */ int sd2506_get_battery_voltage(uint16_t *voltage); /* * 函数功能:读取芯片 8 字节 ID * 入口参数:id - 8 字节输出缓冲区 * 返回值:0 - 成功,-2 - I2C 通信错误 * 限定条件:sd2506_init() 已调用 * 函数说明:读取 72H~79H 共 8 字节唯一 ID */ int sd2506_get_id(uint8_t id[8]); /* * 函数功能:读取用户 SRAM 数据 * 入口参数:addr - SRAM 起始地址 (0~69) * buf - 数据输出缓冲区 * len - 读取长度 (1~70) * 返回值:0 - 成功,-2 - I2C 通信错误,-1 - 参数错误 * 限定条件:sd2506_init() 已调用 * 函数说明:SRAM 地址范围 0~69,对应寄存器 2CH~71H */ int sd2506_read_sram(uint8_t addr, uint8_t *buf, uint8_t len); /* * 函数功能:写入用户 SRAM 数据 * 入口参数:addr - SRAM 起始地址 (0~69) * buf - 数据输入缓冲区 * len - 写入长度 (1~70) * 返回值:0 - 成功,-2 - I2C 通信错误,-1 - 参数错误 * 限定条件:sd2506_init() 已调用 * 函数说明:SRAM 地址范围 0~69,对应寄存器 2CH~71H * SRAM 无需开写保护即可写入 */ int sd2506_write_sram(uint8_t addr, const uint8_t *buf, uint8_t len); /* * 函数功能:设置报警中断 * 入口参数:time - 报警时间结构体 * mask - 报警匹配掩码 (SD2506_AL_EN_xxx 位或组合) * 返回值:0 - 成功,-2 - I2C 通信错误 * 限定条件:sd2506_init() 已调用 * 函数说明:1. 开写保护 * 2. 写入报警寄存器 (07H~0EH) * 3. 使能报警中断 INTAE * 4. 关写保护 */ int sd2506_set_alarm(const sd2506_time_t *time, uint8_t mask); /* * 函数功能:清除报警中断标志 * 入口参数:无 * 返回值:0 - 成功,-2 - I2C 通信错误 * 限定条件:sd2506_init() 已调用 * 函数说明:读取 CTR1 自动清除 INTAF (ARST=1 时) */ int sd2506_clear_alarm(void); /* * 函数功能:读取当前 0FH 控制寄存器1 状态 * 入口参数:val - 输出值指针 * 返回值:0 - 成功,-2 - I2C 通信错误 */ int sd2506_read_ctr1(uint8_t *val); /* * 函数功能:BCD 码转十进制 * 入口参数:bcd - BCD 码值 * 返回值:十进制值 * 函数说明:内部辅助函数 */ uint8_t sd2506_bcd_to_dec(uint8_t bcd); /* * 函数功能:十进制转 BCD 码 * 入口参数:dec - 十进制值 * 返回值:BCD 码值 * 函数说明:内部辅助函数 */ uint8_t sd2506_dec_to_bcd(uint8_t dec); #ifdef __cplusplus } #endif #endif /* __SD2506_H */