硬件平台
芯片: AT32F423VCT7
RTC: 增强型 RTC (ERTC),支持 LEXT (32.768KHz) 外部晶振
开发板: AT32F423 START
移植历程
第一阶段:寄存器级实现
目标: 直接操作 ERTC 寄存器实现时间设置和读取代码示例:
// 初始尝试:直接操作寄存器 #define ERTC_BASE 0x40002800 #define ERTC_TP ((ERTC_TypeDef *) ERTC_BASE) // ... 寄存器定义遇到的问题:
1. ERTC 初始化模式进入失败
2. 寄存器配置顺序不正确
3. 每次重启后时间丢失第二阶段:使用 AT32 HAL 库
转折点: 发现官方 AT32 HAL 库中有完整的 ERTC 示例代码
关键发现:// 官方示例的正确初始化顺序ertc_reset(); // 复位 ERTC ertc_wait_update(); // 等待更新 ertc_divider_set(127, 255); // 设置预分频 for 1Hz
核心参数计算:
LEXT = 32768 Hz div_a = 127, div_b = 255 频率 = 32768 / 128 / 256 = 1Hz
第三阶段:集成到 Zephyr 框架
目标: 符合 Zephyr RTC 设备框架 APIstatic const struct rtc_driver_api at32_rtc_driver_api = {
.set_time = at32_rtc_set_time,
.get_time = at32_rtc_get_time,
};智能初始化策略:
// 检查 RTC 是否已配置(时间不为 00:00:00)
// 如果已配置则跳过初始化,保留时间
if (curr_time.hour != 0 || curr_time.min != 0 || curr_time.sec != 0) {
return 0; // RTC 已运行,跳过
}关键技术点
1. 时钟配置// 1. 开启 PWC 时钟 crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE); // 2. 允许访问备份域 pwc_battery_powered_domain_access(TRUE); // 3. 复位备份域 crm_battery_powered_domain_reset(TRUE); crm_battery_powered_domain_reset(FALSE); // 4. 启用 LEXT 晶振 crm_clock_source_enable(CRM_CLOCK_SOURCE_LEXT, TRUE); while (crm_flag_get(CRM_LEXT_STABLE_FLAG) == RESET); // 5. 选择 LEXT 作为 ERTC 时钟源 crm_ertc_clock_select(CRM_ERTC_CLOCK_LEXT); crm_ertc_clock_enable(TRUE);2. 时间转换
// Zephyr time_t → AT32 ERTC year = timeptr->tm_year + 1900 - RTC_YEAR_REF; month = timeptr->tm_mon + 1; day = timeptr->tm_mday; // AT32 ERTC → Zephyr time_t timeptr->tm_year = ertc_time.year + RTC_YEAR_REF - 1900; timeptr->tm_mon = ertc_time.month - 1;3. 驱动文件结构
zephyr/drivers/rtc/ ├── Kconfig.at32 # 配置选项 └── rtc_at32.c # 驱动实现遇到的问题及解决方案
| 问题 | 原因 | 解决方案 |
| ERTC 初始化失败 | 未正确进入初始化模式 | 使用 `ertc_reset()` 函数 |
| 时间每次重启丢失 | 备份域未正确配置 | 检查 LEXT 晶振和时钟源选择 |
| 编译报错 | 未添加 HAL 源文件 | 在 CMakeLists.txt 添加 drivers |
| 预分频计算错误 | 分频系数不对 | 使用 div_a=127, div_b=255 |
CMakeLists.txt 添加
zephyr_library_sources(
${AT32_HAL_DIR}/at32f423/drivers/src/at32f423_crm.c
${AT32_HAL_DIR}/at32f423/drivers/src/at32f423_pwc.c
${AT32_HAL_DIR}/at32f423/drivers/src/at32f423_ertc.c
) prj.conf 添加CONFIG_RTC=y CONFIG_RTC_AT32=y
测试效果:

总结
1. 优先使用 HAL 库: 官方 HAL 库经过充分测试比自己写寄存器更可靠
2. 参考官方示例: AT32 官方固件库中有丰富的示例代码
3. 保留时间逻辑: 智能检测 RTC 是否已配置,避免断电后时间丢失
4. 遵循框架规范: 严格按照 Zephyr 设备框架编写驱动附开源库网址:
at32_zephyr_lugl: Zephyr RTOS port for Artery AT32 series MCUs
我要赚赏金
