问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

基于STM32的L298N电机驱动详解:从原理到代码实现

创作时间:
作者:
@小白创作中心

基于STM32的L298N电机驱动详解:从原理到代码实现

引用
CSDN
1.
https://blog.csdn.net/weixin_44407238/article/details/145750990

一、为什么要用L298N驱动电机?

1.1 电机的“胃口”与单片机的“力气”

  • 问题 :STM32的GPIO引脚只能输出3.3V/20mA,而直流电机需要 5-12V/数百mA 的驱动电流。
  • 解决 :L298N作为 双H桥驱动芯片 ,能承受最高46V/2A的电流,相当于给STM32配了一个“大力士保镖”。

1.2 H桥的魔法:电流方向控制

  • 正转 :IN1=高电平,IN2=低电平 → 电流从OUT1流向OUT2
  • 反转 :IN1=低电平,IN2=高电平 → 电流方向反转
  • 刹车 :IN1=IN2=高电平 → 电机两端短路制动

二、硬件连接全解析(附原理图)

2.1 电源系统设计

电源类型
接法
注意事项
逻辑电源(5V)
L298N的+5V引脚
可为STM32供电(需跳线)
驱动电源(12V)
L298N的+12V和GND
必须与STM32共地!

2.2 信号线连接表

STM32引脚
L298N引脚
作用说明
PA0
ENA
PWM调速(定时器2通道1)
PA1
IN1
方向控制A
PA2
IN2
方向控制B
GND
GND
共地(关键!)

三、PWM调速的数学原理

3.1 什么是占空比?

  • 定义 :一个周期内高电平时间占比
    公式占空比 = (高电平时间 / 周期时间) × 100%
  • 示例 :周期1ms,高电平0.7ms → 占空比70%

3.2 STM32如何生成PWM?

  • 时钟源 :72MHz系统时钟 → 通过预分频器降低频率
  • 自动重装载值 :决定PWM周期
  • 捕获比较寄存器 :设置高电平时间
代码参数计算示例:
htim2.Init.Prescaler = 71;     // 预分频系数72 → 72MHz/(71+1)=1MHz
htim2.Init.Period = 999;       // 自动重装载值1000 → 周期=1MHz/1000=1kHz
// 占空比 = Pulse / (Period+1) → 500/1000=50%

四、代码逐行解析(HAL库版)

4.1 GPIO初始化

// 配置PA1、PA2为推挽输出
GPIO_InitStruct.Pin = GPIO_PIN_1 | GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;  // 推挽模式(强驱动)
GPIO_InitStruct.Pull = GPIO_NOPULL;          // 无上下拉
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

4.2 PWM定时器配置

void MX_TIM2_Init(void)
{
    htim2.Instance = TIM2;                   // 选择定时器2
    htim2.Init.Prescaler = 71;               // 预分频系数
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP; // 向上计数
    htim2.Init.Period = 999;                 // 自动重装载值
    HAL_TIM_PWM_Init(&htim2);                // 初始化PWM

    TIM_OC_InitTypeDef sConfigOC = {0};
    sConfigOC.OCMode = TIM_OCMODE_PWM1;      // PWM模式1(CNT<CCR时高电平)
    sConfigOC.Pulse = 0;                     // 初始占空比0%
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; // 高电平有效
    HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1);
    HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); // 启动PWM
}

4.3 电机控制逻辑

// 正转函数
void Motor_Forward(void)
{
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);   // IN1=1
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); // IN2=0
    __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 700);    // 70%速度
}

// 停止函数
void Motor_Stop(void)
{
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
    __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 0);      // 占空比0%
}

五、烧录与调试技巧

5.1 常见问题解决方案

现象
排查步骤
工具使用技巧
电机抖动
1. 检查PWM频率是否过低(<50Hz)
示波器观察ENA引脚波形
驱动芯片发烫
1. 测量电机是否堵转
万用表测量电机电阻
电源指示灯熄灭
1. 检查12V电源是否短路
替换法测试电源适配器

5.2 进阶调试方法

  • 逻辑分析仪 :同时捕捉IN1/IN2和PWM信号时序
  • 电流检测 :串联万用表观察启动电流
  • 热成像仪 :检测L298N芯片温度分布

六、知识扩展:PID速度闭环控制

6.1 为什么要闭环?

  • 开环问题 :负载变化导致转速波动
  • 解决方案 :通过编码器反馈转速 → PID计算 → 调节PWM

6.2 伪代码示例

float Kp=0.5, Ki=0.01, Kd=0.1;
float error, last_error, integral;

void PID_Control(float target_speed, float current_speed)
{
    error = target_speed - current_speed;
    integral += error;
    float output = Kp*error + Ki*integral + Kd*(error-last_error);
    Motor_Speed(output);  // 输出PWM
    last_error = error;
}

七、学习资源推荐

  1. 《STM32CubeMX实战指南》 - 快速生成初始化代码
  2. 《电机控制从入门到精通》 - 深入讲解H桥与驱动技术

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号