Files
STM32F4-Base/Drivers/BSP/SD2506/sd2506.h
T
wandering1 0f7b5a87fb chore(编号): 存量编号全量转语义短语,门禁识别面与语料同批重打
登记簿、文档与代码注释里的存量字母加数字编号(N-x / S-x / T-x / E-x / A-x / 卡号)
一律改写为语义短语,净删 2,028 处引用;删除基线与待确认、并行分道方案、排期详述、
采集保护收尾 4 篇(内容已并入 docs/任务规划/README 与登记簿)。

门禁机器与三张账同批重打:check_ids.py 新增变更记录行豁免与第二根护栏
undecidable_total_ceiling;check_test_traceability.py 只加 stdout/stderr UTF-8
reconfigure(TC_RE 未动);check_cubemx_survival.py 的 --write 固定 newline=LF;
id_registry / id_aliases(+19 条 retired-to-phrase)/ id_known_backlog 重打。

test/ 56 个文件同步 TC 标签语义化,其中 18 个 TU 改了 CHECK / printf 里的标签文字,
是本批唯一改变构建产物的文件集合。

为什么合成一笔、不拆四笔(实测撞闸,非偏好):pre-commit 跑钩子前会 stash 未 staged
部分,拆开后中间提交必然是「新规则 + 旧语料」——实跑可判定 85.15% < 基线 86.00%、
不可判定 1,453 > 上限 1,166,编号门禁直接拦下。编号识别面与它描述的语料只能同码移动。

实跑基线(工作区全量):754 文件 / 8,230 处编号字面量 / 可判定 7,079 = 86.01%
(基线 86.0%,容差 0.1pp)/ 不可判定绝对数 1,151(上限 1,166)/ 校验 1-6 错误级 0 /
告警 = 悬空 2(App/algo/freq.c 的 S2,属 §4.4 同号不同义)+ 孤儿 50。

基线从 84.0 抬到 86.0 的理由见 docs/门禁说明/id-check.md §7.6:本批真删了 2,028 处
引用,可判定面随真实内容上升,不是把分母做小。同批新增排除 docs/硬件平台/ 语料,使
识别面少 264 处——芯片手册位号与网表料号不属编号空间(registry 有 excluded_paths_note)。

⚠ 余量只剩 0.11pp(约 10 处)与绝对数 15 处:把「可判定的引用」改成散文会立刻撞第二
根护栏。另遗留一项:id_aliases 里 retired 的 N / S / T / A 别名没有 scope(U1~U5 有),
今后有人新写一个 A-4,校验 3 不会响,只能靠人,建议下批补 scope。

固件不变证据:115 个 .c/.h 剥注释并归一字符串后与 HEAD 逐字节全等,残留代码差异 0;
App / Src / Drivers 的字符串字面量零改动。@build 0 错误 0 警告;40/40 主机套件、2,889
断言全通过;覆盖率 line 89.2% / func 92.6%;pre-commit 48 钩子 --all-files 全绿;
check_doc_links --all 通过(176 文档,章节引用无法判定 0);逐字节卫生核过:14 个带
BOM 文件与 HEAD 一致、0 个 CR、0 个 U+FFFD,字符串字面量纯 ASCII。

.cubemx_survival_baseline.json 的 watchdog-module 哈希 56bf27 变 2bb051 属合法:
Src/freertos.c 的 USER CODE 区内只有注释文字随编号改写,代码未变。

同批带上体积同码凭证与 RAM 台账行(@build 之后盖戳):RW_IRAM1 79,008 B / 60.3%,
RW_CCM 57,376 B / 87.9%,阈值 92%。
2026-10-26 12:28:14 +08:00

316 lines
13 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 读取等功能
* 适用平台: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 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):bit7=WRTC3 bit6=OSF bit5=INTAF bit4=INTDF bit3=BLF
* bit2=WRTC2 bit1=PMF bit0=RTCF(手册寄存器总表) */
#define SD2506_CTR1_INTAF (1U << 5) /* 报警中断标志 */
#define SD2506_CTR1_INTDF (1U << 4) /* 倒计时中断标志 */
#define SD2506_CTR1_BLF (1U << 3) /* 电池欠压标志 */
/* 控制寄存器 3 (11H) */
#define SD2506_CTR3_ARST (1U << 7) /* 自动复位使能(ARST=1 时读 CTR1 自动清 INTAF/INTDF/BLF) */
/* 控制寄存器 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) 位定义(手册 §4.8):
* Bit7=EN_Charge(充电允许,复位 0=禁止);
* Bit1=Charge1、Bit0=Charge0:00=2K / 01=10K / 10=5K / 11=断开(复位态) */
#define SD2506_CHARGE_EN (1U << 7) /* EN_Charge: 充电允许 (Bit7) */
#define SD2506_CHARGE_2K (0U) /* 2K 电阻: Charge1=0, Charge0=0 */
#define SD2506_CHARGE_10K (1U << 0) /* 10K 电阻: Charge1=0, Charge0=1 */
#define SD2506_CHARGE_5K (1U << 1) /* 5K 电阻: Charge1=1, Charge0=0 */
#define SD2506_CHARGE_DISCON (0x03U) /* 断开: Charge1=1, Charge0=1(复位态) */
#define SD2506_CHARGE_INIT_VALUE (0x82U) /* 上电目标值: EN_Charge|5K = 出厂 82H */
/* ======================== 写保护配置 ======================== */
/* 写允许窗口内写 0FH 的建议值: 0xFF(手册 L396:WRTC 位只能保持 1,
* 0FH 其余位均为标志位) */
#define SD2506_CTR1_WRITE_ON 0xFFU
/* 写禁止过渡时 0FH 的建议值: 0x7B(WRTC2/WRTC3=0、标志位 1;WRTC1 在
* CTR2 需另行清除;ARST 在 CTR3 与本寄存器无关) */
#define SD2506_CTR1_WRITE_OFF 0x7BU
/* ======================== 返回值定义 ========================
* 本模块**不再自带错误码**(2026-10-23):统一走 Drivers/BSP/bsp_err.h。
* 旧码映射 —— SD2506_OK → BSP_OK;SD2506_ERROR(参数类)→ BSP_ERR_PARAM;
* SD2506_I2C_ERROR → BSP_ERR_IO,其中 I2C 超时刻意单独归成 **BSP_ERR_TIMEOUT
* (可重试)**:旧码把"总线上没人应答"和"超时"混成一个 -2,调用方没法规避。
* 三处旧宏已**删除而不是留别名**——留着就还能被新代码继续用,等于把迁移洗掉。
*/
#include "bsp_err.h"
/* ======================== 超时时间 ======================== */
#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
* 入口参数:无
* 返回值:BSP_OK - 成功;BSP_ERR_IO - I2C 失败或回读校验不符;BSP_ERR_TIMEOUT - I2C 超时(可重试)
* 限定条件:CubeMX 已完成 I2C1 初始化
* 函数说明:1. 读取芯片 ID 验证通信
* 2. 充电寄存器 18H 回读校验(出厂 82H 非易失),值漂移时经写允许
* 窗口重置并回读验证
* 3. 上电即写禁止态(WRTC 全 0),无需再写 0FH
*/
bsp_err_t sd2506_init(void);
/*
* 函数功能:设置 RTC 时间日期
* 入口参数:time - 时间结构体指针,包含要设置的时间
* 返回值:BSP_OK - 成功;BSP_ERR_IO - I2C 通信失败;BSP_ERR_TIMEOUT - I2C 超时(可重试)
* 限定条件:sd2506_init() 已调用
* 函数说明:1. 先开写保护
* 2. 一次性写入 7 字节时间数据 (00H~06H)
* 3. 关闭写保护
* 注意:不可单独写某一个时间寄存器
*/
bsp_err_t sd2506_set_time(const sd2506_time_t *p_time);
/*
* 函数功能:读取 RTC 时间日期
* 入口参数:time - 时间结构体指针,用于存储读取结果
* 返回值:BSP_OK - 成功;BSP_ERR_IO - I2C 通信失败;BSP_ERR_TIMEOUT - I2C 超时(可重试)
* 限定条件:sd2506_init() 已调用
* 函数说明:1. 一次读取 7 字节时间数据 (00H~06H)
* 2. BCD 转十进制
* 3. 屏蔽小时 bit7 (12/24标志位)
*/
bsp_err_t sd2506_get_time(sd2506_time_t *p_time);
/*
* 函数功能:读取芯片内部温度
* 入口参数:temp - 温度输出指针 (整数部分, 有符号)
* 返回值:BSP_OK - 成功;BSP_ERR_IO - I2C 通信失败;BSP_ERR_TIMEOUT - I2C 超时(可重试)
* 限定条件:sd2506_init() 已调用
* 函数说明:读取 16H 寄存器,bit7 为符号位,范围 -40~+85
*/
bsp_err_t sd2506_get_temperature(int8_t *p_temp);
/*
* 函数功能:读取电池电压 (毫伏)
* 入口参数:voltage - 电压输出指针 (单位: mV)
* 返回值:BSP_OK - 成功;BSP_ERR_IO - I2C 通信失败;BSP_ERR_TIMEOUT - I2C 超时(可重试)
* 限定条件:sd2506_init() 已调用
* 函数说明:1. 读取 1AH bit7 (BAT8_VAL) 和 1BH (BAT_VL)
* 2. 组合 9 位数据得到电压值 (如 0x135 = 309 = 3.09V)
*/
bsp_err_t sd2506_get_battery_voltage(uint16_t *p_voltage);
/*
* 函数功能:读取芯片 8 字节 ID
* 入口参数:id - 8 字节输出缓冲区
* 返回值:BSP_OK - 成功;BSP_ERR_IO - I2C 通信失败;BSP_ERR_TIMEOUT - I2C 超时(可重试)
* 限定条件:sd2506_init() 已调用
* 函数说明:读取 72H~79H 共 8 字节唯一 ID
*/
bsp_err_t sd2506_get_id(uint8_t p_id[8]);
/*
* 函数功能:读取用户 SRAM 数据
* 入口参数:addr - SRAM 起始地址 (0~69)
* buf - 数据输出缓冲区
* len - 读取长度 (1~70)
* 返回值:BSP_OK - 成功;BSP_ERR_PARAM - 参数错误;BSP_ERR_IO - I2C 通信失败;
* BSP_ERR_TIMEOUT - I2C 超时(可重试)
* 限定条件:sd2506_init() 已调用
* 函数说明:SRAM 地址范围 0~69,对应寄存器 2CH~71H
*/
bsp_err_t sd2506_read_sram(uint8_t addr, uint8_t *p_buf, uint8_t len);
/*
* 函数功能:写入用户 SRAM 数据
* 入口参数:addr - SRAM 起始地址 (0~69)
* buf - 数据输入缓冲区
* len - 写入长度 (1~70)
* 返回值:BSP_OK - 成功;BSP_ERR_PARAM - 参数错误;BSP_ERR_IO - I2C 通信失败;
* BSP_ERR_TIMEOUT - I2C 超时(可重试)
* 限定条件:sd2506_init() 已调用
* 函数说明:SRAM 地址范围 0~69,对应寄存器 2CH~71H
* SRAM 无需开写保护即可写入
*/
bsp_err_t sd2506_write_sram(uint8_t addr, const uint8_t *p_buf, uint8_t len);
/*
* 函数功能:设置报警中断
* 入口参数:time - 报警时间结构体
* mask - 报警匹配掩码 (SD2506_AL_EN_xxx 位或组合)
* 返回值:BSP_OK - 成功;BSP_ERR_IO - I2C 通信失败;BSP_ERR_TIMEOUT - I2C 超时(可重试)
* 限定条件:sd2506_init() 已调用
* 函数说明:1. 开写保护
* 2. 写入报警寄存器 (07H~0EH)
* 3. 使能报警中断 INTAE
* 4. 关写保护
*/
bsp_err_t sd2506_set_alarm(const sd2506_time_t *p_time, uint8_t mask);
/*
* 函数功能:清除报警中断标志 INTAF
* 入口参数:无
* 返回值:BSP_OK - 成功;BSP_ERR_IO - I2C 通信失败;BSP_ERR_TIMEOUT - I2C 超时(可重试)
* 限定条件:sd2506_init() 已调用
* 函数说明:ARST(CTR3 bit7) 未启用,读 CTR1 不清 INTAF;本函数经写允许窗口
* 手动写 CTR1 将 INTAF 置 0
*/
bsp_err_t sd2506_clear_alarm(void);
/*
* 函数功能:读取当前 0FH 控制寄存器1 状态
* 入口参数:val - 输出值指针
* 返回值:BSP_OK - 成功;BSP_ERR_IO - I2C 通信失败;BSP_ERR_TIMEOUT - I2C 超时(可重试)
*/
bsp_err_t 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 */