STM32F1系列MCU-TIM定时器实战应用解析

张开发
2026/4/10 14:22:52 15 分钟阅读

分享文章

STM32F1系列MCU-TIM定时器实战应用解析
1. STM32F1定时器基础与实战指南在嵌入式开发领域定时器堪称MCU的心脏。以STM32F103C8T6为例这颗72MHz主频的芯片配备了4个定时器TIM1-TIM4就像给开发者配备了4块不同功能的瑞士军刀。我刚开始接触STM32时最头疼的就是理解预分频器PSC和自动重装载寄存器ARR的关系。后来发现可以用水龙头来类比PSC像是调节水流大小的阀门72MHz主频分频后得到计数时钟ARR则是接水的桶容量计数值达到ARR时触发中断。实际项目中遇到过这样的坑配置PWM时忘记设置GPIO为复用推挽输出模式结果死活没有波形输出。后来用示波器排查才发现引脚模式配置错误。这也让我养成了检查GPIO模式的好习惯——就像开车前要先确认档位是否正确。2. 定时器类型深度解析2.1 基本定时器的精妙设计基本定时器如TIM6/TIM7就像个简单的秒表只有最基础的计时功能。但其16位自动重装载计数器的设计非常巧妙预分频器范围1~65536写入0表示1分频计数时钟公式CK_CNT CK_PSC/(PSC1)中断周期计算示例72MHz/(7200)/(10000) 1Hz1秒中断一次// 基本定时器配置示例 TIM_TimeBaseInitTypeDef TIM_InitStruct; TIM_InitStruct.TIM_Period 10000-1; // ARR值 TIM_InitStruct.TIM_Prescaler 7200-1; // PSC值 TIM_TimeBaseInit(TIM6, TIM_InitStruct);2.2 通用定时器的多面手特性通用定时器如TIM2-TIM4更像是多功能工具除了基本计时外还能支持向上/向下/中央对齐计数模式提供4个独立通道用于输入捕获/输出比较可连接正交编码器时钟源可选内部72MHz或外部信号特别实用的一个功能是单脉冲模式我用它实现了精确的延时触发。比如在超声波测距时先发出一个10μs的触发脉冲然后启动输入捕获等待回波。2.3 高级定时器的电机控制专长高级定时器如TIM1最突出的特点是死区控制功能这在驱动三相无刷电机时至关重要。我曾用TIM1的互补PWM输出控制电机驱动芯片关键配置包括死区时间通常设置1-2μs防止上下管直通刹车功能紧急关断输出重复计数器实现中断分频// 高级定时器PWM配置要点 TIM_BDTRInitTypeDef BDTR_InitStruct; BDTR_InitStruct.TIM_DeadTime 0x1F; // 约1.5μs死区 BDTR_InitStruct.TIM_Break ENABLE; // 使能刹车功能 TIM_BDTRConfig(TIM1, BDTR_InitStruct);3. PWM应用实战技巧3.1 LED呼吸灯的平滑控制制作呼吸灯时PWM频率选择很关键。通过实测发现频率低于100Hz会出现明显闪烁1KHz左右时人眼感觉最平滑占空比变化采用指数曲线比线性更自然// 呼吸灯效果实现 for(int i0; i100; i){ PWM_SetCompare(i*i/100); // 二次方曲线 Delay_ms(20); }3.2 舵机控制的精准角度控制舵机时需要特别注意周期必须严格20ms50Hz脉宽范围0.5ms-2.5ms对应0°-180°机械结构存在回差建议单方向运动我做过一个机械臂项目发现不同品牌舵机的中位脉宽可能有±50μs偏差需要实际校准。后来专门写了校准程序把各舵机参数保存在Flash中。3.3 直流电机调速系统基于TB6612的电机驱动方案比传统L298N效率更高。关键经验PWM频率建议10KHz以上降低电机啸叫加速减速需要渐变处理防止失步加入软件限流保护监测电流采样// 电机软启动实现 void Motor_SoftStart(int8_t target_speed){ static int8_t current_speed 0; while(current_speed ! target_speed){ current_speed (target_speed current_speed) ? 1 : -1; Motor_SetSpeed(current_speed); Delay_ms(10); // 10ms间隔 } }4. 输入捕获与编码器应用4.1 高精度频率测量方案测量高频信号时推荐使用测频法低频信号用测周法。我的实测对比数据方法1KHz信号误差100Hz信号误差测频法±0.1%±1.2%测周法±0.8%±0.05%特别有用的技巧是使用从模式自动复位CNT配合DMA传输捕获值可以实现无CPU干预的连续测量。4.2 正交编码器接口实战编码器接口配置要注意选择TI1和TI2双边沿计数4倍频提高分辨率计数器周期设为65535方便处理反转添加软件滤波消除抖动// 编码器速度计算示例 int32_t Get_Speed(uint32_t interval_ms){ static int16_t last_count 0; int16_t current_count TIM_GetCounter(TIM3); int16_t delta current_count - last_count; last_count current_count; return delta * 1000 / interval_ms; // 脉冲数/秒 }在智能车项目中我将编码器测速与PID控制结合实现了±2%的速度控制精度。关键点是每10ms读取一次编码器值并通过滑动窗口滤波处理突发干扰。5. 定时器应用中的常见问题根据多年经验整理出最常遇到的三大问题及解决方案中断不触发检查NVIC优先级配置确认TIM_ITConfig使能了中断查看状态寄存器标志位PWM无输出GPIO必须配置为复用推挽输出高级定时器需要调用TIM_CtrlPWMOutputs检查CCR值是否在合理范围编码器计数异常确认A/B相接线正确适当增加输入滤波器参数检查电源稳定性电压波动会导致误计数有个记忆诀窍定时器配置就像做菜时基单元是火候PSC/ARR功能配置是调味CCR/极性GPIO设置是装盘输出模式——缺一不可。

更多文章