本文记录了在极海APM32F402微控制器上实现高精度实时时钟(RTC)功能的开发过程。旨在通过配置外部低速晶振(LSE)作为时钟源,实现精准的秒级计时,并通过串口打印与LED指示进行验证。
一、时钟源选型分析:LSE与LSI的比较
在项目初期,RTC功能采用的是芯片内部的低速晶振(LSI)。然而,测试结果显示其计时精度无法满足应用需求,存在显著的频率偏差。经查阅技术手册得知,LSI的标称频率约为45kHz,且受温度、老化等因素影响较大,精度较差,仅适用于对时间精度要求不高的临时性测试场景。
为实现高精度计时,本文选用外部32.768kHz无源晶振(LSE)作为RTC时钟源。尽管该方案增加了硬件电路的复杂度,但LSE具有频率稳定、精度高的显著优势,是实现可靠计时的必然选择。
二、系统实现与代码解析
本系统基于Geehy官方提供的APM32F402标准外设库进行开发,核心逻辑位于main.c文件中。主要涉及RTC的初始化配置及秒中断服务程序的编写。
RTC初始化配置(LSE时钟源)
该函数实现了从开启电源管理单元(PMU)时钟到配置嵌套向量中断控制器(NVIC)的完整流程,确保RTC基于LSE正常工作。
void RTC_LSE_Config(void)
{
// 1. 使能PMU时钟,访问备份域寄存器的前提
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_PMU);
// 2. 解锁备份域写保护,允许配置RTC相关寄存器
PMU_EnableBackupAccess();
// 3. 开启外部LSE晶振,并等待其稳定就绪
RCM_ConfigLSE(RCM_LSE_OPEN);
while(RCM_ReadStatusFlag(RCM_FLAG_LSERDY) == RESET);
// 选择LSE作为RTC时钟源,并使能RTC时钟
RCM_ConfigRTCCLK(RCM_RTCCLK_LSE);
RCM_EnableRTCCLK();
// 4. 等待RTC时钟同步,防止配置失效
RTC_WaitForSynchro();
RTC_WaitForLastTask();
// 5. 配置RTC预分频器,将32.768kHz分频为1Hz
RTC_ConfigPrescaler(32768);
RTC_WaitForLastTask();
// 6. 初始化计数器值为0
RTC_ConfigCounter(0);
RTC_WaitForLastTask();
// 7. 使能秒中断,用于触发周期性计时
RTC_EnableInterrupt(RTC_INT_SEC);
RTC_WaitForLastTask();
// 8. 配置NVIC,开启RTC全局中断
NVIC_EnableIRQRequest(RTC_IRQn, 0, 0);
}RTC中断服务函数
该函数在每秒中断触发时执行,负责读取计数值、转换时间格式、串口打印输出以及LED状态翻转。
void RTC_Isr(void)
{
// 检查秒中断标志位
if(RTC_ReadIntFlag(RTC_INT_SEC))
{
uint32_t time, h, m, s;
time = RTC_ReadCounter(); // 读取当前秒计数值
// 将总秒数转换为时、分、秒格式
h = (time / 3600) % 24;
m = (time / 60) % 60;
s = time % 60;
// 通过串口打印当前时间,ld确保两位数显示
printf("ldh:ldm:lds\r\n", h, m, s);
BOARD_LED_Toggle(LED2); // 翻转板载LED2,直观指示计时
RTC_ClearIntFlag(RTC_INT_SEC); // 清除中断标志位,避免重复进入
}
}三、测试结果与验证
完成代码编译与下载后,通过串口助手(配置为115200波特率,8N1)观察输出。结果显示,系统成功从00h:00m:00s开始进行精准计时,每秒打印一次时间信息,且板载LED以1Hz频率稳定闪烁。长时间运行测试表明,基于LSE的计时方案精度高、稳定性好,完全解决了LSI方案存在的计时偏差问题。
Copyrights© Shenzhen Linkchip Co.,LTD All Rights Reserved.