STM32驱动 28BYJ-48 步进电机 (4相5线8拍5.625/64)

发布时间:2024年01月06日


电动机是获取动力的来源之一,在某些特殊的应用中,精确地控制电动机的转动角度是控制的难点,如想让电动机转动三周半,这对于普通的直流电动机来说是很难实现的,而步进电动机则不同,它只需要几个简单的控制脉冲即可轻而易举地实现这样的操控过程。步进电动机就是这样一种能“听话”的电动机,它在微处理器的控制下可以产生精确的角位移,使其在诸如打印机、传真机等精密设备中有广泛的应用。

常见的电动机都是连续转动的,而步进电动机的转动则是分步进行的,步进电动机也因此而得名。步进电动机是一种将电脉冲转化为角位移的执行机构,当步进驱动器接收到一个脉冲信号后,就会驱动电动机按设定的方向转动一个固定的角度,通过控制脉冲的个数来控制角位移量,从而达到准确定位的目的。另外,通过控制驱动脉冲的频率,还可以控制电动机转动的速度。

步进电动机在构造上有三种主要类型,即反应式永磁式混合式

1)反应式(VR):定子上有线圈,转子由软磁材料组成。反应式步进电动机具有结构简单、成本低、步距角小的优点,但其动态性能差、效率低、发热量大、可靠性较难保证。

2)永磁式(PM):永磁式步进电动机的转子用永磁材料制成,转子的极数与定子的极数相同。永磁式步进电动机的特点是动态性能好、输出力矩大,但这种电动机精度差步矩角大,一般为7.5°或15°。

3)混合式(HS):混合式步进电动机综合了反应式和永磁式的优点,其定子上有多相线圈,转子采用永磁材料,转子和定子上均有多个小齿以提高步距精度。混合式步进电动机的特点是输出力矩大、动态性能好、步距角小,但其结构复杂、成本相对较高。


第一部分:28BYJ-48

在这里插入图片描述


工作原理

【B站】STM32控制ULN2003驱动板-驱动28BYJ48步进电机

在这里插入图片描述

这种电动机的转子上有六个凸齿,但没有线圈缠绕,而定子上有八个凸齿,每一个凸齿上均绕有一组线圈。定子线圈的连接方式是在对称齿上的两个线圈进行反相连接,八个齿构成四对,所以称为四相步进电动机

在这里插入图片描述

步进电动机的工作原理:

1)当步进电动机的A相线圈被激励时,磁通从定子的正相齿,经过软铁心的转子,以最短的路径流向负相齿。为使磁通路径最短,在磁场力的作用下,转子被强迫移动,使最近的一对齿与被激励的一相对准,其状态如图a所示。

2)在这个位置的基础上,驱动器再次对B相进行激励,这时离B相最接近的转子上的凸齿被吸引,转子会逆时针转动15°,其状态如图b所示。此时若是D相被激励,则转子会顺时针转动15°,其状态如图c所示。

3)按照驱动的顺序,当C相被激励时,转子会按照前一步的运动方向继续转动15°。

通过上面的介绍,我们对步进电动机的驱动已经有一个基本的理解了。通过控制不同相的驱动顺序,可以改变步进电动机的转动方向,驱动脉冲的个数会决定电动机转动的角度,而两个驱动脉冲的时间间隔决定了电动机的转动速度


主要参数

步进电动机的静态技术指标主要有以下几项:

1.相数:产生不同对N、S极磁场的激磁线圈的对数。

2.拍数:完成一个磁场周期性变化所需脉冲数或转过一个齿距角所需脉冲数。

3.步距角:单个脉冲信号驱动电动机转子转动的角位移量。

步距角的计算方法

在这里插入图片描述
在这里插入图片描述

电动机步距角(步长)是步进电动机的主要性能指标之一,不同的应用场合对步距角大小的要求不同,步距角越小,步进电动机的转动控制就越精确。改变步进电动机的相数(线圈数)或转子的极数(齿数)可以改变步距角的大小。它们之间的相互关系可由下式计算:

步距角=360 ÷(相数×齿数)

在这里插入图片描述

以图中所示的步进电动机为例,相数为4、齿数为6,经计算步距角为15°,电动机转一圈需要24步。

在以上众多参数中,单片机软件开发时,最需要了解的参数即为 步距角。
步距角=5.625°/64,其意思就是每64个脉冲步进电机就会转5.625度

因此可以很容易的得出旋转角度与脉冲之间的计算公式:pulse=(angle/5.625) * 64划重点)。

例如让电机转一圈有360°,那么转一圈的脉冲数为 (360 / 5.625) * 64 = 4096个脉冲。

已知:步距角为5.625/64,即内轴64个脉冲(8步8圈)外轴旋转5.625度;
已知:外轴1圈有360度,得 360/5.625=64(也就是一圈需要64个5.625度);
因此得:64 * 64 = 4096, 即内轴4096个脉冲,外轴旋转1圈。

已知:8步就是8个脉冲;
又已知:8次循环,内轴电机旋转1圈;
已知:8 * 8 = 64,64个脉冲内轴电机旋转1圈;64个脉冲,外轴旋转5.625度。
还已知:减速比为1:64,内轴旋转64圈,外轴旋转1圈;
求:外轴旋转1圈需要多少个脉冲?

什么是28BYJ-48?

28BYJ-48 – 5V 步进电机 28BYJ-48 是一款小型步进电机,适用于多种应用。

  • 28:电机的直径;
  • B: 表示步进电机;
  • Y:表示永磁体;
  • J:表示减速电机;
  • 4:表示4相;
  • 8:表示8拍;

28BYJ-48 主要参数

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


第二部分:驱动

在自动控制中会有很多被控器件,如继电器、电动机、电磁阀、压缩机等,这些设备通常由CPU控制,由于控制系统不能直接驱动被控器件,需要由功率驱动电路来扩展输出电流,以满足被控器件的控制需求。ULN2003高压大电流达林顿晶体管阵列就属于这类可控大功率器件,特别是在步进电动机的驱动上有广泛的应用。

ULN2003A 驱动芯片

ULN2003是高耐压、大电流达林顿阵列,由七个硅NPN达林顿管组成,具有电流增益高、工作电压高、温度范围宽、带负载能力强等特点,适应于各类要求高速大功率驱动的系统。

在这里插入图片描述
ULN2003引脚功能:
在这里插入图片描述

在这里插入图片描述

ULN2003是反向驱动电路,即当输入端为高电平时输出端为低电平,其内部由七个硅NPN达林顿管组成,每一组达林顿复合管都串联了一个2.7kΩ的基极电阻,在5V的工作电压下能与TTL和CMOS电路直接相连,而无需桥接数据缓冲器。输出端采用集电极开路输出,输出电流可达500mA,内部集成了保护二极管,可以用来驱动继电器等感性负载。COM端是内部7个二极管负极的公共端,各二极管的正极分别接各达林顿管的集电极。用于感性负载时,该引脚接负载电源正极,以实现续流作用。

ULN2003的驱动电路

通常使用单片机驱动ULN2003时,需要将I/O口上拉到VCC,上拉电阻选用2kΩ较为合适。另外,由于ULN2003是集电极开路输出,为了让这个二极管起到续流作用,必须将COM引脚接在负载的供电电源上,只有这样才能够形成续流回路。由ULN2003构成的步进电动机驱动电路如图。

在这里插入图片描述

加油站: 弱上拉和强上拉

上拉是指通过一个连接在I/O口和电源之间的电阻将不确定为高电平或高电平驱动能力弱的电位控制在高电平。上拉电阻越小,驱动能力越强,功耗也越大。上拉电阻的取值为1~10kΩ。一般来说当上拉电阻较时,可以称之为强上拉,反之称其为弱上拉。

在这里插入图片描述


第三部分: 程序

MCU(程序) + 驱动芯片 + 28BYJ-48

【B站】STM32控制ULN2003驱动板-驱动28BYJ48步进电机

步进电机驱动方式:

1)1相励磁。这种励磁方式也称为单4拍工作方式,是指在某一驱动瞬间,步进电动机只有一相导通,驱动器每发送一个励磁信号,步进电动机就旋转一个步距角。这种驱动方式的特点是电能消耗小,但输出力矩小振动大

2)1-2相励磁。这种励磁方式也称为单双8拍工作方式,是指在某一驱动瞬间,步进电动机的某一相或某两相交替导通,驱动器每发送一个励磁信号,步进电动机只旋转半个步距角。这种驱动方式的特点是转动精度高、运行平稳,是大多数步进电动机理想的工作方式。

在这里插入图片描述

一般對力矩要求高使用2相勵磁(4相4拍),對精度要求高使用1-2相勵磁(4相8拍)

【B站】步进电机28BYJ-48的结构、原理及控制(Arduino和ULN2003)

在这里插入图片描述

参考程序

Motor.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"

void 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_3 | GPIO_Pin_4|GPIO_Pin_5 | GPIO_Pin_6;    //PA3,PA4,PA5,PA6控制步进驱动引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
}


//1相励磁函数,A-B-C-D    

void Motor_One(uint16_t speed)
{
	GPIO_SetBits(GPIOA,GPIO_Pin_3);
	GPIO_ResetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5 | GPIO_Pin_6);	
	Delay_ms(speed);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_4);
	GPIO_ResetBits(GPIOA,GPIO_Pin_3|GPIO_Pin_5 | GPIO_Pin_6);	
	Delay_ms(speed);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_5);
	GPIO_ResetBits(GPIOA,GPIO_Pin_3|GPIO_Pin_4 | GPIO_Pin_6);	
	Delay_ms(speed);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_6);
	GPIO_ResetBits(GPIOA,GPIO_Pin_3|GPIO_Pin_4 | GPIO_Pin_5);	
	Delay_ms(speed);

}



//2相励磁函数   AB-BC-CD-DA

void Motor_two(uint16_t speed)
{	
	GPIO_SetBits(GPIOA,GPIO_Pin_3|GPIO_Pin_4);
	GPIO_ResetBits(GPIOA,GPIO_Pin_5 | GPIO_Pin_6);	
	Delay_ms(speed);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5);
	GPIO_ResetBits(GPIOA,GPIO_Pin_3 | GPIO_Pin_6);	
	Delay_ms(speed);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6);
	GPIO_ResetBits(GPIOA,GPIO_Pin_3 | GPIO_Pin_4);	
	Delay_ms(speed);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_6|GPIO_Pin_3);
	GPIO_ResetBits(GPIOA,GPIO_Pin_4 | GPIO_Pin_5);	
	Delay_ms(speed);

	
}


//1.2混合励磁函数  A-AB-B-BC-C-CD-D-DA

void Motor_one_two(uint16_t speed)
{
	GPIO_SetBits(GPIOA,GPIO_Pin_3);
	GPIO_ResetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5 | GPIO_Pin_6);	
	Delay_ms(speed);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_3|GPIO_Pin_4);
	GPIO_ResetBits(GPIOA,GPIO_Pin_5 | GPIO_Pin_6);	
	Delay_ms(speed);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_4);
	GPIO_ResetBits(GPIOA,GPIO_Pin_3|GPIO_Pin_5 | GPIO_Pin_6);	
	Delay_ms(speed);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5);
	GPIO_ResetBits(GPIOA,GPIO_Pin_3 | GPIO_Pin_6);	
	Delay_ms(speed);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_5);
	GPIO_ResetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_4 | GPIO_Pin_6);	
	Delay_ms(speed);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6);
	GPIO_ResetBits(GPIOA,GPIO_Pin_3 | GPIO_Pin_4);	
	Delay_ms(speed);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_6);
	GPIO_ResetBits(GPIOA,GPIO_Pin_3|GPIO_Pin_4 | GPIO_Pin_5);	
	Delay_ms(speed);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_6|GPIO_Pin_3);
	GPIO_ResetBits(GPIOA,GPIO_Pin_4 | GPIO_Pin_5);	
	Delay_ms(speed);
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Motor.h"
#include "Key.h"

uint8_t n;
uint16_t num=0;

int main(void)
{
		Motor_Init();
    Key_Init();
	
	while (1)
	{
		if(num==1)
		{
			for(int i=0;i<=(8*64);i++)        //8次循环电机旋转一周,外轴减速比1:64,还需要*64
			{
				Motor_One(5);
//				Motor_two(5);
//				Motor_one_two(5);
			}

			num=0;
			GPIO_ResetBits(GPIOA,GPIO_Pin_3|GPIO_Pin_4 |GPIO_Pin_5| GPIO_Pin_6);
		}
	}
}




void EXTI0_IRQHandler(void)        //按键中断,修改标志位                      
{
	if (EXTI_GetITStatus(EXTI_Line0) == SET)
	{ 
		EXTI_ClearITPendingBit(EXTI_Line0);
		if(num==1)
				  return;
		
		else	
			num=1;
	  		  
	}
}











资料下载


参考资料

文章来源:https://blog.csdn.net/Naiva/article/details/135416800
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。