STM32 HAL库驱动TB6612模块:精准控制编码电机转速与转向(附CubeMX配置)
2026/6/14 2:40:00 网站建设 项目流程

STM32 HAL库驱动TB6612模块:精准控制编码电机转速与转向(附CubeMX配置)

在智能小车、机械臂等嵌入式项目中,电机控制往往是核心环节。TB6612作为一款高效直流电机驱动芯片,配合STM32的PWM输出和编码器接口,能够实现精准的转速与方向控制。本文将手把手带你完成从CubeMX配置到闭环控制的全流程实现。

1. 硬件架构与工作原理

TB6612FNG采用MOSFET构建H桥电路,相比传统晶体管方案具有更低导通损耗和更高开关频率。其核心功能可分解为三个部分:

  • 功率驱动:VM引脚输入4.5-15V驱动电压,通过AO1/AO2和BO1/BO2输出到电机
  • 逻辑控制:VCC引脚2.7-5.5V供电,接收来自MCU的PWM和方向信号
  • 保护机制:内置过热关断和低压检测电路

编码电机则通过正交编码器提供转速反馈,典型接线方式如下:

线序功能描述连接目标
1电机正极TB6612 AO1/AO2
2编码器GNDMCU GND
3编码器B相(正交信号)定时器输入通道
4编码器A相(正交信号)定时器输入通道
5编码器电源(通常5V)MCU 5V输出
6电机负极TB6612 AO1/AO2

2. CubeMX基础配置

2.1 PWM生成配置

  1. 选择高级定时器(如TIM1/TIM8)
  2. 开启PWM Generation模式
  3. 设置预分频器(Prescaler)和自动重载值(ARR):
    // 示例:72MHz主频下生成20kHz PWM htim1.Instance->PSC = 71; // 72MHz/(71+1) = 1MHz htim1.Instance->ARR = 49; // 1MHz/(49+1) = 20kHz
  4. 配置Pulse值为ARR的一半作为初始占空比

2.2 编码器接口配置

  1. 选择通用定时器(如TIM2-TIM5)
  2. 设置为Encoder Mode
  3. 配置通道极性为Rising Edge
  4. 设置编码器分辨率:
    // 4倍频计数模式 htim2.Init.Period = 65535; // 16位最大值

2.3 GPIO控制引脚

引脚功能模式设置初始化状态
AIN1Output Push-PullLow
AIN2Output Push-PullLow
STBYOutput Push-PullHigh

3. 电机驱动实现

3.1 方向控制逻辑

根据TB6612真值表实现方向控制函数:

void Motor_SetDirection(GPIO_TypeDef* IN1_Port, uint16_t IN1_Pin, GPIO_TypeDef* IN2_Port, uint16_t IN2_Pin, MotorDirection dir) { switch(dir) { case MOTOR_BRAKE: HAL_GPIO_WritePin(IN1_Port, IN1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(IN2_Port, IN2_Pin, GPIO_PIN_RESET); break; case MOTOR_CW: HAL_GPIO_WritePin(IN1_Port, IN1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(IN2_Port, IN2_Pin, GPIO_PIN_SET); break; case MOTOR_CCW: HAL_GPIO_WritePin(IN1_Port, IN1_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(IN2_Port, IN2_Pin, GPIO_PIN_RESET); break; } }

3.2 速度控制实现

PWM占空比调节函数示例:

void Motor_SetSpeed(TIM_HandleTypeDef* htim, uint32_t Channel, uint16_t duty) { // 限制占空比范围 duty = (duty > htim->Instance->ARR) ? htim->Instance->ARR : duty; switch(Channel) { case TIM_CHANNEL_1: htim->Instance->CCR1 = duty; break; case TIM_CHANNEL_2: htim->Instance->CCR2 = duty; break; // 其他通道处理... } }

4. 编码器测速与闭环控制

4.1 速度计算

采用定时中断法测量转速:

// 全局变量 int32_t encoder_count = 0; float rpm = 0.0f; // 定时器中断回调 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim == &htim3) { // 1ms定时器 static int32_t last_count = 0; int32_t delta = encoder_count - last_count; // 计算RPM:delta/(PPR*4) * (60000/采样周期ms) rpm = (delta / (13.0f * 4)) * (60000.0f / 10.0f); last_count = encoder_count; encoder_count = 0; // 清零计数器 } }

4.2 简易PID控制器

实现位置式PID算法:

typedef struct { float Kp, Ki, Kd; float integral; float prev_error; } PID_Controller; float PID_Update(PID_Controller* pid, float setpoint, float measurement) { float error = setpoint - measurement; pid->integral += error; if(pid->integral > 1000) pid->integral = 1000; if(pid->integral < -1000) pid->integral = -1000; float derivative = error - pid->prev_error; pid->prev_error = error; return pid->Kp * error + pid->Ki * pid->integral + pid->Kd * derivative; }

5. 系统集成与调试技巧

5.1 典型问题排查

现象可能原因解决方案
电机不转STBY引脚未使能检查STBY引脚是否为高电平
只有一个转向方向控制逻辑错误验证真值表实现代码
PWM无输出定时器未启动调用HAL_TIM_PWM_Start()
编码器读数异常信号线接触不良检查接线并添加上拉电阻

5.2 性能优化建议

  • PWM频率选择
    • 普通直流电机:5-20kHz
    • 空心杯电机:建议>25kHz
  • 抗干扰措施
    // 在编码器输入引脚配置上拉 GPIO_InitStruct.Pull = GPIO_PULLUP;
  • 速度滤波算法
    // 移动平均滤波 #define FILTER_SIZE 5 float speed_buffer[FILTER_SIZE]; float filtered_speed(float new_speed) { static uint8_t index = 0; speed_buffer[index++] = new_speed; if(index >= FILTER_SIZE) index = 0; float sum = 0; for(uint8_t i=0; i<FILTER_SIZE; i++) { sum += speed_buffer[i]; } return sum / FILTER_SIZE; }

在实际项目中,我发现电机启动时的电流冲击容易导致MCU复位。通过增加软启动算法——即PWM占空比从0开始按指数曲线递增,能有效避免这个问题。具体实现时,可以将目标速度作为PID的设定值,而不是直接控制PWM占空比。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询