[具身智能-693]:STM32F103 + AM2857 H 桥驱动芯片如何实现电机的正转与反转?如何实现转速控制?
STM32F103 + AM2857 完整实现方案
先重申硬件基础: 单颗 AM2857 = 单路 H 桥,驱动 1 台直流有刷电机 控制引脚:IN_A、IN_B(2 个 3.3V 信号,STM32 GPIO 直接驱动) AM2857 真值表
表格
| IN_A | IN_B | 工作状态 |
|---|---|---|
| 0 | 1 | 电机正转 |
| 1 | 0 | 电机反转 |
| 0 | 0 | 滑行(高阻,自由停止) |
| 1 | 1 | 能耗刹车(短接制动) |
⚠️ 重点:AM2857无硬件死区保护,禁止直接换向,防止上下 MOS 直通烧毁芯片。
一、两种工程实现方案(推荐方案 1,机器人底盘首选)
方案 1:一个引脚固定电平,另一个引脚输出 PWM【推荐】
硬件分配
IN_A:普通 GPIO 推挽输出(输出恒定高低电平,方向控制)IN_B:定时器复用功能TIM_CHx,输出 PWM 波形(调速控制)
全程不需要动态切换 GPIO 模式,代码最简单、稳定性最高。
工作逻辑
-
电机正转
IN_A = 0(固定低电平)IN_B = PWM波形✅ PWM 占空比越大 → 电机两端平均电压越高,转速越快 -
电机反转
IN_A = 1(固定高电平)IN_B = PWM波形 -
滑行停机
IN_A = 0PWM占空比设置为0
时序优势
同一时刻只有一条信号线在高速跳变,EMI 干扰更小,降低对板载 ICM20948 陀螺仪的噪声干扰。
方案 2:IN_A、IN_B 轮流切换 PWM(不推荐)
正转:INA 固定 0,INB 输出 PWM
反转:INA 输出 PWM,INB 固定 0
缺陷:运行时需要动态切换 GPIO
「普通输出 <-> 定时器复用模式(PWM输出)」,代码复杂,容易出现配置 BUG。
二、参数配置建议(STM32F103)
- PWM 定时器:TIM1/TIM2/TIM3/TIM4,推荐 10kHz
- <5kHz:电机人耳可闻噪声大
-
20kHz:AM2857 开关损耗上升,发热加剧
- 定时器计数周期: 72MHz 系统时钟,预分频 71 → 定时器时钟 1MHz 自动重装载值 ARR=99 → 1MHz/(99+1)=10kHz 占空比范围:0~100(0%~100%)
三、标准可直接移植代码(STM32 HAL 库,方案 1 架构)
硬件定义示例
c
运行
//IN_A 普通GPIO
#define IN_A_PIN GPIO_PIN_0
#define IN_A_PORT GPIOA
//IN_B TIM_CH PWM输出(例如TIM3_CH1)
extern TIM_HandleTypeDef htim3;
#define PWM_TIM_HANDLE htim3
c
运行
//电机初始化:启动PWM通道
void Motor_Init(void)
{
HAL_TIM_PWM_Start(&PWM_TIM_HANDLE, TIM_CHANNEL_1);
__HAL_TIM_SET_COMPARE(&PWM_TIM_HANDLE, TIM_CHANNEL_1, 0); //初始占空比0
HAL_GPIO_WritePin(IN_A_PORT, IN_A_PIN, GPIO_PIN_RESET);
}
/**
* @brief 电机控制函数
* @param speed 范围 -100 ~ +100
* speed>0:正转;speed<0:反转;speed=0:滑行停止
*/
void Motor_SetSpeed(int16_t speed)
{
uint16_t duty = abs(speed);
//第一步:先把PWM清零
__HAL_TIM_SET_COMPARE(&PWM_TIM_HANDLE, TIM_CHANNEL_1, 0);
HAL_Delay(1); //换向安全死区
if(speed > 0)
{
//正转:IN_A=0,IN_B输出PWM
HAL_GPIO_WritePin(IN_A_PORT, IN_A_PIN, GPIO_PIN_RESET);
}
else if(speed < 0)
{
//反转:IN_A=1,IN_B输出PWM
HAL_GPIO_WritePin(IN_A_PORT, IN_A_PIN, GPIO_PIN_SET);
}
else
{
//停止
HAL_GPIO_WritePin(IN_A_PORT, IN_A_PIN, GPIO_PIN_RESET);
return;
}
//设置占空比,开启转速
__HAL_TIM_SET_COMPARE(&PWM_TIM_HANDLE, TIM_CHANNEL_1, duty);
}
//滑行停止简易封装
void Motor_Stop(void)
{
Motor_SetSpeed(0);
}
四、关键避坑要点(针对YB-ERF01-V3.0 控制板)
1. 换向必须加入死区延时!
禁止直接从 正转 → 立即反转 错误操作:电平瞬间翻转,MOS 关断存在延时,造成电源直通,直接烧毁 AM2857。 ✅ 规范流程:PWM 清零 → 等待 ≥1ms → 切换方向电平 → 恢复 PWM。
2. PWM 占空比含义
在这套代码里:
占空比 = IN_B 引脚上 PWM 波形的高电平占比
占空比 0 → IN_B 持续低,电机停止;
占空比 100 → IN_B 持续高,电机全速。
3. 刹车模式慎用
IN_A=1 && IN_B=1 为能耗刹车,仅适合紧急制动; 长时间堵转刹车会持续大电流,芯片过热触发 OTP 保护。 机器人底盘常规停止优先使用滑行模式(0,0)。
4. PCB 布线注意
AM2857 功率回路(VM、电机输出线)远离 ICM20948 九轴陀螺仪; 电机两端 RC 吸收回路不能省略,抑制反向电动势,减少传感器漂移。
五、麦轮 / 差速底盘拓展说明
板子使用两颗 AM2857,左右电机各一套独立 IN_A + PWM 控制信号; STM32 运动学解算得到左右轮目标速度,分别调用Motor_SetSpeed()即可实现底盘前进、后退、转向。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)