基于HAL库的C8T6与TB6612驱动编码器电机实战指南

1次阅读
没有评论

共计 2724 个字符,预计需要花费 7 分钟才能阅读完成。

image.webp

硬件架构

1. 核心部件清单

  • STM32C8T6:主控制器,负责 PWM 生成和编码器信号处理
  • TB6612FNG:双路电机驱动模块,最大电流 1.2A
  • 带编码器的直流电机 :建议选择 6V 供电,编码器输出为 AB 相(如 JGA25-370)
  • 逻辑电平转换模块 :若电机编码器为 5V 输出需添加(如 74HC14)

2. 接线示意图

[STM32C8T6]           [TB6612]            [电机]
PA8(TIM1_CH1)  → PWMA
PA9(TIM1_CH2)  → PWMB
PC0            → AIN1
PC1            → AIN2
PC2            → BIN1
PC3            → BIN2
GND            → GND
               VM(6-12V) → 电机电源正极
               VCC(5V)  → 逻辑电源

[编码器接口]
PA6(TIM3_CH1)  → 编码器 A 相
PA7(TIM3_CH2)  → 编码器 B 相 

3. 关键注意事项

  • TB6612 的 VM 和 VCC 必须分开供电
  • 电机外壳与 STM32 共地
  • 编码器线建议使用双绞线,长度不超过 50cm

HAL 库配置

1. PWM 配置(以 TIM1 为例)

  1. 在 CubeMX 中启用 TIM1
  2. Channel1/ 2 选择 ”PWM Generation CHx”
  3. 参数设置:
  4. Prescaler: 71 (72MHz/(71+1)=1MHz)
  5. Counter Period: 999 (1MHz/1000=1kHz PWM)
  6. Pulse: 初始占空比设为 0

2. 编码器接口配置(TIM3)

  1. 选择 ”Encoder Mode”
  2. 编码器模式选 ”TI1 and TI2″
  3. 参数建议:
  4. Prescaler: 0
  5. Counter Period: 65535
  6. IC Filter: 6 (抗干扰)

3. GPIO 设置

  • 方向控制引脚 PC0-PC3 设为 GPIO_Output
  • 编码器引脚 PA6/PA7 自动配置

核心代码实现

1. TB6612 驱动函数

// 电机转向控制
#define MOTOR_A_DIR_PIN  GPIO_PIN_0
#define MOTOR_A_DIR_PORT GPIOC

void Motor_SetDir(uint8_t dir) {HAL_GPIO_WritePin(MOTOR_A_DIR_PORT, MOTOR_A_DIR_PIN, dir);
}

// PWM 占空比设置 (0-1000 对应 0%-100%)
void Motor_SetSpeed(int16_t speed) {speed = constrain(speed, -1000, 1000);
  if(speed >= 0) {Motor_SetDir(1);
    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, speed);
  } else {Motor_SetDir(0);
    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, -speed);
  }
}

2. 编码器速度计算

// 全局变量
int32_t encoder_count = 0;
float motor_rpm = 0;

// 在 TIM3 中断回调中更新计数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {if(htim == &htim3) {encoder_count = (int16_t)__HAL_TIM_GET_COUNTER(&htim3);
    __HAL_TIM_SET_COUNTER(&htim3, 0);
  }
}

// 定时计算 RPM(假设每转 20 个脉冲)void Calc_Speed(void) {
  static uint32_t last_time = 0;
  uint32_t current_time = HAL_GetTick();

  if(current_time - last_time >= 100) { // 每 100ms 计算一次
    motor_rpm = (encoder_count * 600.0f) / (20.0f * (current_time - last_time)/1000.0f);
    last_time = current_time;
    encoder_count = 0;
  }
}

3. PID 速度控制

// PID 参数结构体
typedef struct {
  float Kp, Ki, Kd;
  float integral;
  float prev_error;
} PID_Controller;

// PID 计算函数
float PID_Update(PID_Controller *pid, float setpoint, float measurement) {
  float error = setpoint - measurement;
  pid->integral += error;
  float derivative = error - pid->prev_error;

  float output = pid->Kp * error 
               + pid->Ki * pid->integral 
               + pid->Kd * derivative;

  pid->prev_error = error;
  return output;
}

// 使用示例
PID_Controller speed_pid = {.Kp=0.8, .Ki=0.2, .Kd=0.05};

void Motor_Control_Loop(void) {
  float target_rpm = 300.0f; // 目标转速
  float pid_out = PID_Update(&speed_pid, target_rpm, motor_rpm);
  Motor_SetSpeed((int16_t)pid_out);
}

避坑指南

1. 电机抖动问题

  • 现象 :电机启动时剧烈震动
  • 解决方案
  • 在 TB6612 的 VM 端并联 1000μF 电解电容
  • 每个电机引脚添加 0.1μF 陶瓷电容
  • 软件上增加启动缓升曲线

2. 编码器计数异常

  • 可能原因
  • 信号线过长引入干扰
  • 未使用施密特触发器
  • 采样频率不足
  • 解决方法
  • 缩短编码器线缆或改用屏蔽线
  • 添加 74HC14 整形电路
  • 在 CubeMX 中增加输入捕获滤波器(建议值 6)

3. PWM 频率选择

  • 低速场景 (<1000RPM):建议 500Hz-1kHz
  • 高速场景 :推荐 5kHz 以上
  • 特殊注意 :频率过高会导致 TB6612 发热明显

性能验证

1. PWM 波形测量

  • 使用示波器观测 PA8 引脚
  • 正常波形应呈现稳定方波,上升沿无振铃
  • 占空比变化时应响应迅速(延时 <100μs)

2. 编码器信号

  • AB 相波形应为 90°相位差的方波
  • 高速旋转时无波形失真
  • 建议使用数字存储示波器的 XY 模式观察李萨如图形

3. 闭环响应测试

  • 阶跃响应测试:观察从静止到 300RPM 的建立时间
  • 建议指标:超调量 <10%,稳定时间 <500ms

开放性问题

在实际应用中,编码器的采样频率需要根据电机转速动态调整:
– 低速时需要更长的采样周期来提高分辨率
– 高速时需要缩短采样间隔防止漏脉冲

基于 HAL 库的 C8T6 与 TB6612 驱动编码器电机实战指南

思考 :如何设计自适应采样算法?可以考虑以下方向:
1. 根据当前速度值动态调整定时器中断周期
2. 实现滑动窗口均值滤波
3. 使用 STM32 的硬件滤波功能自动适应信号频率

正文完
 0
评论(没有评论)