STM32 HAL 初始化I2C启动DS1307
void bsp_ds1307_init(void)
{// 初始化数据数组:包含时钟配置、时间日期和密码const uint8_t init_data[] = {0x80, 0x00, 0x00 , 0x05, 0x01, 0x01, 0x21, 0x10, \0x19, 0x61, 0x05, 0x18};uint8_t a[4];uint16_t i;// 1. 读取DS1307地址8~11的4字节数据(存储的密码)HAL_I2C_Mem_Read(&hi2c1, DS1307_ADDR, 8, I2C_MEMADD_SIZE_8BIT, a, 4, 100);// 2. 验证读取的密码是否与init_data中存储的匹配for(i = 0; i < 4; i++)if(init_data[8 + i] != a[i])break;// 3. 如果密码不匹配(i<4),则写入完整初始化数据if(i < 4){HAL_I2C_Mem_Write(&hi2c1, DS1307_ADDW, 0, I2C_MEMADD_SIZE_8BIT, \(uint8_t*)init_data, 12, 100);}
}
初始化数据详解
init_data
数组的 12 个字节依次配置如下:
索引 | 寄存器地址 | 功能描述 | 值解析(BCD 格式) |
---|---|---|---|
0 | 0x00 | 秒寄存器 | 0x80 → CH=1(振荡器停止) |
1 | 0x01 | 分寄存器 | 0x00 → 00 分 |
2 | 0x02 | 时寄存器 | 0x00 → 00 时(24 小时制) |
3 | 0x03 | 星期寄存器 | 0x05 → 星期五 |
4 | 0x04 | 日期寄存器 | 0x01 → 1 日 |
5 | 0x05 | 月寄存器 | 0x01 → 1 月 |
6 | 0x06 | 年寄存器 | 0x21 → 2021 年 |
7 | 0x07 | 控制寄存器 | 0x10 → SQWE=1(启用方波,频率 1Hz) |
8 | 0x08 | 用户自定义寄存器(密码第 1 字节) | 0x19 |
9 | 0x09 | 用户自定义寄存器(密码第 2 字节) | 0x61 |
10 | 0x0A | 用户自定义寄存器(密码第 3 字节) | 0x05 |
11 | 0x0B | 用户自定义寄存器(密码第 4 字节) | 0x18 |
关键配置点
-
振荡器状态
- 初始值
0x80
会导致时钟停止运行(CH=1)。这可能是设计问题,通常应设为0x00
启动时钟。
- 初始值
-
方波输出
- 控制寄存器(
0x07
)配置为0x10
,启用方波输出(SQWE=1),频率为 1Hz(RS0=0,RS1=0)。
- 控制寄存器(
-
时间日期
- 设置为 2021 年 1 月 1 日 星期五 00:00:00。若需更新时间,应修改此数据。
-
密码验证
- 通过比较地址
0x08~0x0B
的 4 字节数据判断是否需要初始化。
- 通过比较地址
潜在问题
-
振荡器停止
- 秒寄存器初始值
0x80
会导致时钟停止。若需启动时钟,应在写入后清除 CH 位(例如:sec &= 0x7F
)。
- 秒寄存器初始值
-
密码存储冲突
- 地址
0x08~0x0F
属于用户自定义区域,但某些应用可能将其用于其他功能,需注意冲突。
- 地址
-
时间过时
- 预设时间为 2021 年,若设备长期未使用,需手动更新时间。
改进建议
void bsp_ds1307_init(void)
{const uint8_t init_data[] = {0x00, 0x00, 0x00 , 0x05, 0x01, 0x01, 0x25, 0x10, \0x19, 0x61, 0x05, 0x18}; // 修改:秒寄存器初始值0x00(启动时钟)uint8_t a[4];uint16_t i;HAL_I2C_Mem_Read(&hi2c1, DS1307_ADDR, 8, I2C_MEMADD_SIZE_8BIT, a, 4, 100);for(i = 0; i < 4; i++)if(init_data[8 + i] != a[i])break;if(i < 4){HAL_I2C_Mem_Write(&hi2c1, DS1307_ADDW, 0, I2C_MEMADD_SIZE_8BIT, \(uint8_t*)init_data, 12, 100);}// 确保振荡器启动(清除CH位)uint8_t sec = 0;HAL_I2C_Mem_Read(&hi2c1, DS1307_ADDR, 0, I2C_MEMADD_SIZE_8BIT, &sec, 1, 100);sec &= 0x7F; // 清除CH位HAL_I2C_Mem_Write(&hi2c1, DS1307_ADDW, 0, I2C_MEMADD_SIZE_8BIT, &sec, 1, 100);
}
总结
该初始化函数主要实现了:
- 密码验证机制(通过地址
0x08~0x0B
的 4 字节数据) - 默认时间设置(2021 年 1 月 1 日)
- 方波输出配置(1Hz)