共计 2724 个字符,预计需要花费 7 分钟才能阅读完成。
硬件架构
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 为例)
- 在 CubeMX 中启用 TIM1
- Channel1/ 2 选择 ”PWM Generation CHx”
- 参数设置:
- Prescaler: 71 (72MHz/(71+1)=1MHz)
- Counter Period: 999 (1MHz/1000=1kHz PWM)
- Pulse: 初始占空比设为 0
2. 编码器接口配置(TIM3)
- 选择 ”Encoder Mode”
- 编码器模式选 ”TI1 and TI2″
- 参数建议:
- Prescaler: 0
- Counter Period: 65535
- 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
开放性问题
在实际应用中,编码器的采样频率需要根据电机转速动态调整:
– 低速时需要更长的采样周期来提高分辨率
– 高速时需要缩短采样间隔防止漏脉冲

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