STM32F103 TIM3四路PWM驱动舵机与LED调光一份代码搞定两个项目在嵌入式开发中PWM脉冲宽度调制技术就像一把瑞士军刀能同时解决多种控制问题。想象一下你正在做一个智能小车项目需要两个舵机控制摄像头云台同时还要用LED显示系统状态——传统做法可能需要多个定时器或复杂的分时控制。但STM32F103的TIM3定时器给了我们更优雅的解决方案四个独立PWM通道可以同时输出不同特性的波形。1. 硬件设计与项目规划TIM3是STM32F103系列中功能全面的通用定时器拥有四个捕获/比较通道CH1-CH4每个通道都能独立配置PWM输出。在我们的项目中通道分配CH1/CH2连接SG90舵机典型50Hz控制信号CH3/CH4连接LED电路1KHz调光频率关键硬件连接注意事项舵机信号线接TIM3_CH1/CH2如PA6/PA7LED阳极通过限流电阻接VCC阴极接TIM3_CH3/CH4如PB0/PB1确保GPIO模式设置为复用推挽输出GPIO_Mode_AF_PP提示使用杜邦线连接时建议给每个舵机单独供电避免MCU电源过载2. 定时器参数计算与配置PWM的核心是三个寄存器ARR自动重装载值、PSC预分频器和CCR捕获比较值。我们需要为舵机和LED分别计算参数舵机通道配置50Hz// 系统时钟72MHz目标频率50Hz TIM_TimeBaseStructure.TIM_Prescaler 71; // 预分频72 1MHz计数频率 TIM_TimeBaseStructure.TIM_Period 19999; // 20000个计数周期 50HzLED通道配置1KHz// 使用同一个定时器基准通过不同CCR实现频率差异 TIM_OCInitStructure.TIM_Pulse 500; // 默认50%占空比参数舵机配置值LED配置值说明时钟频率1MHz1MHz相同PSC产生统一时基ARR19999999决定波形周期典型CCR值1500500控制脉宽/亮度3. 代码架构与多设备控制创新性地采用单定时器多模式设计通过通道分组实现独立控制void TIM3_PWM_Init(void) { // 公共时基配置 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_CounterMode TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_ClockDivision TIM_CKD_DIV1; // 通道特定配置 TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCMode TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState TIM_OutputState_Enable; // 初始化各通道 TIM_OC1Init(TIM3, TIM_OCInitStructure); // 舵机1 TIM_OC2Init(TIM3, TIM_OCInitStructure); // 舵机2 TIM_OC3Init(TIM3, TIM_OCInitStructure); // LED1 TIM_OC4Init(TIM3, TIM_OCInitStructure); // LED2 // 独立设置各通道CCR TIM_SetCompare1(TIM3, 1500); // 舵机中位 TIM_SetCompare3(TIM3, 300); // LED初始亮度30% }实时控制技巧使用TIM_SetComparex()函数动态调整占空比对舵机采用map()函数将角度转换为CCR值uint16_t angleToPulse(uint8_t angle) { return (angle * 10) 500; // 0°~180°映射到500~2500us }4. 工程优化与调试技巧在实际部署时会遇到几个典型问题舵机抖动检查电源稳定性建议5V/2A以上添加0.1uF电容滤除信号噪声确保中断优先级配置正确LED闪烁// 调光平滑过渡算法示例 void fadeLED(uint8_t targetBrightness) { int16_t current TIM_GetCapture3(TIM3); while(current ! targetBrightness) { current (current target) ? 1 : -1; TIM_SetCompare3(TIM3, current); Delay_ms(10); } }进阶技巧使用DMA自动更新CCR值实现复杂灯光效果通过定时器主从模式同步多个PWM定时器利用输入捕获功能实现舵机位置反馈5. 完整项目实战云台跟踪系统结合两个舵机和RGB LED我们可以构建一个简单的物体跟踪演示系统void ObjectTrackingSystem(void) { uint8_t x_angle 90, y_angle 90; uint16_t led_color 0; while(1) { if(物体在左侧) { x_angle constrain(x_angle-1, 0, 180); led_color 0xFF0000; // 红色 } // 其他方向判断... TIM_SetCompare1(TIM3, angleToPulse(x_angle)); TIM_SetCompare2(TIM3, angleToPulse(y_angle)); TIM_SetCompare3(TIM3, (led_color 16) 0xFF); // R TIM_SetCompare4(TIM3, (led_color 8) 0xFF); // G } }在调试这个项目时发现一个有趣现象当快速改变舵机角度时LED亮度变化会产生视觉暂留效果意外形成了位置指示器功能。这种硬件特性组合往往能催生创意应用。