用STM32的PWM驱动AT8870控制直流电机:从电平控制到精准调速的保姆级代码解析
STM32与AT8870的深度协同从基础PWM到电机控制库封装实战在智能小车和机器人开发中直流电机控制往往是核心环节之一。AT8870作为一款性价比极高的H桥驱动芯片配合STM32的PWM功能可以实现从简单转向到精准调速的全套控制方案。本文将带您从最基础的GPIO控制开始逐步深入到PWM调速、衰减模式选择最终完成一个可复用的电机驱动库封装。1. 硬件架构与基础控制AT8870的典型应用电路看似简单但细节决定稳定性。VM电源引脚需要并联至少47μF的电解电容和100nF的陶瓷电容且尽量靠近芯片放置。ISEN引脚根据是否需要电流检测功能可选择接采样电阻或直接接地。关键硬件连接表STM32引脚AT8870引脚功能说明PA6IN1PWM1输入PA7IN2PWM2输入3.3VVREF电流限制VBATVM电机电源基础GPIO控制只需四个状态组合// 正转 void Motor_Forward(void) { GPIO_SetBits(GPIOA, GPIO_Pin_6); GPIO_ResetBits(GPIOA, GPIO_Pin_7); } // 反转 void Motor_Reverse(void) { GPIO_ResetBits(GPIOA, GPIO_Pin_6); GPIO_SetBits(GPIOA, GPIO_Pin_7); } // 刹车 void Motor_Brake(void) { GPIO_SetBits(GPIOA, GPIO_Pin_6); GPIO_SetBits(GPIOA, GPIO_Pin_7); } // 休眠 void Motor_Sleep(void) { GPIO_ResetBits(GPIOA, GPIO_Pin_6); GPIO_ResetBits(GPIOA, GPIO_Pin_7); }注意直接GPIO控制无法调速长时间全压运行可能导致电机过热建议仅用于方向切换等短暂操作。2. PWM调速实现与定时器配置STM32的定时器PWM功能是精准调速的关键。以TIM4为例配置为向上计数模式ARR决定PWM频率CCR控制占空比。对于直流电机推荐PWM频率在5-20kHz之间既能避免可闻噪声又能保证响应速度。TIM4初始化代码void PWM_Init(void) { TIM_TimeBaseInitTypeDef TIM_BaseStruct; TIM_OCInitTypeDef TIM_OCStruct; // 时钟使能 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); // 时基配置10kHz PWM TIM_BaseStruct.TIM_Prescaler 72-1; // 72MHz/72 1MHz TIM_BaseStruct.TIM_Period 100-1; // 1MHz/100 10kHz TIM_BaseStruct.TIM_CounterMode TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, TIM_BaseStruct); // PWM通道配置 TIM_OCStruct.TIM_OCMode TIM_OCMode_PWM1; TIM_OCStruct.TIM_OutputState TIM_OutputState_Enable; TIM_OCStruct.TIM_Pulse 0; // 初始占空比0% TIM_OCStruct.TIM_OCPolarity TIM_OCPolarity_High; TIM_OC3Init(TIM4, TIM_OCStruct); // 通道3对应PA6 TIM_OC4Init(TIM4, TIM_OCStruct); // 通道4对应PA7 TIM_Cmd(TIM4, ENABLE); }调速函数通过修改CCR值实现void Motor_SetSpeed(uint8_t speed) { TIM_SetCompare3(TIM4, speed); // 修改通道3占空比 TIM_SetCompare4(TIM4, 0); // 通道4保持低电平 }3. 快衰减与慢衰减模式解析衰减模式的选择直接影响电机动态响应和能耗快衰减模式特点PWM关断期间电机两端短路电流衰减快制动效果强适合需要快速响应的场景慢衰减模式特点PWM关断期间电机自由旋转电流衰减慢运行更平滑适合需要平稳运行的场景代码实现差异体现在PWM通道的控制逻辑上// 快衰减正转 void Motor_FastDecay_Forward(uint8_t speed) { TIM_SetCompare3(TIM4, speed); // IN1 PWM TIM_SetCompare4(TIM4, 0); // IN2 0 } // 慢衰减正转 void Motor_SlowDecay_Forward(uint8_t speed) { TIM_SetCompare3(TIM4, 100); // IN1 常高 TIM_SetCompare4(TIM4, speed); // IN2 PWM }提示实际项目中可通过实验选择最佳衰减模式通常低速时慢衰减更优高速时快衰减响应更好。4. 驱动库封装与状态管理将分散的函数封装成结构体驱动的形式提高代码复用性电机控制结构体定义typedef struct { void (*Init)(void); void (*SetSpeed)(int16_t speed); // -100~100 void (*Brake)(void); void (*Sleep)(void); uint8_t currentSpeed; Motor_DecayMode decayMode; } Motor_Controller;完整驱动实现示例Motor_Controller M1 { .Init Motor_Init, .SetSpeed Motor_SetSpeed, .Brake Motor_Brake, .Sleep Motor_Sleep, .decayMode FAST_DECAY }; void Motor_SetSpeed(int16_t speed) { speed constrain(speed, -100, 100); M1.currentSpeed abs(speed); if(speed 0) { if(M1.decayMode FAST_DECAY) { Motor_FastDecay_Forward(M1.currentSpeed); } else { Motor_SlowDecay_Forward(M1.currentSpeed); } } else if(speed 0) { if(M1.decayMode FAST_DECAY) { Motor_FastDecay_Reverse(M1.currentSpeed); } else { Motor_SlowDecay_Reverse(M1.currentSpeed); } } else { Motor_Brake(); } }5. 实战小车运动控制系统结合上述封装实现一个完整的小车运动控制例程void Car_Move(int16_t leftSpeed, int16_t rightSpeed) { LeftMotor.SetSpeed(leftSpeed); RightMotor.SetSpeed(rightSpeed); } void Car_Stop(void) { LeftMotor.Brake(); RightMotor.Brake(); } void Car_Rotate(int16_t speed) { LeftMotor.SetSpeed(speed); RightMotor.SetSpeed(-speed); }调试时发现当PWM占空比低于15%时电机可能出现启动困难这是H桥驱动的常见问题。解决方案是提高初始PWM占空比至20%再逐步降低或改用慢衰减模式降低启动扭矩需求在项目后期可以进一步加入PID控制算法实现速度闭环或者通过STM32的ADC监测ISEN引脚实现电流保护功能。