)
STM32F1平衡小车实战HAL库CubeMX配置编码器模式测速全流程附避坑指南平衡小车的核心在于精确获取电机转速数据而STM32F1系列MCU的编码器接口模式为此提供了硬件级解决方案。本文将深入探讨如何利用HAL库和CubeMX工具链构建一套完整的电机测速系统特别针对工程实践中容易忽视的细节问题提供解决方案。1. 硬件架构设计与关键器件选型平衡小车的运动控制系统需要精确的转速反馈这直接关系到PID控制的稳定性。我们选择的STM32F103C8T6作为主控芯片其内置的编码器接口模式可以高效处理霍尔编码器信号。核心器件清单STM32F103C8T6最小系统板72MHz主频GM25-370直流减速电机12V/350RPM15线霍尔编码器4倍频后2040脉冲/转DRV8848电机驱动模块替代已停产的TB66120.96寸OLED显示屏I2C接口LM2596S降压模块12V转5V注意电机驱动板的电源必须与MCU系统隔离建议采用独立电源供电避免电机噪声干扰MCU工作。1.1 编码器信号处理原理霍尔编码器输出两路正交方波信号A/B相STM32的编码器接口模式可以自动识别信号相位关系信号变化计数方向脉冲计数A相上升沿B相低电平正向1B相上升沿A相高电平正向1A相下降沿B相高电平正向1B相下降沿A相低电平正向1// 编码器数值读取示例 short encoder_counter (short)__HAL_TIM_GET_COUNTER(htim3); __HAL_TIM_SET_COUNTER(htim3, 0); // 每次读取后清零计数器2. CubeMX关键配置详解CubeMX的图形化配置极大简化了外设初始化流程但对于编码器模式仍需特别注意以下参数2.1 定时器工作模式配置TIM3编码器模式配置Combined Channels选择Encoder ModeEncoder Mode设置为TI1 and TI24倍频Counter Period设为6553516位计数器最大值IC1/IC2的Polarity保持Rising EdgeTIM1定时中断配置Clock Source选择Internal ClockPrescaler设为7200-110kHz时基Counter Period设为1000-1100ms中断周期启用Update Interrupt// 定时器中断回调函数 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim htim1) { short pulses (short)__HAL_TIM_GET_COUNTER(htim3); float rpm (float)pulses * 60 / (2040 * 0.1); // 转换为RPM OLED_ShowRPM(rpm); // OLED显示转速 } }2.2 硬件接口保护设计平衡小车在实际运行中容易受到电机干扰推荐电路设计电机驱动信号线串联100Ω电阻GPIO口添加TVS二极管防护电源输入端加装470μF电解电容编码器信号线使用双绞线3. 软件实现与算法优化3.1 转速计算算法编码器原始脉冲需要转换为实际转速考虑减速比和倍频系数实际转速(RPM) (脉冲数 × 60) / (编码器线数 × 减速比 × 倍频系数 × 采样时间)对于GM25-370电机编码器线数15线减速比34:1倍频系数4采样时间0.1秒// 转速计算实现 float CalculateRPM(short pulses) { const float PULSES_PER_REV 15.0 * 34 * 4; // 2040 return (pulses * 60.0) / (PULSES_PER_REV * 0.1f); }3.2 数据滤波处理原始脉冲数据可能存在抖动推荐采用移动平均滤波#define FILTER_WINDOW 5 float speed_filter_buf[FILTER_WINDOW]; uint8_t filter_index 0; float MovingAverageFilter(float new_speed) { speed_filter_buf[filter_index] new_speed; filter_index (filter_index 1) % FILTER_WINDOW; float sum 0; for(int i0; iFILTER_WINDOW; i) { sum speed_filter_buf[i]; } return sum / FILTER_WINDOW; }4. 工程实践中的典型问题解决4.1 脉冲丢失问题排查现象转速显示值低于实际值解决方案检查编码器供电电压建议5V±5%缩短编码器信号线长度30cm在TIM配置中增加输入滤波器htim3.Init.InputCaptureFilter 0xF; // 最大滤波值4.2 方向判断错误处理当电机实际转向与检测结果相反时交换编码器A/B相接线或修改CubeMX中Encoder Mode为TI2 and TI1在代码中取反计数值encoder_counter -(short)__HAL_TIM_GET_COUNTER(htim3);4.3 计数器溢出处理16位计数器最大值为65535长时间运行可能溢出// 扩展为32位计数的解决方案 static int32_t total_pulses 0; short current_count (short)__HAL_TIM_GET_COUNTER(htim3); if(abs(current_count) 30000) { // 接近溢出阈值 total_pulses current_count 0 ? 65536 : -65536; } total_pulses current_count;5. 系统集成与调试技巧5.1 实时监控实现利用OLED显示屏实现多参数同显void DisplayMotorInfo(float rpm, short pulses) { OLED_ClearLine(2); OLED_ShowString(0, 2, RPM:, 12); OLED_ShowFloat(24, 2, rpm, 2, 12); OLED_ClearLine(3); OLED_ShowString(0, 3, Pulses:, 12); OLED_ShowNumber(42, 3, pulses, 5, 12); }5.2 蓝牙遥控集成通过HC-08模块实现转速远程调节void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart huart2) { uint8_t cmd USART2_RX_BUF[2]; uint16_t pwm_duty cmd * 72; // 0-100%对应0-7200 __HAL_TIM_SET_COMPARE(htim4, TIM_CHANNEL_1, pwm_duty); } }实际调试中发现当PWM频率设置在8-12kHz时电机运行最平稳且无明显啸叫声。对于GM25-370电机建议初始PID参数设置为Kp2.5, Ki0.1, Kd0.05然后根据实际响应进行微调。