单片机定时为何不准?晶振误差怎么补?
计时偏差通常不是某个 delay 写错,而是时间基准从源头就不稳定。单片机定时若同时受晶振误差、分频取整和同步延迟影响,软件看到的一秒就可能不是硬件世界的一秒。
时钟源漂移先决定长期误差。外部晶体的标称 ppm 只说明器件本体,真正上板后还受负载电容、走线寄生、驱动电平和温度曲线影响;内部 RC 振荡器虽然省成本、启动快,却更容易随电压和温度漂移。若产品用它做通信波特率、计量周期或低功耗唤醒,室温校准一次不能覆盖全工况。低温下晶振起振慢,热态下频偏又可能换方向,长期计时会出现每天数秒甚至更多的累计误差。
补偿要先确认误差来源是否稳定。负载电容不匹配造成的固定偏差可以通过换容值或软件校准修正;温度相关漂移则需要温度表或周期性对齐外部基准,如 GPS 秒脉冲、工频零点或通信网络时间。单片机若在运行态和低功耗态之间切换不同振荡器,还要分别记录两套时间基的误差,不能用主时钟校准结果去修 RTC。否则设备醒来后看似补了时间,实际把睡眠期间的漂移折算错了。
定时器配置会把源误差继续放大或量化。预分频和自动重装载寄存器只能取整数,目标频率无法整除时,每个周期都会带着固定余数;若用简单四舍五入,误差会长期累积。中断方式更新定时任务时,ISR 延迟又会让软件动作晚于硬件溢出点。对于电机控制、脉冲计数或采样触发,这种差别很关键:定时器本身准,不代表中断里的 GPIO 翻转准。若多个定时器还来自不同总线时钟,调试时看到的相位漂移可能不是算法漂移,而是分频树在负载或低功耗切换后重新排列。
更可靠的做法是让硬件承担确定时间点。PWM 更新、ADC 触发和输入捕获应尽量由定时器事件直接连接,而不是先中断再由软件拉脚;需要非整数周期时,可以用误差累加或分数分频策略,把余数分散到多个周期,避免长期单向漂移。捕获外部信号时,还要注意同步器会引入一到数个时钟的不确定延迟,高速边沿不能按理想寄存器时间理解。单片机片上外设之间若跨时钟域,触发路径也需要按数据手册核对。对低功耗唤醒定时,还应把振荡器重新稳定的时间从业务周期里扣出来,不能把唤醒后的第一拍直接当成有效采样点。
验证定时精度要分长期和短期两条线。长期用高精度频率计或基准秒脉冲测累计误差,短期用逻辑分析仪看触发抖动和中断延迟。改变温度、电压、低功耗切换次数和负载中断压力后,再比较误差是否随时钟源还是随软件负载变化。还要记录校准动作本身是否引入相位跳变,避免补偿过程打断正在运行的控制周期。对需要计量的产品,还要把老化后的频偏重新纳入预算。只有这两类误差分开,补晶振、改分频还是改触发链路才有依据。
所以,定时可靠性不是把计数器设对就结束。先把时钟源漂移建模,再让关键动作落在硬件事件上,时间轴才会稳定。





