修复多连接的问题

This commit is contained in:
2026-07-19 15:27:49 +08:00
parent 9ed4c22022
commit e06d849007
38 changed files with 2475 additions and 1953 deletions

View File

@@ -1,39 +1,43 @@
/*
* 模块名称SD2506API-G RTC 实时时钟驱动
* 模块功能SD2506API-G 高精度温补实时时钟模I2C 驱动
* 模块功能SD2506API-G 高精度温补实时时钟模<EFBFBD>?I2C 驱动
* 适用平台STM32F407ZGT6I2C1 接口 (PB6-SCL, PB7-SDA)
* 作者:王建
* 创建日期2026-07-17
* 修改记录:
* 2026-07-17 王建锋 创建初始版本,参考 SD2506API-G Ver2.0 手册
* 作者:王建<EFBFBD>? * 创建日期<E697A5>?026-07-17
* 修改记录<EFBFBD>? * 2026-07-17 王建<E78E8B>? 创建初始版本<EFBC8C>?SD2506API-G Ver2.0 手册
*/
#include <string.h>
#include "sd2506.h"
#include "i2c.h"
#include <string.h>
extern I2C_HandleTypeDef hi2c1;
/* ======================== 内部辅助函数 ======================== */
uint8_t sd2506_bcd_to_dec(uint8_t bcd)
{
/*
* 函数功能BCD 码转十进<E58D81>? * 入口参数bcd - BCD 编码<E7BC96>? uint8_t 0x00 - 0x99
* <20>?<3F>?值十进制数<E588B6>? * 限定条件:输入为合法 BCD <20>? * 函数说明:高 4 位为十位,低 4 位为个位
*/
uint8_t sd2506_bcd_to_dec(uint8_t bcd) {
return ((bcd >> 4) * 10) + (bcd & 0x0FU);
}
uint8_t sd2506_dec_to_bcd(uint8_t dec)
{
/*
* 函数功能十进制<E8BF9B>?BCD <20>? * 入口参数dec - 十进制数<E588B6>? uint8_t 0 - 99
* <20>?<3F>?值BCD 编码<E7BC96>? * 限定条件:输入值在 0 - 99 范围<E88C83>? * 函数说明:十位存入高 4 位个位存入<E5AD98>?4 <20>? */
uint8_t sd2506_dec_to_bcd(uint8_t dec) {
return ((dec / 10) << 4) | (dec % 10);
}
/*
* 写单字节寄存器
* reg: 寄存器地址 (00H~79H)
* val: 写入
* 返回: 0=成功, -2=I2C错误
* 函数功能:写单字节寄存器
* 入口参数:reg - 寄存器地址 uint8_t 00H - 79H
* val - 写入<EFBFBD>? uint8_t 0x00 - 0xFF
* <EFBFBD>?<3F>?值0 - 成功<E68890>?2 - I2C 错误
* 限定条件I2C 外设已初始化
* 函数说明:通过 I2C 向指定地址写入 1 字节
*/
static int sd2506_write_reg(uint8_t reg, uint8_t val)
{
static int sd2506_write_reg(uint8_t reg, uint8_t val) {
if (HAL_I2C_Mem_Write(&hi2c1, SD2506_I2C_ADDR_WRITE, reg,
I2C_MEMADD_SIZE_8BIT, &val, 1,
SD2506_I2C_TIMEOUT_MS) != HAL_OK) {
@@ -43,15 +47,15 @@ static int sd2506_write_reg(uint8_t reg, uint8_t val)
}
/*
* 读单字节寄存器
* reg: 寄存器地址 (00H~79H)
* val: 读取值指
* 返回: 0=成功, -2=I2C错误
* 函数功能:读单字节寄存器
* 入口参数:reg - 寄存器地址 uint8_t 00H - 79H
* val - 读取值指<EFBFBD>? uint8_t*
* <EFBFBD>?<3F>?值0 - 成功<E68890>?2 - I2C 错误
* 限定条件I2C 外设已初始化val 为非空指<E7A9BA>? * 函数说明:通过 I2C 从指定地址读取 1 字节
*/
static int sd2506_read_reg(uint8_t reg, uint8_t *val)
{
static int sd2506_read_reg(uint8_t reg, uint8_t *p_val) {
if (HAL_I2C_Mem_Read(&hi2c1, SD2506_I2C_ADDR_READ, reg,
I2C_MEMADD_SIZE_8BIT, val, 1,
I2C_MEMADD_SIZE_8BIT, p_val, 1,
SD2506_I2C_TIMEOUT_MS) != HAL_OK) {
return SD2506_I2C_ERROR;
}
@@ -59,16 +63,16 @@ static int sd2506_read_reg(uint8_t reg, uint8_t *val)
}
/*
* 写多字节寄存器 (从 reg 开始连续写入 len 字节)
* reg: 起始寄存器地址
* data: 数据缓冲区
* len: 数据长度
* 返回: 0=成功, -2=I2C错误
* 函数功能:写多字节寄存器
* 入口参数reg - 起始寄存器地址 uint8_t 00H - 79H
* data - 数据缓冲区<EFBFBD>? uint8_t*
* len - 数据长度 uint8_t 1 - N
* <EFBFBD>?<3F>?值0 - 成功<E68890>?2 - I2C 错误
* 限定条件I2C 外设已初始化data 为非空指<E7A9BA>? * 函数说明:从 reg 开始连续写<E7BBAD>?len 字节
*/
static int sd2506_write_regs(uint8_t reg, const uint8_t *data, uint8_t len)
{
static int sd2506_write_regs(uint8_t reg, const uint8_t *p_data, uint8_t len) {
if (HAL_I2C_Mem_Write(&hi2c1, SD2506_I2C_ADDR_WRITE, reg,
I2C_MEMADD_SIZE_8BIT, (uint8_t *)data, len,
I2C_MEMADD_SIZE_8BIT, (uint8_t *)p_data, len,
SD2506_I2C_TIMEOUT_MS) != HAL_OK) {
return SD2506_I2C_ERROR;
}
@@ -76,16 +80,16 @@ static int sd2506_write_regs(uint8_t reg, const uint8_t *data, uint8_t len)
}
/*
* 读多字节寄存器 (从 reg 开始连续读取 len 字节)
* reg: 起始寄存器地址
* data: 数据缓冲区
* len: 数据长度
* 返回: 0=成功, -2=I2C错误
* 函数功能:读多字节寄存器
* 入口参数reg - 起始寄存器地址 uint8_t 00H - 79H
* data - 数据缓冲区<EFBFBD>? uint8_t*
* len - 数据长度 uint8_t 1 - N
* <EFBFBD>?<3F>?值0 - 成功<E68890>?2 - I2C 错误
* 限定条件I2C 外设已初始化data 为非空指<E7A9BA>? * 函数说明:从 reg 开始连续读<E7BBAD>?len 字节
*/
static int sd2506_read_regs(uint8_t reg, uint8_t *data, uint8_t len)
{
static int sd2506_read_regs(uint8_t reg, uint8_t *p_data, uint8_t len) {
if (HAL_I2C_Mem_Read(&hi2c1, SD2506_I2C_ADDR_READ, reg,
I2C_MEMADD_SIZE_8BIT, data, len,
I2C_MEMADD_SIZE_8BIT, p_data, len,
SD2506_I2C_TIMEOUT_MS) != HAL_OK) {
return SD2506_I2C_ERROR;
}
@@ -93,14 +97,16 @@ static int sd2506_read_regs(uint8_t reg, uint8_t *data, uint8_t len)
}
/*
* 开启写保护 (允许写00H~71H 寄存器)
* 顺序: 先写 WRTC1=1, 再写 WRTC2=1 + WRTC3=1
* 函数功能:开启写保护允许写<EFBFBD>?00H~71H 寄存器
* 入口参数:无
* 返回值0 - 成功<E68890>?2 - I2C 错误
* 限定条件I2C 外设已初始化
* 函数说明:顺序:先写 WRTC1=1, 再写 WRTC2=1 + WRTC3=1
*/
static int sd2506_write_enable(void)
{
int ret;
static int sd2506_write_enable(void) {
int ret = 0;
/* 先置 WRTC1=1 (bit6=1), 其它位参考手册: 0x84 */
/* 先置 WRTC1=1 (bit6=1), 其它位参考手<EFBFBD>? 0x84 */
ret = sd2506_write_reg(SD2506_REG_CTR1, 0x84U);
if (ret != SD2506_OK) return ret;
@@ -112,12 +118,14 @@ static int sd2506_write_enable(void)
}
/*
* 关闭写保护 (禁止写00H~71H 寄存器)
* 顺序: 先写 WRTC2=0 + WRTC3=0, 再写 WRTC1=0
* 函数功能:关闭写保护禁止写<EFBFBD>?00H~71H 寄存器
* 入口参数:无
* 返回值0 - 成功<E68890>?2 - I2C 错误
* 限定条件I2C 外设已初始化
* 函数说明:顺序:先写 WRTC2=0 + WRTC3=0, 再写 WRTC1=0
*/
static int sd2506_write_disable(void)
{
int ret;
static int sd2506_write_disable(void) {
int ret = 0;
/* 先清 WRTC2=0, WRTC3=0: 0x00 */
ret = sd2506_write_reg(SD2506_REG_CTR2, 0x00U);
@@ -132,28 +140,36 @@ static int sd2506_write_disable(void)
/* ======================== 公共 API 实现 ======================== */
int sd2506_init(void)
{
int ret;
uint8_t id[8];
/*
* 函数功能:初始化 SD2506API-G RTC
* 入口参数:无
* 返回值0 - 成功<E68890>?2 - I2C 错误
* 限定条件CubeMX 已完<E5B7B2>?I2C1 初始<E5889D>?
* 函数说明<E8AFB4>?. 读取芯片 ID 验证通信
* 2. 上电重置充电寄存<E5AF84>?18H=82H
* 3. 配置 24 小时制、开自动复位
*/
int sd2506_init(void) {
int ret = 0;
uint8_t a_id[8] = {0};
/* 验证 I2C 通信: 尝试读取 8 字节 ID */
ret = sd2506_read_regs(SD2506_REG_ID_START, id, SD2506_ID_SIZE);
ret = sd2506_read_regs(SD2506_REG_ID_START, a_id, SD2506_ID_SIZE);
if (ret != SD2506_OK) {
return ret;
}
/* 上电重置充电寄存18H = 82H (开启充电, 5K电阻)
* 手册强烈建议每次上电时重置此*/
/* 上电重置充电寄存<EFBFBD>?18H = 82H (开启充<EFBFBD>? 5K电阻)
* 手册强烈建议每次上电时重置此<EFBFBD>?*/
ret = sd2506_write_reg(SD2506_REG_CHARGE, 0x82U);
if (ret != SD2506_OK) {
return ret;
}
/* 配置: 24小时制, 自动复位使能
* 0FH = 0x20 (bit5=ARST=1, 其它标志位清零)
* 写入时需注意: 写允许状态下 0FH WRTC 位必须为1
* 此处直接写入 0x20 即可 (ARST=1, WRTC 位) */
/* 配置: 24小时<EFBFBD>? 自动复位使能
* 0FH = 0x20 (bit5=ARST=1, 其它标志位清<EFBFBD>?
* 写入时需注意: 写允许状态下 0FH <EFBFBD>?WRTC 位必须为1
* 此处直接写入 0x20 即可 (ARST=1, <EFBFBD>?WRTC <EFBFBD>? */
ret = sd2506_write_reg(SD2506_REG_CTR1, SD2506_CTR1_WRITE_OFF);
if (ret != SD2506_OK) {
return ret;
@@ -162,73 +178,91 @@ int sd2506_init(void)
return SD2506_OK;
}
int sd2506_set_time(const sd2506_time_t *time)
{
int ret;
uint8_t buf[7];
/*
* 函数功能<EFBC9A>?RTC 时间日期
* 入口参数p_time - 时间结构体指针,包含要设置的时间
* 返回值0 - 成功<E68890>?2 - I2C 错误
* 限定条件sd2506_init() 已调<E5B7B2>?
* 函数说明<E8AFB4>?. 先开写保<E58699>?
* 2. 一次性写<E680A7>?7 字节时间数据 (00H~06H)
* 3. 关闭写保<E58699>?
*/
int sd2506_set_time(const sd2506_time_t *p_time) {
int ret = 0;
uint8_t buf[7] = {0};
if (time == NULL) {
if (p_time == NULL) {
return SD2506_ERROR;
}
/* 组装 7 字节时间数据 (BCD 码) */
buf[0] = sd2506_dec_to_bcd(time->second); /* 00H: */
buf[1] = sd2506_dec_to_bcd(time->minute); /* 01H: */
buf[2] = sd2506_dec_to_bcd(time->hour) | 0x80U; /* 02H: (bit7=1, 24小时制) */
buf[3] = sd2506_dec_to_bcd(time->week); /* 03H: 星期 */
buf[4] = sd2506_dec_to_bcd(time->day); /* 04H: */
buf[5] = sd2506_dec_to_bcd(time->month); /* 05H: */
buf[6] = sd2506_dec_to_bcd(time->year - 2000U); /* 06H: */
/* 组装 7 字节时间数据 (BCD <EFBFBD>? */
buf[0] = sd2506_dec_to_bcd(p_time->second); /* 00H: <EFBFBD>?*/
buf[1] = sd2506_dec_to_bcd(p_time->minute); /* 01H: <EFBFBD>?*/
buf[2] = sd2506_dec_to_bcd(p_time->hour) | 0x80U; /* 02H: <EFBFBD>?(bit7=1, 24小时<EFBFBD>? */
buf[3] = sd2506_dec_to_bcd(p_time->week); /* 03H: 星期 */
buf[4] = sd2506_dec_to_bcd(p_time->day); /* 04H: <EFBFBD>?*/
buf[5] = sd2506_dec_to_bcd(p_time->month); /* 05H: <EFBFBD>?*/
buf[6] = sd2506_dec_to_bcd(p_time->year - 2000U); /* 06H: <EFBFBD>?*/
/* 开启写保护 */
ret = sd2506_write_enable();
if (ret != SD2506_OK) return ret;
/* 一次性写7 字节时间数据 (00H~06H)
* 手册要求: 不可单独写某一个时间寄存器,否则可能引起错误进*/
/* 一次性写<EFBFBD>?7 字节时间数据 (00H~06H)
* 手册要求: 不可单独写某一个时间寄存器,否则可能引起错误进<EFBFBD>?*/
ret = sd2506_write_regs(SD2506_REG_SEC, buf, 7);
if (ret != SD2506_OK) return ret;
/* 关闭写保*/
/* 关闭写保<EFBFBD>?*/
ret = sd2506_write_disable();
if (ret != SD2506_OK) return ret;
return SD2506_OK;
}
int sd2506_get_time(sd2506_time_t *time)
{
int ret;
uint8_t buf[7];
/*
* function: read RTC time
* param: p_time - output time struct
* return: 0=OK, -2=I2C error
* note: sd2506_init() must be called first
*/
int sd2506_get_time(sd2506_time_t *p_time) {
int ret = 0;
uint8_t buf[7] = {0};
if (time == NULL) {
if (p_time == NULL) {
return SD2506_ERROR;
}
/* 一次读7 字节时间数据 (00H~06H)
* 手册说明: 读取时所有实时数据被锁存,避免错*/
/* 一次读<EFBFBD>?7 字节时间数据 (00H~06H)
* 手册说明: 读取时所有实时数据被锁存,避免错<EFBFBD>?*/
ret = sd2506_read_regs(SD2506_REG_SEC, buf, 7);
if (ret != SD2506_OK) {
return ret;
}
time->second = sd2506_bcd_to_dec(buf[0] & 0x7FU); /* 00H: */
time->minute = sd2506_bcd_to_dec(buf[1] & 0x7FU); /* 01H: */
time->hour = sd2506_bcd_to_dec(buf[2] & 0x7FU); /* 02H: 屏蔽 bit7 (12/24标志) */
time->week = sd2506_bcd_to_dec(buf[3] & 0x07U); /* 03H: 星期 */
time->day = sd2506_bcd_to_dec(buf[4] & 0x3FU); /* 04H: */
time->month = sd2506_bcd_to_dec(buf[5] & 0x1FU); /* 05H: */
time->year = sd2506_bcd_to_dec(buf[6]) + 2000U; /* 06H: */
p_time->second = sd2506_bcd_to_dec(buf[0] & 0x7FU); /* 00H: <EFBFBD>?*/
p_time->minute = sd2506_bcd_to_dec(buf[1] & 0x7FU); /* 01H: <EFBFBD>?*/
p_time->hour = sd2506_bcd_to_dec(buf[2] & 0x7FU); /* 02H: 屏蔽 bit7 (12/24标志) */
p_time->week = sd2506_bcd_to_dec(buf[3] & 0x07U); /* 03H: 星期 */
p_time->day = sd2506_bcd_to_dec(buf[4] & 0x3FU); /* 04H: <EFBFBD>?*/
p_time->month = sd2506_bcd_to_dec(buf[5] & 0x1FU); /* 05H: <EFBFBD>?*/
p_time->year = sd2506_bcd_to_dec(buf[6]) + 2000U; /* 06H: <EFBFBD>?*/
return SD2506_OK;
}
int sd2506_get_temperature(int8_t *temp)
{
int ret;
uint8_t val;
/*
* function: read internal temperature
* param: p_temp - output temperature
* return: 0=OK, -2=I2C error
* note: reads register 0x16
*/
int sd2506_get_temperature(int8_t *p_temp) {
int ret = 0;
uint8_t val = 0;
if (temp == NULL) {
if (p_temp == NULL) {
return SD2506_ERROR;
}
@@ -237,54 +271,72 @@ int sd2506_get_temperature(int8_t *temp)
return ret;
}
/* bit7 为符号位, 其余为温度*/
/* bit7 为符号位, 其余为温度<EFBFBD>?*/
if (val & 0x80U) {
/* 负温度: 取补*/
*temp = (int8_t)(val | 0xF0U);
/* 负温<EFBFBD>? 取补<EFBFBD>?*/
*p_temp = (int8_t)(val | 0xF0U);
} else {
/* 正温*/
*temp = (int8_t)(val & 0x7FU);
/* 正温<EFBFBD>?*/
*p_temp = (int8_t)(val & 0x7FU);
}
return SD2506_OK;
}
int sd2506_get_battery_voltage(uint16_t *voltage)
{
int ret;
uint8_t val_high, val_low;
/*
* function: read battery voltage (mV)
* param: p_voltage - output voltage
* return: 0=OK, -2=I2C error
* note: combines 9-bit value
*/
int sd2506_get_battery_voltage(uint16_t *p_voltage) {
int ret = 0;
uint8_t val_high = 0;
uint8_t val_low = 0;
if (voltage == NULL) {
if (p_voltage == NULL) {
return SD2506_ERROR;
}
/* 读取 1AH bit7 (BAT8_VAL) 1BH (BAT_VL) */
/* 读取 1AH bit7 (BAT8_VAL) <EFBFBD>?1BH (BAT_VL) */
ret = sd2506_read_reg(SD2506_REG_CTR5, &val_high);
if (ret != SD2506_OK) return ret;
ret = sd2506_read_reg(SD2506_REG_BAT_VAL, &val_low);
if (ret != SD2506_OK) return ret;
/* 组合 9 位: bit8=BAT8_VAL(1AH bit7), bit7~0=BAT_VL(1BH)
* 1AH=80H, 1BH=30H => 电压 = 0x130 = 304 => 3.04V => 3040mV */
/* 组合 9 <EFBFBD>? bit8=BAT8_VAL(1AH bit7), bit7~0=BAT_VL(1BH)
* <EFBFBD>?1AH=80H, 1BH=30H => 电压 = 0x130 = 304 => 3.04V => 3040mV */
uint16_t raw = ((val_high & 0x80U) << 1) | val_low;
*voltage = raw * 10; /* 转换为毫(raw 单位 0.01V) */
*p_voltage = raw * 10; /* 转换为毫<EFBFBD>?(raw 单位 0.01V) */
return SD2506_OK;
}
int sd2506_get_id(uint8_t id[8])
{
if (id == NULL) {
/*
* function: read 8-byte chip ID
* param: p_id - 8-byte output buffer
* return: 0=OK, -2=I2C error
* note: reads registers 0x72-0x79
*/
int sd2506_get_id(uint8_t p_id[8]) {
if (p_id == NULL) {
return SD2506_ERROR;
}
return sd2506_read_regs(SD2506_REG_ID_START, id, SD2506_ID_SIZE);
return sd2506_read_regs(SD2506_REG_ID_START, p_id, SD2506_ID_SIZE);
}
int sd2506_read_sram(uint8_t addr, uint8_t *buf, uint8_t len)
{
if (buf == NULL || len == 0 || addr >= SD2506_SRAM_SIZE) {
/*
* function: read SRAM data
* param: addr - start address (0-69)
* p_buf - output buffer
* len - read length
* return: 0=OK, -1=param err, -2=I2C err
* note: SRAM range 0x2C-0x71
*/
int sd2506_read_sram(uint8_t addr, uint8_t *p_buf, uint8_t len) {
if (p_buf == NULL || len == 0 || addr >= SD2506_SRAM_SIZE) {
return SD2506_ERROR;
}
@@ -292,12 +344,18 @@ int sd2506_read_sram(uint8_t addr, uint8_t *buf, uint8_t len)
return SD2506_ERROR;
}
return sd2506_read_regs(SD2506_REG_SRAM_START + addr, buf, len);
return sd2506_read_regs(SD2506_REG_SRAM_START + addr, p_buf, len);
}
int sd2506_write_sram(uint8_t addr, const uint8_t *buf, uint8_t len)
{
if (buf == NULL || len == 0 || addr >= SD2506_SRAM_SIZE) {
/*
* function: write SRAM data
* param: addr - start address (0-69)
* p_buf - input data
* len - write length
* return: 0=OK, -1=param err, -2=I2C err
*/
int sd2506_write_sram(uint8_t addr, const uint8_t *p_buf, uint8_t len) {
if (p_buf == NULL || len == 0 || addr >= SD2506_SRAM_SIZE) {
return SD2506_ERROR;
}
@@ -305,64 +363,74 @@ int sd2506_write_sram(uint8_t addr, const uint8_t *buf, uint8_t len)
return SD2506_ERROR;
}
/* SRAM 无需开写保护即可写(写保护仅00H~71H 有效, SRAM 2CH~71H)
* 但为安全起见, SRAM 写入也走写保护流*/
int ret;
/* SRAM 无需开写保护即可写<EFBFBD>?(写保护仅<EFBFBD>?00H~71H 有效, SRAM <EFBFBD>?2CH~71H)
* 但为安全起见, SRAM 写入也走写保护流<EFBFBD>?*/
int ret = 0;
ret = sd2506_write_enable();
if (ret != SD2506_OK) return ret;
ret = sd2506_write_regs(SD2506_REG_SRAM_START + addr, buf, len);
ret = sd2506_write_regs(SD2506_REG_SRAM_START + addr, p_buf, len);
if (ret != SD2506_OK) return ret;
ret = sd2506_write_disable();
return ret;
}
int sd2506_set_alarm(const sd2506_time_t *time, uint8_t mask)
{
int ret;
uint8_t buf[8];
/*
* function: set alarm interrupt
* param: p_time - alarm time struct
* mask - alarm match mask
* return: 0=OK, -2=I2C error
*/
int sd2506_set_alarm(const sd2506_time_t *p_time, uint8_t mask) {
int ret = 0;
uint8_t buf[8] = {0};
if (time == NULL) {
if (p_time == NULL) {
return SD2506_ERROR;
}
/* 组装 8 字节报警数据 (07H~0EH) */
buf[0] = sd2506_dec_to_bcd(time->second) & 0x7FU; /* 07H: 秒报*/
buf[1] = sd2506_dec_to_bcd(time->minute) & 0x7FU; /* 08H: 分报*/
buf[2] = sd2506_dec_to_bcd(time->hour) & 0x3FU; /* 09H: 时报(最高位始终为0) */
buf[0] = sd2506_dec_to_bcd(p_time->second) & 0x7FU; /* 07H: 秒报<EFBFBD>?*/
buf[1] = sd2506_dec_to_bcd(p_time->minute) & 0x7FU; /* 08H: 分报<EFBFBD>?*/
buf[2] = sd2506_dec_to_bcd(p_time->hour) & 0x3FU; /* 09H: 时报<EFBFBD>?(最高位始终<EFBFBD>?) */
buf[3] = 0x00U; /* 0AH: 星期报警 */
buf[4] = sd2506_dec_to_bcd(time->day) & 0x3FU; /* 0BH: 日报*/
buf[5] = sd2506_dec_to_bcd(time->month) & 0x1FU; /* 0CH: 月报*/
buf[6] = sd2506_dec_to_bcd(time->year - 2000U); /* 0DH: 年报*/
buf[4] = sd2506_dec_to_bcd(p_time->day) & 0x3FU; /* 0BH: 日报<EFBFBD>?*/
buf[5] = sd2506_dec_to_bcd(p_time->month) & 0x1FU; /* 0CH: 月报<EFBFBD>?*/
buf[6] = sd2506_dec_to_bcd(p_time->year - 2000U); /* 0DH: 年报<EFBFBD>?*/
buf[7] = mask; /* 0EH: 报警允许 */
/* 开启写保护 */
ret = sd2506_write_enable();
if (ret != SD2506_OK) return ret;
/* 写入报警寄存(07H~0EH) */
/* 写入报警寄存<EFBFBD>?(07H~0EH) */
ret = sd2506_write_regs(SD2506_REG_AL_SEC, buf, 8);
if (ret != SD2506_OK) return ret;
/* 使能报警中断: CTR2 INTAE=1, INTS1=0, INTS0=1, IM=1 (周期性) */
/* 使能报警中断: CTR2 <EFBFBD>?INTAE=1, INTS1=0, INTS0=1, IM=1 (周期<EFBFBD>? */
ret = sd2506_write_reg(SD2506_REG_CTR2,
SD2506_CTR2_INTAE | SD2506_CTR2_INTS0 | SD2506_CTR2_IM);
if (ret != SD2506_OK) return ret;
/* 关闭写保*/
/* 关闭写保<EFBFBD>?*/
ret = sd2506_write_disable();
if (ret != SD2506_OK) return ret;
return SD2506_OK;
}
int sd2506_clear_alarm(void)
{
int ret;
uint8_t val;
/*
* function: clear alarm interrupt flag
* param: none
* return: 0=OK, -2=I2C error
* note: reading CTR1 clears INTAF
*/
int sd2506_clear_alarm(void) {
int ret = 0;
uint8_t val = 0;
/* 读取 CTR1, ARST=1 时自动清INTAF */
/* 读取 CTR1, ARST=1 时自动清<EFBFBD>?INTAF */
ret = sd2506_read_reg(SD2506_REG_CTR1, &val);
if (ret != SD2506_OK) {
return ret;
@@ -371,11 +439,16 @@ int sd2506_clear_alarm(void)
return SD2506_OK;
}
int sd2506_read_ctr1(uint8_t *val)
{
if (val == NULL) {
/*
* function: read control register 1
* param: p_val - output value
* return: 0=OK, -2=I2C error
*/
int sd2506_read_ctr1(uint8_t *p_val) {
if (p_val == NULL) {
return SD2506_ERROR;
}
return sd2506_read_reg(SD2506_REG_CTR1, val);
return sd2506_read_reg(SD2506_REG_CTR1, p_val);
}

View File

@@ -180,7 +180,7 @@ int sd2506_init(void);
* 3. 关闭写保护
* 注意:不可单独写某一个时间寄存器
*/
int sd2506_set_time(const sd2506_time_t *time);
int sd2506_set_time(const sd2506_time_t *p_time);
/*
* 函数功能:读取 RTC 时间日期
@@ -191,7 +191,7 @@ int sd2506_set_time(const sd2506_time_t *time);
* 2. BCD 转十进制
* 3. 屏蔽小时 bit7 (12/24标志位)
*/
int sd2506_get_time(sd2506_time_t *time);
int sd2506_get_time(sd2506_time_t *p_time);
/*
* 函数功能:读取芯片内部温度
@@ -200,7 +200,7 @@ int sd2506_get_time(sd2506_time_t *time);
* 限定条件sd2506_init() 已调用
* 函数说明:读取 16H 寄存器bit7 为符号位,范围 -40~+85
*/
int sd2506_get_temperature(int8_t *temp);
int sd2506_get_temperature(int8_t *p_temp);
/*
* 函数功能:读取电池电压 (毫伏)
@@ -210,7 +210,7 @@ int sd2506_get_temperature(int8_t *temp);
* 函数说明1. 读取 1AH bit7 (BAT8_VAL) 和 1BH (BAT_VL)
* 2. 组合 9 位数据得到电压值 (如 0x135 = 309 = 3.09V)
*/
int sd2506_get_battery_voltage(uint16_t *voltage);
int sd2506_get_battery_voltage(uint16_t *p_voltage);
/*
* 函数功能:读取芯片 8 字节 ID
@@ -219,7 +219,7 @@ int sd2506_get_battery_voltage(uint16_t *voltage);
* 限定条件sd2506_init() 已调用
* 函数说明:读取 72H~79H 共 8 字节唯一 ID
*/
int sd2506_get_id(uint8_t id[8]);
int sd2506_get_id(uint8_t p_id[8]);
/*
* 函数功能:读取用户 SRAM 数据
@@ -230,7 +230,7 @@ int sd2506_get_id(uint8_t id[8]);
* 限定条件sd2506_init() 已调用
* 函数说明SRAM 地址范围 0~69对应寄存器 2CH~71H
*/
int sd2506_read_sram(uint8_t addr, uint8_t *buf, uint8_t len);
int sd2506_read_sram(uint8_t addr, uint8_t *p_buf, uint8_t len);
/*
* 函数功能:写入用户 SRAM 数据
@@ -242,7 +242,7 @@ int sd2506_read_sram(uint8_t addr, uint8_t *buf, uint8_t len);
* 函数说明SRAM 地址范围 0~69对应寄存器 2CH~71H
* SRAM 无需开写保护即可写入
*/
int sd2506_write_sram(uint8_t addr, const uint8_t *buf, uint8_t len);
int sd2506_write_sram(uint8_t addr, const uint8_t *p_buf, uint8_t len);
/*
* 函数功能:设置报警中断
@@ -255,7 +255,7 @@ int sd2506_write_sram(uint8_t addr, const uint8_t *buf, uint8_t len);
* 3. 使能报警中断 INTAE
* 4. 关写保护
*/
int sd2506_set_alarm(const sd2506_time_t *time, uint8_t mask);
int sd2506_set_alarm(const sd2506_time_t *p_time, uint8_t mask);
/*
* 函数功能:清除报警中断标志
@@ -271,7 +271,7 @@ int sd2506_clear_alarm(void);
* 入口参数val - 输出值指针
* 返回值0 - 成功,-2 - I2C 通信错误
*/
int sd2506_read_ctr1(uint8_t *val);
int sd2506_read_ctr1(uint8_t *p_val);
/*
* 函数功能BCD 码转十进制