ESP32读取RTC毫秒值出现跳变问题的解决方案咨询
问题原因及解决方案
核心问题
- 数值计算错误:你用
rtc.getMicros()/100得到的是10微秒单位的数值,不是毫秒,导致输出的“毫秒”实际是10μs的倍数,呈现跳变效果。 - RTC计时与硬件定时器不同步:ESP32Time的
getMicros()依赖系统软件计时,和硬件定时器的1ms中断触发时机存在偏差,无法保证每次中断时刚好递增1ms。 - 冗余计数:你已经在中断里维护了
millisCounter,这是硬件定时器驱动的精准1ms计数器,完全可以替代RTC读取的毫秒值。
修正后的代码
#include <Arduino.h> #include <esp32-hal-timer.h> #include <sys/time.h> #include <ESP32Time.h> ESP32Time rtc(0); volatile bool timer_flag = false; hw_timer_t *My_timer = NULL; // 创建硬件定时器 volatile unsigned long millisCounter = 0; // 毫秒计数器 void IRAM_ATTR onTimer() // 定时器中断函数 { timer_flag = true; millisCounter++; // 每毫秒递增计数器 } void setup() { Serial.begin(115200); // 初始化硬件定时器:定时器1,预分频80(时钟80MHz/80=1MHz),向上计数 My_timer = timerBegin(1, 80, true); timerAttachInterrupt(My_timer, &onTimer, true); // 设置中断触发周期:1000个时钟周期(1MHz时钟下,1000周期=1ms),自动重载 timerAlarmWrite(My_timer, 1000, true); timerAlarmEnable(My_timer); // 启用定时器中断 } void loop() { if (timer_flag) { timer_flag = false; // 获取RTC秒数,结合硬件计数器的毫秒值 int currentSecond = rtc.getSecond(); // 获取秒数 unsigned long currentMillis = millisCounter % 1000; // 取计数器低三位,得到0-999的毫秒值 // 输出时间信息 Serial.print("秒: "); Serial.print(currentSecond); Serial.print(", 毫秒: "); Serial.println(currentMillis); } }
额外说明
- 如果需要完整的运行时间戳,直接使用
millisCounter即可,它从0开始每毫秒递增,代表系统运行的总毫秒数。 - 若必须使用RTC的毫秒值,需修正计算为
rtc.getMicros()/1000,但仍可能存在同步偏差,精度不如硬件计数器。
内容的提问来源于stack exchange,提问作者sema
相关产品推荐
相关产品推荐

