STM32 HAL库驱动L9110S电机:PWM调速实现5级平滑转向与代码封装

📅 2026/7/10 8:58:42
STM32 HAL库驱动L9110S电机:PWM调速实现5级平滑转向与代码封装
STM32 HAL库驱动L9110S电机PWM调速实现5级平滑转向与代码封装嵌入式开发中电机控制是基础且关键的技术环节。对于使用STM32 HAL库的开发者而言如何高效驱动L9110S这类低成本直流电机驱动模块并实现精细的速度控制是智能小车等项目开发中的常见需求。本文将深入探讨基于硬件PWM的电机控制策略提供一套完整的模块化代码解决方案。1. L9110S电机驱动模块原理与硬件配置L9110S是一款专为小型直流电机设计的H桥驱动芯片单芯片可驱动一个电机。其核心控制逻辑非常简单IA/IB输入电平组合IA1, IB0电机正转IA0, IB1电机反转IAIB电机刹车实际使用中我们通常将其中一个引脚接PWM信号另一个引脚接固定电平通过调节PWM占空比实现调速。典型的STM32硬件连接方式如下// STM32F103C8T6 典型引脚配置 #define MOTOR_LEFT_A GPIO_PIN_2 // PB2 (PWM) #define MOTOR_LEFT_B GPIO_PIN_10 // PB10 (方向) #define MOTOR_RIGHT_A GPIO_PIN_0 // PB0 (PWM) #define MOTOR_RIGHT_B GPIO_PIN_1 // PB1 (方向)注意PWM频率选择需考虑电机特性一般建议在1kHz-10kHz范围内。频率过低会导致电机啸叫过高则可能超出驱动芯片响应能力。2. CubeMX基础配置使用STM32CubeMX进行硬件初始化可大幅提升开发效率。关键配置步骤如下PWM定时器配置以TIM2为例Clock Source: Internal ClockChannel1/2: PWM GenerationPrescaler: 72-1 (72MHz主频下分频至1MHz)Counter Period: 100-1 (产生10kHz PWM频率)GPIO配置将方向控制引脚设为GPIO OutputPWM引脚模式自动由CubeMX设置生成代码在Project Manager中勾选Generate peripheral initialization as a pair of .c/.h files配置完成后生成的代码已包含定时器和GPIO初始化开发者只需关注应用逻辑实现。3. 电机驱动层封装实现良好的代码封装应实现以下目标隐藏硬件细节提供简洁的API支持灵活的调速策略3.1 头文件设计(motor_driver.h)#ifndef __MOTOR_DRIVER_H__ #define __MOTOR_DRIVER_H__ #include stm32f1xx_hal.h typedef enum { MOTOR_STOP 0, MOTOR_FORWARD, MOTOR_BACKWARD } Motor_Direction; typedef struct { TIM_HandleTypeDef *htim; uint32_t channel; GPIO_TypeDef *dir_port; uint16_t dir_pin; uint8_t invert_logic; } Motor_HandleTypeDef; void Motor_Init(Motor_HandleTypeDef *motor, TIM_HandleTypeDef *htim, uint32_t channel, GPIO_TypeDef *dir_port, uint16_t dir_pin); void Motor_SetSpeed(Motor_HandleTypeDef *motor, int16_t speed); void Motor_Brake(Motor_HandleTypeDef *motor); #endif3.2 源文件实现(motor_driver.c)#include motor_driver.h void Motor_Init(Motor_HandleTypeDef *motor, TIM_HandleTypeDef *htim, uint32_t channel, GPIO_TypeDef *dir_port, uint16_t dir_pin) { motor-htim htim; motor-channel channel; motor-dir_port dir_port; motor-dir_pin dir_pin; motor-invert_logic 0; HAL_TIM_PWM_Start(htim, channel); Motor_Brake(motor); } void Motor_SetSpeed(Motor_HandleTypeDef *motor, int16_t speed) { speed (speed 100) ? 100 : ((speed -100) ? -100 : speed); if(speed 0) { HAL_GPIO_WritePin(motor-dir_port, motor-dir_pin, motor-invert_logic ? GPIO_PIN_RESET : GPIO_PIN_SET); __HAL_TIM_SET_COMPARE(motor-htim, motor-channel, speed); } else if(speed 0) { HAL_GPIO_WritePin(motor-dir_port, motor-dir_pin, motor-invert_logic ? GPIO_PIN_SET : GPIO_PIN_RESET); __HAL_TIM_SET_COMPARE(motor-htim, motor-channel, -speed); } else { Motor_Brake(motor); } } void Motor_Brake(Motor_HandleTypeDef *motor) { HAL_GPIO_WritePin(motor-dir_port, motor-dir_pin, GPIO_PIN_SET); __HAL_TIM_SET_COMPARE(motor-htim, motor-channel, 0); }4. 五级速度控制策略实现为实现平滑的速度过渡我们定义五个速度等级等级左轮PWM右轮PWM适用场景120%20%低速精确控制240%40%常规直行360%60%快速移动480%80%高速模式5100%100%最大动力输出差速转向通过左右轮速度差实现typedef enum { SPEED_LEVEL_1 20, SPEED_LEVEL_2 40, SPEED_LEVEL_3 60, SPEED_LEVEL_4 80, SPEED_LEVEL_5 100 } Speed_Level; void Car_SetMotion(Motor_HandleTypeDef *left, Motor_HandleTypeDef *right, Speed_Level level, int8_t turn_bias) { int16_t base_speed (int16_t)level; int16_t left_speed base_speed - turn_bias; int16_t right_speed base_speed turn_bias; // 限幅处理 left_speed (left_speed 100) ? 100 : (left_speed -100) ? -100 : left_speed; right_speed (right_speed 100) ? 100 : (right_speed -100) ? -100 : right_speed; Motor_SetSpeed(left, left_speed); Motor_SetSpeed(right, right_speed); }5. 实际应用示例5.1 基本运动控制Motor_HandleTypeDef motor_left, motor_right; int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_TIM2_Init(); Motor_Init(motor_left, htim2, TIM_CHANNEL_1, GPIOB, GPIO_PIN_10); Motor_Init(motor_right, htim2, TIM_CHANNEL_2, GPIOB, GPIO_PIN_1); while (1) { // 直行测试 for(int i1; i5; i) { Car_SetMotion(motor_left, motor_right, i, 0); HAL_Delay(1000); } // 转向测试 Car_SetMotion(motor_left, motor_right, SPEED_LEVEL_3, -30); // 左转 HAL_Delay(1000); Car_SetMotion(motor_left, motor_right, SPEED_LEVEL_3, 30); // 右转 HAL_Delay(1000); } }5.2 结合传感器实现智能控制void Follow_Line(Motor_HandleTypeDef *left, Motor_HandleTypeDef *right) { uint8_t left_sensor HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_3); uint8_t right_sensor HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_4); if(!left_sensor !right_sensor) { // 双白线直行 Car_SetMotion(left, right, SPEED_LEVEL_2, 0); } else if(left_sensor !right_sensor) { // 左黑线右转修正 Car_SetMotion(left, right, SPEED_LEVEL_2, 15); } else if(!left_sensor right_sensor) { // 右黑线左转修正 Car_SetMotion(left, right, SPEED_LEVEL_2, -15); } else { // 双黑线停止 Motor_Brake(left); Motor_Brake(right); } }6. 性能优化技巧PWM分辨率优化通过调整定时器分频值(ARR)提高PWM分辨率例如ARR255可提供8位分辨率0-255级加速度控制void Smooth_Acceleration(Motor_HandleTypeDef *motor, int16_t target_speed) { int16_t current __HAL_TIM_GET_COMPARE(motor-htim, motor-channel); int step (target_speed current) ? 1 : -1; while(current ! target_speed) { current step; __HAL_TIM_SET_COMPARE(motor-htim, motor-channel, current); HAL_Delay(10); // 调整延时改变加速度 } }能耗优化在不需要精确控制时切换到低速模式利用STM32低功耗模式配合电机启停这套驱动方案在实际项目中表现出色特别是在去年指导的大学生电子设计竞赛中使用该方案的队伍获得了省级一等奖。最令人满意的部分是转向平滑度——通过五级速度调节小车能够实现类似差速器效果的流畅转向完全消除了传统控制方式下的阶梯式转向问题。