基于STM32F103控制L298N驱动两相四线步进电机

文章目录


前言

  L298N 是一种常见的双 H 桥电机驱动模块,广泛用于驱动直流电机和步进电机。它基于 ST 的 L298N 芯片,具有高电流承载能力和灵活的控制模式,适合机器人、自动化设备等领域。

一、模块参数

1、驱动芯片:L298N 双 H 桥直流电机驱动芯片

2、驱动电压 Vs:+5V~+35V ; 如需要板内取电,则供电范围Vs:+7V~+35V

3、驱动电流Io:2A(MAX)

4、逻辑电压Vss:+5V~+7V(可板内取电+5V)

5、逻辑电流:0~36mA

6、控制信号输入电压范围:

  低电平:-0.3V≤Vin≤1.5V

  高电平:2.3V≤Vin≤Vss

7、使能信号输入电压范围:

  低电平:-0.3≤Vin≤1.5V(控制信号无效)

  高电平:2.3V≤Vin≤Vss(控制信号有效)

8、最大功耗:20W(温度 T=75℃时)

9、存储温度:-25℃~+130℃

二、接口说明

关于模块供电说明:

  供电一:板上除了L298N外,还有7805的5V稳压芯片,当供电为5V到7V区间的时候模块内置的7805芯片不能正常工作的。所以供电端接5-7V外部电源只负责给电机供电,然后逻辑端外接5V逻辑电源。

  供电二:当供电电压为7-12V时,插上板载5V使能的跳线帽,此时的逻辑端不但不用外接5V电源,还可以输出5V为单片机进行供电。

  供电三:当供电在大于12V的时候,此时必须断开板载5V使能跳线帽,再在逻辑端子接入5V电源给芯片供电。如果不断开板载使能跳线帽的话,可能会损坏内置的7805的稳压芯片。

  注意:板子没有升降压功能,供电范围要根据接的电机选择,避免供电过低过高带不动电机或烧坏电机,如驱动12V的电机,则接12V的电源。

三、准备工作

  STM32F103最小系统板、L298N驱动模块、2个直流电机或1个两相四线步进电机、EC11旋转编码器模块以及供电电源。

四、直流电机驱动

  该驱动板可驱动 2 路直流电机,使能端 ENA、ENB 为高电平时有效,控制方式及直流电机状态表如下所示:

  若要对直流电机进行 PWM 调速,需设置 IN1 和 IN2,确定电机的转动方向,然后对使能端输出 PWM 脉冲,即可实现调速。注意当使能信号为 0 时,电机处于自由停止状态;当使能信号为 1,且 IN1 和 IN2 为 00 或 11 时,电机处于制动状态,阻止电机转动。IN1和IN2控制输出A,IN3和IN4控制输出B。

引脚接线

L298N STM32F103 / 电源 / 直流电机
输出A,B 连接电机1,2
12V供电 电源正
供电GND 电源负
旋转编码器A,B,S PB3,PB1,PB0
通道A,B使能 去掉跳线帽,使能A接PA6,使能B接PA7 ,PWM调速
IN1,IN2 PA0,PA1
IN3,IN4 PA2,PA3

效果展示

五、两相四线步进电机驱动

步进电机相关概念

  相数------步进电机的N、S磁场的激磁线圈对数,如两相四线步进电机,就有两对极N、S磁场的激磁线圈,四线A+、A-、B+、B-,A+A-,B+B-是连通的,在不知道四线哪两两线为一对激磁线圈,通过短接两两线有明显阻力变化的则为一对线圈。

  拍数------转子转动一周,定子绕组通电的次数,以两相电机为例,有两相四拍运行方式即(A+)---(B+)---(A-)---(B-),两相八拍运行方式(A+)---(A+B+)---(B+)--(B+A-)---(A-)---(A-B-)---(B-)--(B-A+),以此循环。

  步距角------步进电机接收到一个脉冲信号后,驱动电机按设定的方向转动的一个固定角度。如两相四线步进电机的基本步距角是1.8°,即一个脉冲走1.8°。

  同时,为了减弱或消除步进电机的低频振动开发了细分驱动技术。细分后电机运行时的实际步距角是基本步距角的几分之一,微步即1/4-step、1/8-step、1/16-step等。 比如,两相步进电机的基本步距角是1.8°,如果没有细分,则是200个脉冲走一圈360°。细分是通过驱动器靠精确控制电机的相电流所产生的,如果是10细分,则发一个脉冲电机走0.18°,即2000个脉冲走一圈360°,电机的精度能否达到或接近0.18°,还取决于细分驱动器的细分电流控制精度等其它因素。

细分驱动 单圈步数=360°÷角度
四拍(1细分) 1.8°------ 单圈200步
八拍(2细分) 0.9°------ 单圈400步
十六拍(4细分) 0.45°------ 单圈800步
三十二拍(8细分) 0.225°------ 单圈1600步
六十四拍(16细分) 0.1125°------ 单圈3200步

拍数驱动时序

  单4拍(整步)方式驱动时序

  双4拍(整步)方式驱动时序

  电机转动方向如下所示,(A+)---(B+)---(A-)---(B-),以此循环,

特性 单四拍 双四拍
通电相数 每次一相 每次两相
功耗 较低 较高
步进角 一致 一致
力矩 较小 较大
定位稳定性 一般 更高

  8拍(半步)方式驱动时序

  电机转动方向如下所示,(A+)---(A+B+)---(B+)--(B+A-)---(A-)---(A-B-)---(B-)---(B-A+),以此循环,

  反转时,控制时序倒过来控制就可实现反向转动。

引脚接线

L298N STM32F103 / 电源 / 两相四线电机
12V供电 电源正
供电GND 电源负
旋转编码器A,B,S PB3,PB1,PB0
通道A,B使能 把跳线帽插回去
IN1,IN2 PA0,PA1
IN3,IN4 PA2,PA3
OUT1,OUT2 A+,A-
OUT3,OUT4 B+,B-

效果展示

六、参考示例

main.c

c 复制代码
#include "stm32f10x.h"                  // Device header
#include "encoder.h"
#include "l298n.h"
#include "usart.h"
#include "timer.h"
#include "pwm.h"

int32_t RxData;

int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	usart_Init();
	L298N_Init();
	Encoder_Init();
	Timer_Inti();
	PWM_Init();
	
	
	while(1)
	{		
		RxData =Encoder_Get();
		
		//直流电机控制正反转,调速
		TIM_SetCompare1(TIM3,RxData);
		
		if(Encoder_GetKey() == 0)
		{
			Motor1_Zturn();
			Motor2_Zturn();
		}else{
			Motor1_Rturn();
			Motor2_Rturn();
		}
		
		//步进电机控制正反转
//		if(Encoder_GetKey() == 0)
//		{
//			switch(RxData)
//			{
//				case 1:
//					ZturndouControl_4();
//					break;
//				case 2:
//					RturndouControl_4();
//					break;
//			}
//		}else{
//			switch(RxData)
//			{
//				case 1:
//					ZturnControl_8();
//					break;
//				case 2:
//					RturnControl_8();
//					break;
//			}
//		}
	}
}

l298n.c

c 复制代码
#include "l298n.h"
#include "delay.h"
#include "timer.h"

void L298N_Init(void)
{
	//通过旋转编码器控制步进电机正转,翻转,加减速,停止
	GPIO_InitTypeDef GPIO_InitStructurn;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitStructurn.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructurn.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
	GPIO_InitStructurn.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructurn);
}

void Motor1_Stop(void)	//电机1停止
{
	IN1(0);
	IN2(0);
}

void Motor2_Stop(void)	//电机2停止
{
	IN3(0);
	IN4(0);
}

void ALL_Stop(void)	//两个电机全停止
{
	IN1(0);
	IN2(0);
	IN3(0);
	IN4(0);
}

void Motor1_Zturn(void)	//电机1正转
{
	IN1(1);
	IN2(0);
}

void Motor1_Rturn(void)	//电机1反转
{
	IN1(0);
	IN2(1);
}

void Motor2_Zturn(void)	//电机2正转
{
	IN3(1);
	IN4(0);
}

void Motor2_Rturn(void)	//电机2反转
{
	IN3(0);
	IN4(1);
}

void Control_4(void)	//单四拍
{
	if(Timer_GetCounter()<2500)
	{
		IN1(1);IN2(0);IN3(0);IN4(0);
		delay_ms(10);
	}else if(Timer_GetCounter()>2500 && Timer_GetCounter()<5000)
	{
		IN1(0);IN2(1);IN3(0);IN4(0);
		delay_ms(10);
	}else if(Timer_GetCounter()>5000 && Timer_GetCounter()<7500)
	{
		IN1(0);IN2(0);IN3(1);IN4(0);
		delay_ms(10);
	}else if(Timer_GetCounter()>7500 && Timer_GetCounter()<10000)
	{
		IN1(0);IN2(0);IN3(0);IN4(1);
		delay_ms(10);
	}
}

void ZturndouControl_4(void)	//正双四拍
{
	if(Timer_GetCounter()<2500)
	{
		IN1(0);IN2(1);IN3(1);IN4(0);
		delay_ms(10);
	}else if(Timer_GetCounter()>2500 && Timer_GetCounter()<5000)
	{
		IN1(0);IN2(1);IN3(0);IN4(1);
		delay_ms(10);
	}else if(Timer_GetCounter()>5000 && Timer_GetCounter()<7500)
	{
		IN1(1);IN2(0);IN3(0);IN4(1);
		delay_ms(10);
	}else if(Timer_GetCounter()>7500 && Timer_GetCounter()<10000)
	{
		IN1(1);IN2(0);IN3(1);IN4(0);
		delay_ms(10);
	}
}

void RturndouControl_4(void)	//反双四拍
{
	if(Timer_GetCounter()<2500)
	{
		IN1(1);IN2(0);IN3(1);IN4(0);
		delay_ms(10);
	}else if(Timer_GetCounter()>2500 && Timer_GetCounter()<5000)
	{
		IN1(1);IN2(0);IN3(0);IN4(1);
		delay_ms(10);
	}else if(Timer_GetCounter()>5000 && Timer_GetCounter()<7500)
	{
		IN1(0);IN2(1);IN3(0);IN4(1);
		delay_ms(10);
	}else if(Timer_GetCounter()>7500 && Timer_GetCounter()<10000)
	{
		IN1(0);IN2(1);IN3(1);IN4(0);
		delay_ms(10);
	}
}

void ZturnControl_8(void)	//正八拍
{
	if(Timer_GetCounter()<1250)
	{
		IN1(1);IN2(0);IN3(0);IN4(0);
		delay_ms(10);
	}else if(Timer_GetCounter()>1250 && Timer_GetCounter()<2500)
	{
		IN1(1);IN2(0);IN3(1);IN4(0);
		delay_ms(10);
	}else if(Timer_GetCounter()>2500 && Timer_GetCounter()<3750)
	{
		IN1(0);IN2(0);IN3(1);IN4(0);
		delay_ms(10);
	}else if(Timer_GetCounter()>3750 && Timer_GetCounter()<5000)
	{
		IN1(0);IN2(1);IN3(1);IN4(0);
		delay_ms(10);
	}else if(Timer_GetCounter()>5000 && Timer_GetCounter()<6250)
	{
		IN1(0);IN2(1);IN3(0);IN4(0);
		delay_ms(10);
	}else if(Timer_GetCounter()>6250 && Timer_GetCounter()<7500)
	{
		IN1(0);IN2(1);IN3(0);IN4(1);
		delay_ms(10);
	}else if(Timer_GetCounter()>7500 && Timer_GetCounter()<8750)
	{
		IN1(0);IN2(0);IN3(0);IN4(1);
		delay_ms(10);
	}else if(Timer_GetCounter()>8750 && Timer_GetCounter()<10000)
	{
		IN1(1);IN2(0);IN3(0);IN4(1);
		delay_ms(10);
	}
}

void RturnControl_8(void)	//反八拍
{
	if(Timer_GetCounter()<1250)
	{
		IN1(1);IN2(0);IN3(0);IN4(1);
		delay_ms(10);
	}else if(Timer_GetCounter()>1250 && Timer_GetCounter()<2500)
	{
		IN1(0);IN2(0);IN3(0);IN4(1);
		delay_ms(10);
	}else if(Timer_GetCounter()>2500 && Timer_GetCounter()<3750)
	{
		IN1(0);IN2(1);IN3(0);IN4(1);
		delay_ms(10);
	}else if(Timer_GetCounter()>3750 && Timer_GetCounter()<5000)
	{
		IN1(0);IN2(1);IN3(0);IN4(0);
		delay_ms(10);
	}else if(Timer_GetCounter()>5000 && Timer_GetCounter()<6250)
	{
		IN1(0);IN2(1);IN3(1);IN4(0);
		delay_ms(10);
	}else if(Timer_GetCounter()>6250 && Timer_GetCounter()<7500)
	{
		IN1(0);IN2(0);IN3(1);IN4(0);
		delay_ms(10);
	}else if(Timer_GetCounter()>7500 && Timer_GetCounter()<8750)
	{
		IN1(1);IN2(0);IN3(1);IN4(0);
		delay_ms(10);
	}else if(Timer_GetCounter()>8750 && Timer_GetCounter()<10000)
	{
		IN1(1);IN2(0);IN3(0);IN4(0);
		delay_ms(10);
	}
}
相关推荐
HQB202610 小时前
EG1198|屹晶微电子 120V 内置 MOS 异步降压 DC‑DC(高性价比)
嵌入式硬件·硬件工程
果壳science11 小时前
张祥前实验如何获取正电荷
笔记·科技·嵌入式硬件·硬件工程·制造
南山电子nscn11 小时前
中科芯CETC汽车电池管理系统BMS进口芯片国产型号替代指南
单片机·汽车·bms
沉淀的.晴天12 小时前
can总线
stm32
桀人12 小时前
认识AT24C02
stm32·单片机·嵌入式硬件
国科安芯13 小时前
星间激光通信终端CANFD控制网络的时延确定性与辐射可靠性
网络·嵌入式硬件·信息与通信·canfd·低轨卫星·商业航天·抗辐射
一直C13 小时前
嵌入式 Linux 驱动开发学习笔记:内核定时器、platform 总线与 I²C 驱动
linux·驱动开发·嵌入式硬件·学习·imx6ull
传感器与混合集成电路14 小时前
150MHz主频、8路DAC与6路PWM:JLH221360伺服控制SIP解析
嵌入式硬件
comyccccc14 小时前
STM32PID控制板设计全解析学习笔记
单片机·嵌入式硬件
碧海银沙音频科技研究院15 小时前
实现炬芯ATS308X的usb cdc 串口IAP 固件升级功能实现
人工智能·嵌入式硬件·深度学习·算法