Files
STM32F4-Base/Drivers/BSP/SD2506/sd2506.h

297 lines
11 KiB
C
Raw 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.
/*
* 模块名称SD2506API-G RTC 实时时钟驱动
* 模块功能SD2506API-G 高精度温补实时时钟模块 I2C 驱动,提供时间读写、
* 温度读取、电池电压检测、ID 读取等功能
* 适用平台STM32F407ZGT6I2C1 接口 (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 0x0FU /* 控制寄存器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 *p_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 *p_time);
/*
* 函数功能:读取芯片内部温度
* 入口参数temp - 温度输出指针 (整数部分, 有符号)
* 返回值0 - 成功,-2 - I2C 通信错误
* 限定条件sd2506_init() 已调用
* 函数说明:读取 16H 寄存器bit7 为符号位,范围 -40~+85
*/
int sd2506_get_temperature(int8_t *p_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 *p_voltage);
/*
* 函数功能:读取芯片 8 字节 ID
* 入口参数id - 8 字节输出缓冲区
* 返回值0 - 成功,-2 - I2C 通信错误
* 限定条件sd2506_init() 已调用
* 函数说明:读取 72H~79H 共 8 字节唯一 ID
*/
int sd2506_get_id(uint8_t p_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 *p_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 *p_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 *p_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 *p_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 */