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-

      注意:L298N电机驱动模块本身并没有内置的限流保护功能,使用前需要做限流保护,否则可能会烧坏模块或电机。

    效果展示

    六、参考示例

    main.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

    #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);
    	}
    }
    
    

    作者:优信电子

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32F103控制L298N驱动两相四线步进电机详解

    发表回复