三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

STM32F103C8T6平衡小车避坑指南:TB6612电机驱动、编码器与MPU6050的HAL库实战配置

STM32F103C8T6平衡小车避坑指南:TB6612电机驱动、编码器与MPU6050的HAL库实战配置

STM32F103C8T6平衡小车避坑指南:TB6612电机驱动、编码器与MPU6050的HAL库实战配置

平衡小车作为嵌入式开发的经典项目,融合了电机控制、传感器数据采集和PID算法等核心技术。然而,许多开发者在复现过程中常因硬件连接、CubeMX配置或代码调试等问题陷入困境。本文将针对STM32F103C8T6平台,深入剖析TB6612电机驱动、编码器与MPU6050的实战配置要点,帮助开发者避开常见陷阱。

1. TB6612电机驱动的精准控制与常见误区

TB6612作为高效直流电机驱动芯片,其性能直接影响小车的运动表现。但在实际应用中,引脚连接错误、PWM配置不当等问题频发。

1.1 硬件连接的关键细节

典型错误接法:

  • 将电机输出端A/B与电源端VM混淆
  • PWM输入信号未接入指定定时器通道
  • 控制逻辑引脚未正确初始化

推荐连接方案:

功能引脚STM32对应引脚注意事项
PWMAPA11 (TIM1_CH4)需配置为PWM输出
PWMBPA8 (TIM1_CH1)与PWMA使用同一定时器
AIN1PB13GPIO输出模式
AIN2PB12与AIN1形成H桥控制
BIN1PB14同AIN1配置
BIN2PB15同AIN2配置

提示:TB6612的STBY引脚需接高电平使能芯片,常被忽略导致电机不工作

1.2 CubeMX定时器配置要点

在CubeMX中配置TIM1时需注意:

  1. 选择"PWM Generation CHx"模式
  2. 设置Prescaler和Counter Period计算目标频率:
    // 示例:生成10kHz PWM htim1.Instance = TIM1; htim1.Init.Prescaler = 72-1; // 72MHz/72 = 1MHz htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 100-1; // 1MHz/100 = 10kHz htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

常见配置错误:

  • 未开启定时器时钟
  • 极性设置错误导致占空比反向
  • 未配置GPIO为Alternate Function模式

2. 编码器接口的精准配置与速度计算

正交编码器提供轮速反馈,但错误配置会导致计数异常或数据抖动。

2.1 定时器编码器模式设置

在CubeMX中配置编码器接口时:

  1. 选择对应定时器(如TIM2/TIM3)
  2. 设置Combined Channels为"Encoder Mode"
  3. 配置IC1和IC2的Polarity为"Rising Edge"

关键代码实现:

// 编码器初始化 HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL); HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL); // 读取编码器值(带方向判断) int16_t Read_Encoder(TIM_HandleTypeDef *htim) { int16_t cnt = (int16_t)__HAL_TIM_GET_COUNTER(htim); __HAL_TIM_SET_COUNTER(htim, 0); return cnt; }

2.2 速度计算的优化方法

原始速度计算存在采样周期与精度矛盾,可采用以下优化方案:

  1. 移动平均滤波:

    #define FILTER_LEN 5 int32_t speed_buf[FILTER_LEN] = {0}; int32_t Get_Filtered_Speed(TIM_HandleTypeDef *htim) { static uint8_t idx = 0; speed_buf[idx++] = Read_Encoder(htim); if(idx >= FILTER_LEN) idx = 0; int32_t sum = 0; for(uint8_t i=0; i<FILTER_LEN; i++) { sum += speed_buf[i]; } return sum/FILTER_LEN; }
  2. 速度单位转换公式:

    实际速度(rpm) = (编码器值 × 60) / (采样周期(ms) × 编码线数 × 4)

3. MPU6050姿态传感器的可靠数据获取

MPU6050提供姿态数据,但I2C通信不稳定和DMP配置复杂是主要痛点。

3.1 硬件I2C的稳定配置

CubeMX关键设置:

  • I2C时钟速度设为标准模式(100kHz)
  • 开启I2C中断
  • GPIO配置为上拉模式(或外接4.7kΩ上拉电阻)

通信异常排查步骤:

  1. 用逻辑分析仪检查SCL/SDA波形
  2. 验证设备地址(0x68或0x69)
  3. 检查电源稳定性(VCC需3.3V)

3.2 DMP库的移植与优化

正点原子DMP库移植要点:

  1. 修改i2c_write和i2c_read函数对接HAL库
  2. 调整FIFO速率与采样频率匹配
  3. 添加陀螺仪零偏校准例程

姿态数据读取示例:

float pitch, roll, yaw; while(1) { if(mpu_dmp_get_data(&pitch,&roll,&yaw)==0){ printf("Pitch:%.2f Roll:%.2f Yaw:%.2f\n", pitch, roll, yaw); } HAL_Delay(10); }

4. 系统整合与PID调参实战

将各模块整合后,PID参数调节决定最终平衡效果。

4.1 控制环路架构设计

推荐采用级联PID结构:

  1. 内环(速度环):控制电机转速
  2. 外环(角度环):维持车身直立

代码框架:

void Balance_Control(void) { // 1. 读取传感器数据 float angle = Get_MPU6050_Angle(); int16_t speed = Get_Encoder_Speed(); // 2. 角度环PID计算 angle_out = PID_Calculate(&angle_pid, target_angle, angle); // 3. 速度环PID计算 speed_out = PID_Calculate(&speed_pid, angle_out, speed); // 4. 输出PWM Set_Motor_PWM(speed_out); }

4.2 PID参数调试技巧

分步调试法:

  1. 先调角度环P值,使小车能勉强站立
  2. 加入角度环D抑制振荡
  3. 最后引入速度环I值消除静差

典型参数范围参考:

参数角度环范围速度环范围
P20-505-15
I00.1-0.5
D0.5-20

调试时发现,电机响应延迟较大时可适当降低P值,增加D值;出现持续抖动时需检查MPU6050数据是否平滑。

← 返回列表