由于单片机内部结构原因,其等效内阻极大, 导致输出电流极小,输出功率极小,无法满足直流电机的额定功率,所以我们一般只把单片机当控制器,而不是驱动器。
模块介绍
L298N芯片是ST公司生产的一种高电压、大电流双全桥式的电机驱动芯片。该芯片采用15脚封装,具有驱动能力强,发热量低,抗干扰能力强的特点。
特点
工作电压高,最高工作电压可达46V
输出电流大,瞬间峰值电流可达3A,持续工作电流为2A
低静态电压
过热保护逻辑0电平高至1.5V(高抗扰度)
在L298N芯片基础上,本模块使用大容量滤波电容,续流保护二极管,可以提高可靠性。
硬件特性
驱动部分端子供电范围 | Vs:+5V~+35V;如需要板内取电,则供电范围+7V~+35V |
驱动部分峰值电流 | Io: 2A(MAX单桥) |
逻辑部分端子供电范围 | Vss: +5V~+7V(可板内取电+5V) |
逻辑部分工作电流范围: | 0~36mA |
控制信号输入电压范围 | 低电平:-0.3V≤Vin≤1.5V 高电平:2.3V≤Vin≤Vss |
使能信号输入电压范围 | 低电平:-0.3≤Vin≤1.5V(控制信号无效) 高电平:2.3V≤Vin≤Vss(控制信号有效) |
最大功耗 | 25W(温度T=75℃时) |
存储温度 | -25℃~+130℃ |
驱动板尺寸 | 43*43*27mm |
驱动板重量 | 30g |
参数最大值
更多内容见参考手册(移至本博客最后)
引脚接线
共14个接线端
A相:通道A输出io1,io2,A相使能,输入1,2
B相:通道B输出io1,io2,B相使能,输入3,4
电源:主电源正极,负极,5V输入,内置5V降压器开关
以A相为例来学习接线
输出端口
通道A输出io1,io2接入电机的端口
控制信号
ENA:使能端-高电平使能,接入电源并且ENA接高电平,电机驱动模块才输出电流给电机
如果只是控制电机正反转,那么ENA跳线帽不要断。接入IN1,IN2就可控制转向,具体见下方表格
Motor1 | 状态 | ||
ENA | IN1 | IN2 | |
1 | 1 | 0 | 正转 |
1 | 0 | 1 | 反转 |
1 | 1 | 1 | 制动 |
1 | 0 | 0 | 制动 |
0 | X | X | 停止 |
注:Motor2对应ENB,IN3,IN4
如果还要控制转速,有两种接线方式
- ENA跳线帽断开,不要接模块的VCC,将其接入单片机IO口
- ENA跳线帽不要断,接入IN1,IN2,给IN1或者IN2其中一个端口输入PWM即可
供电说明
由接线图和最大值表格知道:主电源正极缩写为Vs
5V供电
Vs=5V :单片机引出的5V供电,断开内置5V降压器开关的跳线帽,驱动模块的主电源和5V输入端都接单片机的5V,GND接单片机的GND(这样可以动,但轮子转动的速度不快)
建议使用常规应用的电压范围
常规应用
7V< Vs <12V:(板子背面标识为12V输入,实际可以接受的输入范围是7-12V),插上内置5V降压器开关的跳线帽,使用板载的78M05供给芯片的逻辑电源,可以不用再外接逻辑电源,但是可以引出5V电压供外部使用。
高压驱动的非常规应用
12V< Vs <=24V:(芯片手册中提出可以支持到35V,但是按照经验一般L298保守应用MAX电压支持到24V已经很了不起),比如要驱动额定电压为18V的电机。首先必须拔掉5V降压器开关的跳线帽,不使用板载的78M05供给芯片的逻辑电源,然后在5V输出端口外部接入5V电压对L298N内部逻辑电路供电。
注意事项
L298N供电的5V如果是用另外电源供电的话,(即不是和单片机的电源共用),那么需要将单片机的GND和模块上的GND连接在一起,只有这样单片机上过来的逻辑信号才有个参考0点。板载5V稳压芯片的输入引脚和电机供电驱动接线端子导通的
驱动代码
PWM.h
#ifndef __PWM_H_
#define __PWM_H_
void PWM_Init(void);
void PWM_SetCompare3(uint16_t Compare3);
#endif
PWM.c
#include "stm32f10x.h" // Device header
#include "PWM.h"
void PWM_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PWM
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_InternalClockConfig(TIM2);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 100 - 1; //ARR
TIM_TimeBaseInitStructure.TIM_Prescaler = 36 - 1; //PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0; //CCR
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
TIM_Cmd(TIM2, ENABLE);
}
void PWM_SetCompare3(uint16_t Compare3)
{
TIM_SetCompare3(TIM2, Compare3);
}
L298N.h
#ifndef __MOTOR_H
#define __MOTOR_H
void L298N_Motor_Init(void);
void L298NMotor_SetSpeed(int8_t Speed);
#endif
L298N.c
#include "stm32f10x.h" // Device header
#include "PWM.h"
#include "L298N.h"
void L298N_Motor_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
PWM_Init();
}
void L298NMotor_SetSpeed(int8_t Speed)
{
if (Speed >= 0)
{
GPIO_SetBits(GPIOA, GPIO_Pin_4);
GPIO_ResetBits(GPIOA, GPIO_Pin_5);
PWM_SetCompare3(Speed);
}
else
{
GPIO_ResetBits(GPIOA, GPIO_Pin_4);
GPIO_SetBits(GPIOA, GPIO_Pin_5);
PWM_SetCompare3(-Speed);
}
}
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Key.h"
#include "L298N.h"
uint8_t KeyNum;
int8_t Compare=0;
int main(void)
{
OLED_Init();
Key_Init();
L298N_Motor_Init();
OLED_ShowString(1,1,"Motor:+000");
while (1)
{
KeyNum=Key_GetNum();
if(KeyNum==1)
{
Compare+=30;
if(Compare>60)
{
Compare=-60;
}
OLED_ShowSignedNum(1,7,Compare,3);
L298NMotor_SetSpeed(Compare);
}
}
}
参考手册: