STM32 HAL库驱动TB6612:如何用PWM实现小车电机的精准调速与正反转控制
STM32 HAL库驱动TB6612如何用PWM实现小车电机的精准调速与正反转控制在智能小车和机器人开发中电机控制是核心环节之一。想象一下当你需要让小车完成精确的转弯、匀速行驶或突然加速时背后都离不开对电机转速和方向的精准控制。STM32微控制器配合TB6612电机驱动模块为这类需求提供了高效可靠的解决方案。本文将深入探讨如何利用HAL库的PWM功能实现对TB6612驱动直流电机的精准控制。1. TB6612模块与硬件连接基础TB6612是东芝半导体推出的一款双通道直流电机驱动芯片相比传统的L298N它具有更高的效率可达95%和更低的发热量。模块支持每通道1.2A的连续电流峰值3.2A工作电压范围4.5V-15V非常适合驱动中小型直流电机。典型引脚功能引脚名称功能描述连接目标PWMA/PWMBPWM信号输入STM32定时器PWM输出AIN1/AIN2电机A控制逻辑输入STM32 GPIOBIN1/BIN2电机B控制逻辑输入STM32 GPIOVM电机驱动电压4.5-15V外部电源正极VCC逻辑电平电压2.7-5.5VSTM32 3.3VGND接地共地提示实际接线时务必确保电机电源VM与逻辑电源VCC共地这是许多初学者容易忽略的关键点。硬件连接示例以STM32F103C8T6为例// GPIO配置 // 电机A控制线 AIN1 -- PB12 AIN2 -- PB13 PWMA -- PA8 (TIM1_CH1) // 电机B控制线 BIN1 -- PB14 BIN2 -- PB15 PWMB -- PA11 (TIM1_CH4)2. PWM基础与定时器配置PWM脉冲宽度调制是电机调速的核心技术。STM32的定时器模块可以生成高精度的PWM信号通过调节占空比高电平时间与周期的比值来控制电机平均电压。关键参数计算假设我们使用72MHz的系统时钟希望生成10kHz的PWM周期0.1ms预分频器(Prescaler)设为71将时钟降为1MHz自动重装载值(Period)设为99得到周期 (711)*(991)/72MHz 0.1msHAL库配置代码示例void MX_TIM1_Init(void) { TIM_MasterConfigTypeDef sMasterConfig {0}; TIM_OC_InitTypeDef sConfigOC {0}; htim1.Instance TIM1; htim1.Init.Prescaler 71; htim1.Init.CounterMode TIM_COUNTERMODE_UP; htim1.Init.Period 99; htim1.Init.ClockDivision TIM_CLOCKDIVISION_DIV1; HAL_TIM_PWM_Init(htim1); sConfigOC.OCMode TIM_OCMODE_PWM1; sConfigOC.Pulse 0; // 初始占空比0 sConfigOC.OCPolarity TIM_OCPOLARITY_HIGH; HAL_TIM_PWM_ConfigChannel(htim1, sConfigOC, TIM_CHANNEL_1); HAL_TIM_PWM_ConfigChannel(htim1, sConfigOC, TIM_CHANNEL_4); HAL_TIM_PWM_Start(htim1, TIM_CHANNEL_1); HAL_TIM_PWM_Start(htim1, TIM_CHANNEL_4); }3. 电机控制逻辑实现TB6612通过两个逻辑输入引脚控制电机状态配合PWM实现调速。真值表如下IN1IN2PWM电机状态00X制动01有效正转10有效反转11X制动基于HAL库的控制函数实现void Motor_Control(uint8_t motor, int16_t speed) { // 限制速度范围 speed (speed 100) ? 100 : (speed -100) ? -100 : speed; if(motor MOTOR_A) { if(speed 0) { // 正转 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_RESET); } else if(speed 0) { // 反转 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET); } else { // 停止 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_RESET); } __HAL_TIM_SET_COMPARE(htim1, TIM_CHANNEL_1, abs(speed)); } else { // MOTOR_B // 类似实现... } }4. 高级控制策略与应用4.1 差速转向实现智能小车的转向通常通过左右轮差速实现。以下是一个差速控制函数示例void Differential_Drive(int16_t linear, int16_t angular) { // 计算左右轮速度 int16_t left linear - angular; int16_t right linear angular; // 限制最大速度 int16_t max_val MAX(abs(left), abs(right)); if(max_val 100) { left left * 100 / max_val; right right * 100 / max_val; } Motor_Control(MOTOR_A, left); Motor_Control(MOTOR_B, right); }4.2 加速度控制突然的速度变化会导致机械冲击通过加速度限制可实现平滑运动#define MAX_ACCEL 5 // 每100ms最大速度变化量 typedef struct { int16_t current_speed; int16_t target_speed; } MotorState; void Update_Speed(MotorState* motor) { int16_t diff motor-target_speed - motor-current_speed; diff (diff MAX_ACCEL) ? MAX_ACCEL : (diff -MAX_ACCEL) ? -MAX_ACCEL : diff; motor-current_speed diff; Motor_Control(MOTOR_A, motor-current_speed); }4.3 闭环控制基础结合编码器反馈可实现更精确的速度控制。简单PID实现框架typedef struct { float Kp, Ki, Kd; float integral; float prev_error; } PID_Controller; int16_t PID_Update(PID_Controller* pid, float setpoint, float actual) { float error setpoint - actual; pid-integral error; float derivative error - pid-prev_error; pid-prev_error error; float output pid-Kp * error pid-Ki * pid-integral pid-Kd * derivative; return (int16_t)output; }5. 常见问题与优化技巧电机抖动问题检查PWM频率是否合适建议5-20kHz确保电源容量足够大电容滤波检查接地是否良好调速线性度优化// 使用非线性映射改善低速线性度 int16_t map_speed(int16_t input) { if(input 0) return input * input / 100; else return -input * input / 100; }硬件保护措施在VM端添加大容量电解电容如1000μF电机两端并联续流二极管逻辑端串联100Ω电阻防止干扰注意调试时建议先用小占空比如10%测试电机响应避免突然全速运转导致意外。在实际项目中我发现电机的启动特性对整体控制影响很大。通过实验发现先给一个短时高占空比比维持转速高20%的启动脉冲然后再降到维持占空比可以显著改善启动响应速度而不增加太多功耗。