← 返回嵌入式学习资料第 5 章 · 定时器、PWM 与时间

CHAPTER 5 · TIMERS AND TIME

定时器、PWM 与时间
让节奏可测量

从时钟树和计数器开始,追踪输入捕获、PWM、定时器中断和 deadline 调度;把公式、寄存器、波形、负载和主机/目标机边界明确分开。

6 个一级单元50 个递进小节主机路径可复现

TEXTBOOK MAP

CHAPTER 5 · MAP

从时间源到可复查节奏

六个一级单元对应六种能力:建立时基、测量边沿、生成 PWM、服务事件、安排 deadline、交付波形。

先理解定时器怎样数时间
  • 01 时钟树与计数器
  • 02 输入捕获与时间戳
再把时间变成外部行为
  • 03 PWM 与输出比较
  • 04 定时器中断
最后把节奏做成可移交系统
  • 05 时间驱动调度
  • 06 时间证据与交付

小节数量按认知任务变化:PWM、中断和交付需要更多递进步骤;每个单元都保留无目标机主机路径。

使用方式:先从左侧选择一个时间认知,再按时基、捕获、PWM、中断、调度和交付推进。每个单元底部有前后翻页;小节标题直接说明正在追踪的时钟、计数、边沿、波形或 deadline。
主机边界:默认使用标准库模型、C 源文件和时间序列;没有目标板也能完成公式、捕获重放、PWM 参数计算和调度测试。
目标机边界:真实时钟、计数频率、引脚复用、波形、负载、电流、温升、EMI 和中断延迟必须回到当前芯片、板卡、仪器和工具链的官方资料。

01 · TIMER TIMEBASE

时钟树与计数器:时间从哪里来

定时器不是一个自动产生秒数的黑盒。时钟源、总线分频、预分频器、计数器、自动重载、计数方向和时钟切换共同决定 tick 与周期。本单元先把时间基准拆开,再讨论溢出、精度和可观察证据。

看懂从时钟源推导计数频率。
说清区分周期、tick 与溢出。
开始做为时间误差留下测量证据。
官方基线RM0444 STM32G0x1 reference manual寄存器、复位值、时序和外设边界以本参考手册修订版为准。锁定:Rev 6 · 核对日期:2026-09-05

5.1.1 时间源、分频与计数频率

定时器输入时钟不一定等于 CPU 核心时钟。总线预分频、某些 STM32 定时器的倍频规则、时钟门控和外设选择器都可能改变实际频率。推导前先画 source→bus→timer 的路径,并把芯片系列、复位状态和配置寄存器写进记录。

5.1.2 自动重载与周期

向上计数在达到 ARR 后清零或产生更新事件,周期大致是 (PSC+1)×(ARR+1)/f_timer;向下和中心对齐会改变边沿与有效周期。公式中的加一、计数模式和取整误差不能凭经验省略,最好同时保存配置值和实际波形。

C · TIMER FREQUENCY
static uint32_t timer_tick_hz(uint32_t source_hz, uint32_t psc) { return source_hz / (psc + 1u); } static uint32_t period_ticks(uint32_t tick_hz, uint32_t period_hz) { return (tick_hz + period_hz / 2u) / period_hz; }

模型展示分频与取整;总线规则、时钟门控和具体寄存器必须按当前 MCU 核对。

C · DEADLINE DELTA
static bool reached(uint32_t now, uint32_t deadline) { return (int32_t)(now - deadline) >= 0; }

回绕安全只在有限时间窗口内成立;计数宽度和 deadline 合同必须写进记录。

5.1.3 向上、向下与中心对齐计数

中心对齐 PWM 在上数和下数时都比较,边沿对称、谐波不同,但更新事件和有效频率也不同。比较同一目标频率时,边沿对齐与中心对齐需要不同 ARR;把模式当成装饰会让测量和驱动负载错位。

表 1 · 时钟树与计数器:时间从哪里来的证据判断表
层次应留下的证据不能直接推出
时钟source/总线/门控CPU 频率就是 timer 频率
计数PSC/ARR/模式公式不需要加一
验证寄存器/波形/时基配置值等于实测时间

5.1.4 tick 精度、溢出与单位换算

tick 到时间的换算受整数宽度和溢出影响。使用无符号差值可在有限窗口内安全比较,但窗口不能超过计数器半范围;把一个 16 位计数器直接存进有符号毫秒变量,可能在长时间运行后得到负延迟。

5.1.5 时钟切换与运行时漂移

动态时钟切换会改变定时器输入频率,低功耗模式还可能停止或切换外设时钟。切换前后应重新计算预分频/ARR、记录时钟状态并定义正在等待的 deadline 如何处理。旧 tick 继续被当作真实时间,是一种隐蔽的系统性错误。

图 1.1 · 时钟树与计数器:时间从哪里来的判断路径每一格都要有自己的条件。
来源晶振/PLL/总线
计数分频/ARR
事件溢出/比较
证据计数/波形

从左到右是思考顺序,不是把公式、配置、波形和负载证据合并成一个“通过”。

5.1.6 预分频不是降低所有功耗

增大预分频可以降低计数频率,却不必然降低系统功耗;定时器、总线、CPU 唤醒、GPIO 边沿和负载都有各自开销。应比较计数分辨率、唤醒次数、可达周期和电流测量,而不是只看一个 PSC 数字。

5.1.7 用 LED 与引脚观察时间

翻转一个专用 GPIO 是很有价值的时间证据,但它只证明某段代码执行到了翻转点。波形还需要探头带宽、触发、负载、调试 halt 和测量仪器的说明;内部更新事件、ISR 入口和外部边沿之间可能存在固定或变化延迟。

5.1.8 本节交付:一张 timer contract

timer contract 至少包含时钟源、计数频率、模式、PSC、ARR、事件点、有效范围、溢出规则、误差预算和验证方法。它会被捕获、PWM 和调度共享;如果某章节改变时间基准,就必须明确哪些证据需要重跑。

CHECKPOINT 5.1把“一个定时器的‘一秒’由谁定义,又怎样知道它没有悄悄漂移?”写成一份可复查记录

请围绕“时钟树与计数器:时间从哪里来”写出对象、时钟/输入条件、状态或计算机制、输出、一个约束、一个失败路径和对应证据。没有目标板时,运行主机路径并把未执行字段标为未执行;拥有目标机时,也要补齐芯片、定时器、引脚、供电、负载、工具链、仪器和观察条件。不要用一次频率读数、LED 亮度或一个寄存器截图覆盖没有做过的验证。

合格记录要让没有现场上下文的读者知道先查什么、先运行什么、看到什么才算通过,以及哪一句结论仍然不能推出。未知项和停止条件不是扣分项,而是交付的一部分。

02 · INPUT CAPTURE

输入捕获:把边沿变成时间戳

输入捕获在边沿到来时把计数器值锁存到捕获寄存器,随后软件或 DMA 读取时间戳并计算差值。真正可用的测量还要处理计数器溢出、数字滤波、捕获分频、同步延迟、丢边沿和信号质量。本单元把波形测量写成有误差预算的证据链。

看懂从时间戳计算周期和频率。
说清处理溢出、滤波与丢样。
开始做区分捕获结果与真实信号。
官方基线RM0444 STM32G0x1 reference manual寄存器、复位值、时序和外设边界以本参考手册修订版为准。锁定:Rev 6 · 核对日期:2026-09-05

5.2.1 输入捕获的边沿到时间戳

输入捕获的核心动作是硬件在边沿到达时锁存计数器,而不是等 CPU 看到引脚后再读取时间。同步器和数字滤波仍会让锁存时刻相对物理边沿产生延迟;如果通道选择、极性或复用错了,软件得到的是另一条线的‘精确’时间戳。

5.2.2 周期与频率:差值不是魔法

两个连续上升沿的计数差给出一个周期,频率是计数频率除以差值。多周期平均可以降低量化噪声,却会增加响应延迟;对变速信号,平均窗口又可能掩盖变化。测量接口应同时返回数值、窗口长度和质量标志。

C · CAPTURE DELTA
static uint32_t capture_delta(uint32_t now, uint32_t previous) { return now - previous; } static uint32_t frequency_hz(uint32_t timer_hz, uint32_t delta) { return delta ? timer_hz / delta : 0u; }

无符号差值可处理一次回绕,但真实间隔、计数宽度和丢样仍需质量标志。

C · DUTY FROM EDGES
static float duty_from_edges(uint32_t high_ticks, uint32_t period_ticks) { return period_ticks ? (float)high_ticks / (float)period_ticks : 0.0f; }

比例只是测量模型;边沿顺序、滤波延迟和占空比范围需由目标配置验证。

5.2.3 计数器回绕与无符号差值

无符号差值 `now - previous` 可以自然处理一次回绕,只要真实间隔小于计数器半范围。若输入太慢或计数器太窄,就需要扩展溢出计数或降低计数频率。跨回绕的样本应在测试中明确展示,不能只测试常态。

表 2 · 输入捕获:把边沿变成时间戳的证据判断表
层次应留下的证据不能直接推出
边沿同步/滤波/极性每个边沿都无延迟
差值回绕/窗口/平均两个数字永远足够
质量溢出/丢样/对照频率小数无需不确定度

5.2.4 数字滤波与捕获分频

输入滤波会拒绝短脉冲,捕获分频会每 N 个有效边沿才锁存一次;二者都改变可测上限和边沿时间。滤波不是‘去噪没有代价’,它可能让占空比边沿产生不同延迟。参数要与最短脉宽、信号幅度和噪声频谱一起选择。

5.2.5 高电平/低电平时间与占空比

占空比需要同一周期内的上升、下降和下一次上升时间戳。若极性、边沿顺序、通道复用或溢出处理不正确,计算可能得到负值或超过 100%。先验证时间戳序列的顺序和质量,再做比例计算。

图 2.1 · 输入捕获:把边沿变成时间戳的判断路径每一格都要有自己的条件。
边沿同步/滤波
锁存计数器时间戳
计算差值/频率
质量溢出/丢样

从左到右是思考顺序,不是把公式、配置、波形和负载证据合并成一个“通过”。

5.2.6 DMA 捕获与缓冲区质量

DMA 可以把捕获值连续搬入环形缓冲,降低 ISR 频率,但缓冲满、总线竞争、半传输时机和缓存一致性会成为新条件。每个样本最好附带溢出/丢失标志;没有质量信息的长序列只是一串容易被误读的数字。

5.2.7 测量误差与参考仪器

误差来源包括输入同步和滤波延迟、计数器量化、时钟源频率偏差、温漂、探头和参考仪器误差。两次测量差得很小,不代表已经超过这些误差;报告应写测量方法、基准、环境和置信范围,而不是只给一个小数。

5.2.8 本节交付:输入捕获测量卡

输入捕获测量卡可以包含 signal_identity、edge、timer_clock_hz、counter_bits、filter、prescaler、timestamp_sequence、quality、formula、reference_instrument 和 limits。它把‘频率是 1000 Hz’改成有条件、可复查的结论。

CHECKPOINT 5.2把“怎样用定时器测量外部周期、频率和占空比,而不是用循环次数猜?”写成一份可复查记录

请围绕“输入捕获:把边沿变成时间戳”写出对象、时钟/输入条件、状态或计算机制、输出、一个约束、一个失败路径和对应证据。没有目标板时,运行主机路径并把未执行字段标为未执行;拥有目标机时,也要补齐芯片、定时器、引脚、供电、负载、工具链、仪器和观察条件。不要用一次频率读数、LED 亮度或一个寄存器截图覆盖没有做过的验证。

合格记录要让没有现场上下文的读者知道先查什么、先运行什么、看到什么才算通过,以及哪一句结论仍然不能推出。未知项和停止条件不是扣分项,而是交付的一部分。

03 · PWM AND OUTPUT COMPARE

PWM 与输出比较:周期、占空比和负载

PWM 是在明确周期内安排输出翻转,输出比较是把计数器与比较值连接起来;负载看到的是脉冲序列、边沿、驱动能力和滤波后的响应。频率、分辨率、占空比更新、中心对齐、互补输出和死区都需要独立解释。本单元把波形参数连接到真实负载边界。

看懂从计数器推导 PWM 参数。
说清解释占空比、分辨率与更新时机。
开始做为负载和安全输出留证据。
官方基线RM0444 STM32G0x1 reference manual寄存器、复位值、时序和外设边界以本参考手册修订版为准。锁定:Rev 6 · 核对日期:2026-09-05

5.3.1 PWM 波形不是一个模拟电压

PWM 的高电平时间占周期的比例是 duty,但负载的平均电压、电流、光照或转速还取决于驱动拓扑、二极管/电机特性、滤波、供电和机械惯性。软件 API 可以接受 50%,却不能凭此承诺负载得到 50% 的物理输出。

5.3.2 周期、频率、CCR 与占空比

边沿对齐模式通常每周期一次计数方向,中心对齐会在上数和下数比较,频率与更新事件不同。CCR 应位于定义的有效范围,超出 ARR 的写入可能被截断、产生常高/常低或被厂商特殊解释。公式、极性和寄存器定义要一起保存。

C · PWM PARAMETERS
typedef struct { uint32_t arr; uint32_t ccr; } pwm_values_t; static pwm_values_t pwm_from_duty(uint32_t arr, uint32_t duty_permille) { pwm_values_t v = {arr, (arr * duty_permille) / 1000u}; return v; }

模型不包含极性、影子寄存器、负载电流和互补死区;目标定时器手册优先。

C · SAFE_UPDATE
void pwm_update(uint32_t ccr) { disable_output_if_required(); PWM_CCR_SHADOW = ccr; wait_for_update_event(); enable_output(); }

函数名为教学占位符;更新边界和安全动作必须按具体高级定时器确认。

5.3.3 分辨率与频率的取舍

在固定 timer clock 下,PSC 越大或 ARR 越大,tick 分辨率与可达频率会改变。高频 PWM 需要更小周期,duty 只能用较少的计数步表示;低频 PWM 能提供更细 duty,却可能产生可见闪烁、可闻噪声或控制迟滞。

表 3 · PWM 与输出比较:周期、占空比和负载的证据判断表
层次应留下的证据不能直接推出
参数周期/CCR/分辨率duty 就是模拟电压
更新影子/边界/极性直接写寄存器无毛刺
负载电流/温升/安全态同一 duty 同一结果

5.3.4 输出比较与 PWM 模式

输出比较可以在匹配点翻转、置位或清零,PWM 模式则把这些动作和更新事件组合起来。通道是否已启动、引脚是否切到 alternate function、主输出使能是否打开,决定内部比较结果能否到达焊盘。

5.3.5 影子寄存器与无毛刺更新

影子寄存器让新的 ARR/CCR 在更新事件边界生效,避免半个周期被截断。若直接写活动寄存器,可能产生短脉冲;若在错误时机同时改 ARR 和 CCR,下一周期的 duty 也可能暂时越界。更新顺序和禁用窗口应作为合同。

图 3.1 · PWM 与输出比较:周期、占空比和负载的判断路径每一格都要有自己的条件。
计数周期/ARR
比较CCR/边沿
引脚复用/极性
负载电流/响应

从左到右是思考顺序,不是把公式、配置、波形和负载证据合并成一个“通过”。

5.3.6 边沿/中心对齐、互补与死区

互补输出和死区用于防止上下管同时导通,但死区过小有击穿风险,过大又会改变有效 duty。刹车输入、主输出使能、极性、故障态和复位默认值都必须以具体高级定时器和功率板资料为准,不能用普通 GPIO 经验替代。

5.3.7 LED 亮度、电机速度与实际负载

LED 亮度受到人眼积分和电流峰值影响,电机速度受到电感、反电动势、负载和控制回路影响。测量应至少包含引脚波形、负载电流或温升中的一种;只看软件 duty 不能证明负载安全,也不能证明线性。

5.3.8 频率变化、听感和 EMI

PWM 频率改变会同时改变计数分辨率、开关损耗、EMI、听感和控制响应。调整频率时只改一个变量,先预测波形和负载变化,再检查探头、地线、温升和异常输出。频率越高并不自动代表越好。

5.3.9 本节交付:一张 PWM 输出卡

PWM 输出卡包含 timer_source、mode、psc、arr、ccr、polarity、update_event、pin_mux、load_contract、safe_state、waveform 和 limits。它把计数器参数和电气负载放在同一张交付表,后续 DMA 或中断才能知道哪些时刻是安全更新点。

CHECKPOINT 5.3把“一个数字定时器怎样产生可控脉冲,又为什么占空比不等于负载得到的模拟电压?”写成一份可复查记录

请围绕“PWM 与输出比较:周期、占空比和负载”写出对象、时钟/输入条件、状态或计算机制、输出、一个约束、一个失败路径和对应证据。没有目标板时,运行主机路径并把未执行字段标为未执行;拥有目标机时,也要补齐芯片、定时器、引脚、供电、负载、工具链、仪器和观察条件。不要用一次频率读数、LED 亮度或一个寄存器截图覆盖没有做过的验证。

合格记录要让没有现场上下文的读者知道先查什么、先运行什么、看到什么才算通过,以及哪一句结论仍然不能推出。未知项和停止条件不是扣分项,而是交付的一部分。

04 · TIMER INTERRUPTS

定时器中断:延迟、抖动与丢事件

定时器中断把比较、更新或捕获事件带入 CPU 控制流,但事件标志、NVIC、ISR 延迟、优先级、清除顺序和共享数据会共同决定行为。中断不是精确的闹钟,而是一条有延迟和抖动的通知路径。本单元建立可测的中断时间预算。

看懂分解中断延迟与抖动。
说清设计不会丢标志的 ISR。
开始做用波形和计数验证事件质量。
官方基线RM0444 STM32G0x1 reference manual寄存器、复位值、时序和外设边界以本参考手册修订版为准。锁定:Rev 6 · 核对日期:2026-09-05

5.4.1 更新、比较和捕获中断的来源

一个定时器可能同时产生更新、比较、捕获、触发和刹车事件。标志位、DMA 请求和中断使能是不同层次;开启某个中断不等于硬件已经产生事件。初始化时应清除历史标志、配置来源、打开 NVIC,再在安全时刻启动计数。

5.4.2 从事件到 ISR 的延迟组成

事件发生到 ISR 翻转 GPIO 之间包含外设同步、标志置位、NVIC 挂起、当前屏蔽、抢占、取指和软件路径。入口 GPIO 与出口 GPIO 的差值可以测服务时间,外部事件边沿到入口的差值可以测延迟;两者都要记录仪器和触发方法。

C · TIMER ISR SHAPE
void TIM_IRQHandler(void) { uint32_t status = TIM_STATUS; if (status & UPDATE_FLAG) { TIM_CLEAR = UPDATE_FLAG; ++update_events; } if (status & CAPTURE_FLAG) { capture_queue_push(TIM_CAPTURE); } }

标志清除语义、同时到达事件和寄存器访问宽度必须按当前定时器资料实现。

C · GPIO TIME MARK
GPIO_TRACE_SET = 1u; service_timer_event(); GPIO_TRACE_CLEAR = 1u;

外部标记可测服务时间,但不等于整个事件延迟;仪器触发和调试状态必须记录。

5.4.3 标志清除与读改写竞争

清标志的方式可能是写 0/写 1、读状态再写控制或读取捕获寄存器自动清除。清除前后若又有事件到达,读改写可能覆盖新标志。必须按当前定时器手册实现,并用连续事件或并发注入测试验证,而不是套用另一系列 HAL 的习惯。

表 4 · 定时器中断:延迟、抖动与丢事件的证据判断表
层次应留下的证据不能直接推出
事件来源/标志/使能开中断就有事件
服务延迟/抖动/清除平均值代表最坏情况
质量计数/丢失/过载ISR 返回就处理完成

5.4.4 周期中断的抖动与最坏情况

平均延迟掩盖不了一次超过 deadline 的尖峰。要统计最小、最大、平均、峰峰抖动和丢失计数,并明确采样窗口、系统负载和调试状态。对安全或控制任务,最坏上界比漂亮的平均值更重要。

5.4.5 中断优先级、屏蔽与嵌套

前章的 NVIC 优先级和屏蔽会直接改变定时器 ISR 的到达时间。高优先级中断抢占低优先级服务会增加栈和执行时间,临界区会推迟多个事件;记录优先级位数、分组、屏蔽寄存器和嵌套路径,才能解释波形。

图 4.1 · 定时器中断:延迟、抖动与丢事件的判断路径每一格都要有自己的条件。
事件更新/比较/捕获
挂起标志/NVIC
服务ISR/清除
质量延迟/丢失

从左到右是思考顺序,不是把公式、配置、波形和负载证据合并成一个“通过”。

5.4.6 ISR、DMA 与批量服务

高频捕获每个边沿进 ISR 可能耗尽 CPU,DMA 可以批量搬运时间戳,再由较低频率的 ISR 处理。DMA 也有缓冲区、总线、缓存和溢出条件;选择它不是‘性能更高’一句话,而是一个带容量和丢样证据的合同。

5.4.7 事件计数、丢失检测与回压

事件计数器可以把硬件更新次数、ISR 服务次数、DMA 写入数和应用消费数并列,差值就能暴露丢失或重复。过载实验应设置一个可恢复的输入频率,保存计数、水位、故障标志和停止动作,不要让无限事件把目标机拖死。

5.4.8 本节交付:中断时间预算卡

中断时间预算卡包括 event_source、timer_state、nvic_state、entry_latency、service_time、jitter_window、clear_rule、overflow_policy、loss_counter 和 evidence。它是后续周期调度与低功耗唤醒的输入,不是一个脱离负载的常数。

CHECKPOINT 5.4把“定时器事件发生后,CPU 何时看到它,怎样知道没有漏掉或重复处理?”写成一份可复查记录

请围绕“定时器中断:延迟、抖动与丢事件”写出对象、时钟/输入条件、状态或计算机制、输出、一个约束、一个失败路径和对应证据。没有目标板时,运行主机路径并把未执行字段标为未执行;拥有目标机时,也要补齐芯片、定时器、引脚、供电、负载、工具链、仪器和观察条件。不要用一次频率读数、LED 亮度或一个寄存器截图覆盖没有做过的验证。

合格记录要让没有现场上下文的读者知道先查什么、先运行什么、看到什么才算通过,以及哪一句结论仍然不能推出。未知项和停止条件不是扣分项,而是交付的一部分。

05 · TIME-DRIVEN SCHEDULING

时间驱动调度:周期任务与 deadline

时间驱动调度把定时器 tick、单调计数、deadline 和任务执行时间组合成一个可解释的主循环。它不是把所有事情塞进一个中断,而是明确谁产生时间、谁消费时间、任务超时怎样降级。本单元用非阻塞方法构造可测的周期行为。

看懂用 deadline 组织多个周期任务。
说清区分漂移、抖动和执行超时。
开始做设计睡眠与唤醒边界。
官方基线RM0444 STM32G0x1 reference manual寄存器、复位值、时序和外设边界以本参考手册修订版为准。锁定:Rev 6 · 核对日期:2026-09-05

5.5.1 周期任务不是 delay 列表

`delay(period)` 完成后再加下一个 period 会把本次执行时间累积进相位,长期运行产生漂移。绝对 deadline 以理想时间线为基准,每次加固定 period,再判断 now 是否到达;错过 deadline 时要明确跳过、追赶一次还是进入故障。

5.5.2 用绝对 deadline 抑制漂移

一个周期任务的预算包含读取输入、计算、GPIO/外设写入、日志和可能的临界区。多个任务的最坏执行时间、ISR 抢占和缓存/总线等待共同决定最短可行周期。平均执行时间通过不代表最坏组合通过,时间线必须保留尖峰。

C · ABSOLUTE DEADLINE
typedef struct { uint32_t next; uint32_t period; } task_timer_t; static bool task_due(task_timer_t *task, uint32_t now) { if ((int32_t)(now - task->next) < 0) return false; task->next += task->period; return true; }

绝对 deadline 抑制相位漂移;任务执行时间、回绕和过期策略仍需测试。

C · OVERDUE POLICY
if (overdue_count > MAX_CATCH_UP) { record_timeout(); skip_to_next_phase(); }

过期策略必须明确跳过、追赶、降级或复位,不要让任务无限追赶历史。

5.5.3 任务执行时间与抖动预算

多速率循环可以让快速任务每 tick 检查,慢速任务只在自己的 deadline 到达时运行。相位错开能避免所有任务在同一个 tick 同时启动,但相位本身也是合同;改变一个任务周期后应重新检查总预算和波形。

表 5 · 时间驱动调度:周期任务与 deadline的证据判断表
层次应留下的证据不能直接推出
时间tick/单调/回绕delay 没有漂移
任务周期/相位/WCET平均执行时间足够
恢复超时/睡眠/看门狗过期任务必须追赶

5.5.4 多速率循环与相位安排

低功耗睡眠可能停止高频定时器、切换时钟或让 tick 在唤醒前不再递增。唤醒后可以用低速 RTC 补偿 elapsed、重新建立 deadline,或明确丢弃睡眠期间的周期。不能把 CPU 没运行的时间假装成普通连续 tick。

5.5.5 睡眠、唤醒与时间连续性

超时处理应有分层动作:先记录,随后降低采样/输出频率或跳过非关键任务,连续超过上限再喂狗失败或受控复位。看门狗只是恢复机制,不是时间预算;下一次启动还要读取原因码和最后心跳。

图 5.1 · 时间驱动调度:周期任务与 deadline的判断路径每一格都要有自己的条件。
tick单调时间
任务周期/deadline
执行预算/抖动
恢复sleep/看门狗

从左到右是思考顺序,不是把公式、配置、波形和负载证据合并成一个“通过”。

5.5.6 超时、降级与看门狗

主机模拟可以把 now、任务执行耗时、事件和睡眠作为纯数据输入,断言每次开始/结束、错过 deadline、跳过次数和故障动作。边界要覆盖 now==deadline、tick 回绕、任务执行恰好等于周期和突发事件。

5.5.7 主机模拟与时间线测试

时间调度表包含 clock_source、tick_hz、task、period、phase、deadline_rule、wcet_budget、observed_time、sleep_effect、timeout_action 和 evidence。它把‘大约每 10 ms’改成能被测试、测量和复盘的陈述。

5.5.8 本节交付:一张时间调度表

时间驱动主循环不是 RTOS 的替代品,而是一个明确的协作式模型。任务数量、共享资源、优先级、阻塞调用和安全动作增加后,应重新评估是否需要 RTOS;迁移时保留时间合同,不要只把函数包进 task 就宣布实时性成立。

CHECKPOINT 5.5把“没有 RTOS 时,怎样让多个周期任务按时运行,又不被一个 delay 卡住?”写成一份可复查记录

请围绕“时间驱动调度:周期任务与 deadline”写出对象、时钟/输入条件、状态或计算机制、输出、一个约束、一个失败路径和对应证据。没有目标板时,运行主机路径并把未执行字段标为未执行;拥有目标机时,也要补齐芯片、定时器、引脚、供电、负载、工具链、仪器和观察条件。不要用一次频率读数、LED 亮度或一个寄存器截图覆盖没有做过的验证。

合格记录要让没有现场上下文的读者知道先查什么、先运行什么、看到什么才算通过,以及哪一句结论仍然不能推出。未知项和停止条件不是扣分项,而是交付的一部分。

06 · TIMER DELIVERY

时间交付:从公式到可复查波形

定时器交付不是‘LED 看起来在闪’或‘示波器读到一个频率’,而是一份可以从干净目录复查的时间证据包:时钟身份、寄存器/公式、输入捕获样本、PWM 参数、ISR 时间、任务 deadline、仪器设置和未验证边界都能互相对应。本单元把前五个单元收束为可移交记录。

看懂建立时间证据包。
说清分离模型、配置和波形事实。
开始做用单变量实验维护时间合同。
官方基线RM0444 STM32G0x1 reference manual寄存器、复位值、时序和外设边界以本参考手册修订版为准。锁定:Rev 6 · 核对日期:2026-09-05

5.6.1 时间证据包最小集合

时间证据包要回答:时钟从哪里来、定时器看到多少 Hz、PSC/ARR/CCR 如何计算、输入捕获锁存了什么、PWM 哪一时刻更新、ISR 延迟是多少、任务错过了哪些 deadline、波形和负载是否安全。数字脱离对象和条件就不能复查。

5.6.2 时钟身份与资料版本

换芯片、换晶振、换 APB 分频、换示波器或进入低功耗都会改变时间合同。记录访问日期、芯片修订、时钟寄存器、板卡电源和仪器设置;‘同样的代码’不等于同样的计数频率。

PYTHON · TIMER REPORT
from dataclasses import dataclass @dataclass class Edge: tick: int level: int def deltas(edges): return [b.tick - a.tick for a, b in zip(edges, edges[1:])]

脚本只计算样本差值;它不能证明晶振、引脚复用或目标机波形。

SHELL · TIM EVIDENCE
arm-none-eabi-size build/firmware.elf arm-none-eabi-objdump -h -t build/firmware.elf > build/timer.sections.txt sha256sum build/firmware.elf build/timer.sections.txt

目标工具链未安装时继续完成主机路径;命令、版本和输出文件必须写入交付记录。

5.6.3 定时器寄存器与公式交叉核对

寄存器快照应与公式和 ELF/map 对齐:源时钟、PSC、ARR、CCR、计数模式、通道复用和启停位共同解释波形。若频率偏差,先检查时钟路径和取整,再检查探头/触发和实际负载;不要立即把所有参数重写。

表 6 · 时间交付:从公式到可复查波形的证据判断表
层次应留下的证据不能直接推出
身份时钟/定时器/引脚频率数字已足够
模型公式/样本/测试主机通过即晶振正确
事实寄存器/波形/负载一张截图交付全部

5.6.4 捕获样本、PWM 波形与日志对齐

输入捕获样本是离散时间戳,PWM CSV/截图是外部边沿,软件日志是另一个时间轴。用 GPIO 标记或共享 tick 建立对应关系,并记录串口/调试 halt 延迟。三种证据不一致时保留原始数据,先解释时基差异。

5.6.5 主机路径:重放时间与状态

没有目标板时可完成公式、配置阅读、捕获序列重放、PWM 参数计算、调度测试和记录模板;不能声称晶振精度、输出电平、负载电流、温升、EMI 或真实 ISR 延迟已经验证。未执行字段要显式标出。

图 6.1 · 时间交付:从公式到可复查波形的判断路径每一格都要有自己的条件。
身份时钟/定时器/引脚
模型公式/样本
事实寄存器/波形
交付预算/限制

从左到右是思考顺序,不是把公式、配置、波形和负载证据合并成一个“通过”。

5.6.6 目标机路径:安全测量与停止

目标机测量前确认低压供电、负载额定值、探头接地、输出默认态和可恢复固件。PWM 接到电机/功率级、频率异常或温升不可解释时停止;先限流、降占空比和断电,再保存现场,而不是让测试继续扩大损伤。

5.6.7 单变量时间回归

单变量回归可以改变一个时钟源、PSC、ARR、CCR、捕获滤波、采样周期或任务 period,但不能同时换板、换仪器和换代码。先预测频率、分辨率、边沿、延迟或任务错过次数,再比较 ELF、寄存器、CSV、日志和现象。

5.6.8 资料卡:HAL、Zephyr、Linux 与 ESP-IDF

ST HAL TIM 支持基础定时、PWM、输入捕获和输出比较;Zephyr 提供 counter/PWM 的跨板抽象;Linux 的 hrtimer 服务于内核高分辨率时间;ESP-IDF LEDC 将 PWM 定时器与通道配置分开。抽象帮助迁移,但具体时钟、引脚和电气限制仍须查芯片资料。

5.6.9 本章结业:交给中断与 DMA 的接口

交给中断与 DMA 章节的接口包括:timer clock、事件率、捕获/比较通道、ISR 或 DMA 服务预算、PWM 安全态、时间戳质量、超时动作和仍未验证的负载条件。后续设计应从这些明确边界开始,而不是把定时器当成无误差的时间源。

CHECKPOINT 5.6把“怎样把定时器配置、PWM 波形、捕获样本和调度记录交给下一位读者?”写成一份可复查记录

请围绕“时间交付:从公式到可复查波形”写出对象、时钟/输入条件、状态或计算机制、输出、一个约束、一个失败路径和对应证据。没有目标板时,运行主机路径并把未执行字段标为未执行;拥有目标机时,也要补齐芯片、定时器、引脚、供电、负载、工具链、仪器和观察条件。不要用一次频率读数、LED 亮度或一个寄存器截图覆盖没有做过的验证。

合格记录要让没有现场上下文的读者知道先查什么、先运行什么、看到什么才算通过,以及哪一句结论仍然不能推出。未知项和停止条件不是扣分项,而是交付的一部分。

资料卡(访问日期:2026-09-03):ST HAL TIM 文档支撑 STM32 定时、PWM、输入捕获与输出比较入口;Zephyr Counter/PWM、Linux timers 和 ESP-IDF LEDC 展示不同生态的时间抽象。通用 API 不能替代当前芯片的时钟树、定时器寄存器、引脚复用、负载与测量条件。