STM32 平衡小车 PID 调参实战:JGB37-520 编码器数据采集与 TB6612 闭环控制
STM32 平衡小车 PID 调参实战JGB37-520 编码器数据采集与 TB6612 闭环控制平衡小车的核心在于通过精确的电机控制实现自稳定而PID算法是实现这一目标的关键。本文将深入探讨如何利用STM32微控制器、JGB37-520编码电机和TB6612驱动模块构建一个完整的闭环控制系统。1. 硬件系统架构设计平衡小车的硬件系统主要由三大部分组成传感层、控制层和执行层。传感层负责采集车身姿态和电机转速信息控制层处理数据并计算控制量执行层则根据控制信号驱动电机。关键硬件选型要点JGB37-520编码电机这款直流减速电机集成了霍尔编码器减速比为30:1空载转速约200RPM。编码器每转输出11个脉冲PPR经4倍频后实际分辨率为44PPR。TB6612驱动模块相比传统L298NTB6612具有更高效率典型效率90%以上和更小体积。其主要参数如下参数数值范围电机驱动电压2.5-13.5V逻辑电压2.7-5.5V持续输出电流1.2A/通道峰值输出电流3.2A/通道典型接线示意图STM32 GPIO ──┬── TB6612 AIN1 ├── TB6612 AIN2 ├── TB6612 PWMA └── TB6612 STBY JGB37-520 ───┬── TB6612 AO1 └── TB6612 AO2 编码器输出 ────┬── STM32 TIMx_CH1 └── STM32 TIMx_CH22. 编码器数据采集与处理JGB37-520的霍尔编码器输出两路正交信号A/B相STM32的定时器可配置为编码器模式直接读取脉冲数。初始化代码示例void Encoder_Init(TIM_TypeDef* TIMx) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; TIM_ICInitTypeDef TIM_ICInitStruct; // 时基配置 TIM_TimeBaseStruct.TIM_Prescaler 0; TIM_TimeBaseStruct.TIM_CounterMode TIM_CounterMode_Up; TIM_TimeBaseStruct.TIM_Period 0xFFFF; TIM_TimeBaseStruct.TIM_ClockDivision TIM_CKD_DIV1; TIM_TimeBaseInit(TIMx, TIM_TimeBaseStruct); // 编码器接口配置 TIM_EncoderInterfaceConfig(TIMx, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); // 输入捕获配置 TIM_ICInitStruct.TIM_ICFilter 6; // 设置滤波器 TIM_ICInit(TIMx, TIM_ICInitStruct); TIM_Cmd(TIMx, ENABLE); }速度计算策略采用定时中断法计算转速每50ms读取一次计数器值并清零// 在定时器中断服务函数中 int16_t Get_Speed(TIM_TypeDef* TIMx) { static int16_t last_count 0; int16_t current_count TIMx-CNT; int16_t speed (current_count - last_count) * 1000 / SAMPLE_TIME_MS; last_count current_count; TIMx-CNT 0; return speed; }注意实际应用中需考虑计数器溢出的情况可采用32位变量扩展计数范围。3. PID控制器实现与参数整定PID控制器的离散化公式为u(k) Kp*e(k) Ki*∑e(j) Kd*(e(k)-e(k-1))STM32实现代码typedef struct { float Kp, Ki, Kd; float integral; float prev_error; float output_limit; } PID_Controller; float PID_Update(PID_Controller* pid, float error, float dt) { // 比例项 float proportional pid-Kp * error; // 积分项带抗饱和 pid-integral error * dt; if(pid-integral pid-output_limit) pid-integral pid-output_limit; else if(pid-integral -pid-output_limit) pid-integral -pid-output_limit; float integral pid-Ki * pid-integral; // 微分项 float derivative pid-Kd * (error - pid-prev_error) / dt; pid-prev_error error; // 输出限幅 float output proportional integral derivative; if(output pid-output_limit) output pid-output_limit; else if(output -pid-output_limit) output -pid-output_limit; return output; }参数整定三步法比例调节Kp先将Ki和Kd设为0逐渐增大Kp直到系统开始振荡取振荡临界值的50-70%作为初始Kp积分调节Ki保持Kp不变逐步增加Ki观察系统消除稳态误差的速度过大的Ki会导致超调增大微分调节Kd最后加入微分项抑制超调典型值为Kp的1/10到1/4注意高频噪声可能被放大典型参数范围参考参数速度环角度环Kp5.0-15.020.0-40.0Ki0.1-0.50.5-2.0Kd0.5-2.05.0-15.04. 系统集成与性能优化完整的控制流程包含以下步骤数据采集层通过MPU6050获取姿态角互补滤波或卡尔曼滤波编码器读取电机转速电压电流监测可选控制决策层void Control_Loop() { // 读取传感器数据 float angle Get_IMU_Angle(); float speed_left Get_Motor_Speed(TIM3); float speed_right Get_Motor_Speed(TIM4); // 角度环PID计算 float angle_ctrl PID_Update(angle_pid, target_angle - angle, DT); // 速度环PID计算 float speed_ctrl PID_Update(speed_pid, target_speed - (speed_left speed_right)/2, DT); // 合成控制量 float output angle_ctrl speed_ctrl; // 输出到电机 Set_Motor_Output(MOTOR_L, output); Set_Motor_Output(MOTOR_R, output); }输出执行层PWM占空比限制在10%-90%以保护驱动芯片死区补偿特别是低速时电机转向控制逻辑常见问题解决方案高频振荡增加微分项或降低比例增益响应迟钝检查编码器分辨率是否足够提高采样频率单边偏离校准电机中位电压检查机械对称性启动抖动添加启动缓变算法逐步增加目标值通过系统化的参数整定和细致的机械调整平衡小车应能在3-5秒内达到稳定状态并具备抵抗轻微扰动的能力。实际测试时建议先用支架固定小车通过串口实时监控各参数变化逐步优化控制性能。