STM32 HAL 初始化I2C启动DS1307

发布于:2025-06-23 ⋅ 阅读:(23) ⋅ 点赞:(0)
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

关键配置点

  1. 振荡器状态

    • 初始值 0x80 会导致时钟停止运行(CH=1)。这可能是设计问题,通常应设为 0x00 启动时钟。
  2. 方波输出

    • 控制寄存器(0x07)配置为 0x10,启用方波输出(SQWE=1),频率为 1Hz(RS0=0,RS1=0)。
  3. 时间日期

    • 设置为 2021 年 1 月 1 日 星期五 00:00:00。若需更新时间,应修改此数据。
  4. 密码验证

    • 通过比较地址 0x08~0x0B 的 4 字节数据判断是否需要初始化。

潜在问题

  1. 振荡器停止

    • 秒寄存器初始值 0x80 会导致时钟停止。若需启动时钟,应在写入后清除 CH 位(例如:sec &= 0x7F)。
  2. 密码存储冲突

    • 地址 0x08~0x0F 属于用户自定义区域,但某些应用可能将其用于其他功能,需注意冲突。
  3. 时间过时

    • 预设时间为 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)

网站公告

今日签到

点亮在社区的每一天
去签到