1. 从零认识PWM与定时器的关系

第一次接触PWM时,我盯着示波器上那些方波发呆——为什么简单的电平变化就能控制电机转速?后来才明白,PWM(脉冲宽度调制)本质上是通过调节高电平在一个周期内的占比(占空比)来模拟不同电压。举个生活例子:就像用快速开关的水龙头,开50%时间关50%时间,水流平均效果相当于开了一半水量。

定时器在这里扮演着"精准秒表"的角色。以STM32F407的84MHz主频为例,经过预分频(Prescaler)调整为1MHz后,再设置自动重载值ARR=100,就能得到10kHz的PWM频率(1MHz/100)。这意味着:

  • 每个周期固定为0.1ms
  • 通过修改CCR值(比如设为50)就能得到50%占空比
  • 对应电机驱动电压就是电源电压的50%

实测中发现,预分频和ARR值的组合直接影响PWM分辨率。比如ARR=100时只能实现1%的调节精度,而ARR=1000则能达到0.1%精度,但频率会降低到1kHz。平衡点在于:电机响应频率(通常10kHz足够)和所需控制精度的取舍。

2. TB6612驱动模块深度解析

这块红色的小板子藏着不少设计智慧。拆解其内部结构会发现,它本质上是用MOS管搭建的H桥电路,相比传统的L298N有三个明显优势:

  1. 效率提升:MOS管导通电阻仅0.3Ω,发热量大幅降低
  2. 集成保护:自带短路保护和过热关断
  3. 逻辑简化:3.3V电平兼容,无需光耦隔离

重点引脚功能实测:

  • STBY引脚:接高电平时,我用万用表测量到芯片静态电流仅1μA,比L298N低两个数量级
  • VM引脚:建议并联100μF电解电容+0.1μF陶瓷电容,电机启动瞬间电流可达2A以上
  • AO1/AO2输出:示波器观察发现,PWM频率高于100kHz时波形明显畸变,证实手册建议的100kHz上限

特别提醒:焊接时一定要做好防静电措施!我曾因直接用手触摸芯片导致栅极击穿,表现为电机单向失控。后来用恒温焊台+防静电手环再没出过问题。

3. CubeMX配置关键步骤

打开CubeMX选择STM32F407VETx后,跟着我的操作顺序走:

3.1 定时器参数配置

以TIM2_CH1为例:

  1. Clock Source选择Internal Clock
  2. Channel1设为PWM Generation CH1
  3. Prescaler填83(84MHz/(83+1)=1MHz)
  4. Counter Period设为99(得到10kHz频率)
  5. Pulse初始值填0(启动时电机不转)

易错点:很多新手会忽略Clock Configuration标签页的APB1 Timer Clocks设置。这里必须确保定时器时钟使能,否则配置无效。

3.2 GPIO设置技巧

  • 控制引脚(AIN1/AIN2)设为Output Push Pull
  • PWM输出引脚要检查Alternate Function映射关系
  • 建议所有控制线加上10kΩ上拉电阻,防止MCU复位时电机误动作

配置完成后生成代码前,务必Project Manager标签页勾选"Generate peripheral initialization as a pair of .c/.h files",这样TIM和GPIO配置会生成独立文件,方便后期维护。

4. 代码实战与调试技巧

生成的工程里需要重点关注这几个函数:

// 在main.c中添加
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);  // 启动PWM
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 50);  // 设置50%占空比

// 电机正反转控制宏定义
#define MOTOR_FORWARD() do{ \
    HAL_GPIO_WritePin(GPIOA, AIN1_Pin, GPIO_PIN_SET); \
    HAL_GPIO_WritePin(GPIOA, AIN2_Pin, GPIO_PIN_RESET); \
}while(0)

调试时遇到的典型问题及解决方案:

  1. 电机抖动不转:用逻辑分析仪检查PWM波形,可能是ARR值过大导致频率过低
  2. 单方向不工作:测量AIN1/AIN2电平,常见原因是GPIO初始化模式错误
  3. 带载转速不稳:在VM端增加电容,同时检查电源功率是否足够

进阶技巧:通过DMA方式自动更新CCR值可以实现平滑调速曲线。具体做法是预存速度数组,用TIM_DMACmd函数触发传输,这在机器人运动控制中特别有用。

5. 硬件设计注意事项

画PCB时踩过的坑总结:

  1. 电机电源(VM)与逻辑电源(VCC)最好分开供电,实测共用电源时PWM占空比低于5%会失控
  2. 布线时电机回路面积要最小化,我的方案是采用星型接地:
    • 驱动芯片GND直接连电源电容地
    • 信号地单独走线返回MCU
  3. 散热处理:持续2A电流时芯片温度可达60℃,建议铺铜并预留散热孔

示波器实测波形对比:

  • 未加滤波电容:PWM上升沿有200ns振铃
  • 增加104电容后:振铃消失,电机运行噪音明显降低

6. 项目拓展思路

完成基础驱动后,可以尝试这些进阶玩法:

  1. 加入编码器反馈形成闭环控制,用PID算法实现精准转速调节
  2. 通过CAN总线接收速度指令,构建分布式驱动系统
  3. 利用STM32的硬件刹车功能,实现紧急停止时的再生制动

最近用这套方案做了个平衡小车,关键点是:

  • 定时器2用于电机PWM(10kHz)
  • 定时器3配置为编码器接口模式
  • 定时器6产生1kHz中断执行PID计算

调试中发现,PWM频率提高到20kHz以上时,电机啸叫声几乎消失,但要注意此时MOS管开关损耗会增加。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐