1. PWM驱动四轮智能小车的工程实现原理与实践
在嵌入式智能小车系统中,电机控制是运动执行层的核心环节。本节内容聚焦于基于STM32微控制器、采用单片TB6612FNG双H桥驱动芯片实现四轮独立调速的完整工程方案。该方案摒弃了常见“双芯片拼接”的冗余设计,在硬件资源受限或成本敏感型项目中具备显著优势。其技术本质并非简单复用已有PWM外设,而是围绕电机物理特性、驱动芯片电气逻辑与MCU时序协同三者深度耦合展开的系统级设计。
1.1 硬件拓扑与驱动芯片电气逻辑解析
TB6612FNG作为主流双H桥驱动IC,其核心价值在于将复杂的MOSFET栅极驱动、死区控制与过流保护集成于单一封装内。该芯片内部包含两组完全独立的H桥电路(A通道与B通道),每组均可驱动一个直流电机实现正/反转及制动。关键电气接口定义如下:
- AIN1/AIN2 :A通道输入端,决定A电机转向
- BIN1/BIN2 :B通道输入端,决定B电机转向
- PWMA/PWMB :A/B通道PWM使能输入,占空比直接映射电机平均电压
- STBY :待机使能引脚,低电平强制所有输出为高阻态
在本方案中,四轮小车采用“左右轮组”控制策略:
- 右轮组 :由TB6612FNG的A通道驱动,对应物理上右侧两个并联电机
- 左轮组 :由TB6612FNG的B通道驱动,对应物理上左侧两个并联电机
此设计将四轮运动抽象为两个独立变量——左轮组速度 $v_L$ 与右轮组速度 $v_R$,为后续差速转向算法奠定基础。需特别注意:TB6612FNG的输入逻辑为 非互补型 ,即AIN1=1/AIN2=0与AIN1=0/AIN2=1均产生有效驱动,但方向相反;而AIN1=AIN2=1则触发制动(Brake)模式,AIN1=AIN2=0为浮空(Coast)模式。这种逻辑特性决定了软件层必须严格约束IO状态组合,避免意外制动导致的机械冲击。
1.2 STM32 GPIO与定时器资源规划
本方案选用STM32F103C8T6(主流入门级MCU)作为主控,其资源分配需兼顾功能完整性与引脚复用冲突规避:
| 功能 | MCU引脚 | 外设资源 | 配置要点 |
|---|---|---|---|
| A通道方向控制 | PA4, PA5 | GPIOA | 推挽输出,初始状态需确保安全(如全0避免上电抖动) |
| B通道方向控制 | PA6, PA7 | GPIOA | 同上 |
| A通道PWM输出 | PA8 | TIM1_CH1 | 高级定时器,支持互补输出与死区插入(虽本方案未用互补,但保留扩展性) |
| B通道PWM输出 | PA9 | TIM1_CH2 | 同上 |
| 待机控制(STBY) | PB0 | GPIOB | 开漏输出或推挽,需外接上拉电阻至VCC(典型值10kΩ) |
此处选择TIM1而非通用定时器(如TIM2/TIM3)的关键原因在于:TIM1为高级定时器,具备更强的PWM精度调节能力(16位计数器)与更灵活的时钟分频机制。对于电机控制,PWM频率需在1-20kHz范围内权衡——过低(<1kHz)易引发人耳可闻的啸叫且转矩脉动明显;过高(>20kHz)则增加开关损耗且MCU负载加重。经实测验证, 16kHz 是TB6612FNG驱动12V直流电机的最佳折中点,既能保证足够平滑的转矩输出,又留有充足CPU时间处理传感器数据。
1.3 时钟树配置与PWM参数计算
STM32的PWM输出精度直接受系统时钟树配置影响。以F103系列为例,其默认HSI为8MHz,但为获得更高定时器分辨率,需启用外部晶振(8MHz)并通过PLL倍频至72MHz(APB1总线最高允许36MHz)。关键配置步骤如下:
- RCC初始化 :启用HSE,配置PLL为HSE×9(8MHz×9=72MHz)
- APB1预分频 :设置为2,使TIM2/TIM3/TIM4时钟为36MHz;TIM1挂载于APB2(高速总线),直接使用72MHz
- TIM1时基配置 :
- 计数器时钟 = 72MHz
- 目标PWM频率 = 16kHz → 周期值(ARR)= 72,000,000 / 16,000 = 4500
- 占空比分辨率:16位计数器理论支持65536级,但实际受ARR限制,本方案达4500级(≈12位精度)
此计算过程揭示了一个常被忽视的工程细节: ARR值并非越大越好 。过大的ARR会降低计数器更新频率,导致PWM波形在低占空比时出现“跳变”现象(如1%占空比对应45个计数周期,实际占空比只能以整数周期步进)。因此,ARR需在满足频率要求的前提下尽可能取整数值,本例中4500为精确解,无舍入误差。
1.4 电机驱动模块的代码实现与状态机设计
电机驱动模块(motor_driver.c)是整个运动控制系统的基石,其设计需体现状态安全与故障容错。核心函数 Motor_Init() 完成硬件资源初始化:
void Motor_Init(void)
{
// 1. GPIO初始化:PA4-PA7推挽输出,初始状态设为0(确保H桥输入安全)
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitS

347

被折叠的 条评论
为什么被折叠?



