目录
一、介绍
步进电机(STEP MOTOR)把电脉冲信号变换成角位移以控制转子转动的执行机构。在自动控制装置中作为执行器。每输入一个脉冲信号,步进电动机前进一步,故又称脉冲电动机。步进电动机多用于数字式计算机的外部设备,以及打印机、绘图机和磁盘等装置。
以下是28BYJ48步进电机的参数:
型号 | 28BYJ48 |
工作电压 | 5V |
直径 | 28mm |
减速比 | 1:64 |
驱动方式 | ULN2003 |
相电阻 | 50±10% |
步进角度 | 5.625°/64 |
型号代表含义:
28——最大外径是28毫米
B——表示是步进电机
Y——表示是永磁式
J——表示是减速型
48——表示四相八拍
哔哩哔哩视频演示:
28BYJ-48步进电机详解(五线四相 STM32)
(资料分享见文末)
二、模块原理
1.工作原理介绍
步进电机通过一系列离散的步进动作来实现旋转。每个电脉冲信号驱动电机转动一个固定的角度,称为步距角。步进电机的控制通常通过一个驱动器(步进驱动器)来完成,该驱动器接受来自控制器的脉冲信号,并将其转换为步进电机的相位信号,从而驱动电机按预定的步进角度转动。
2.ULN2003驱动模块原理图
3.引脚描述
引脚名称 | 描述 |
VCC | 供给电压DC 5V |
IN1 | 驱动信号1 |
IN2 | 驱动信号2 |
IN3 | 驱动信号3 |
IN4 | 驱动信号4 |
三、程序设计
使用STM32F103C8T6通过ULN2003驱动板驱动步进电机使其完成正反转动作。
IN1 | PA1 |
IN2 | PA2 |
IN3 | PA3 |
IN4 | PA4 |
main.c文件
#include "stm32f10x.h"
#include "led.h"
#include "usart.h"
#include "delay.h"
#include "oled.h"
#include "stepmotor.h"
/*****************辰哥单片机设计******************
STM32
* 项目 : 28BYJ-48步进电机实验
* 版本 : V1.0
* 日期 : 2024.8.31
* MCU : STM32F103C8T6
* 接口 : 参看stepmotor.h
* BILIBILI : 辰哥单片机设计
* CSDN : 辰哥单片机设计
* 作者 : 辰哥
**********************BEGIN***********************/
float co2;
u8 buff[30];//参数显示缓存数组
int main(void)
{
SystemInit();//配置系统时钟为72M
delay_init(72);
LED_Init();
LED_On();
MOTOR_Init();
USART1_Config();//串口初始化
OLED_Init();
printf("Start \n");
delay_ms(1000);
OLED_Clear();
while (1)
{
MOTOR_Direction_Angle(1,0,90,1);
delay_ms(1000);
MOTOR_Direction_Angle(0,0,90,1);
delay_ms(1000);
}
}
stepmotor.h文件
#ifndef __STEPMOTOR_H
#define __STEPMOTOR_H
#include "stm32f10x.h"
#include "delay.h"
#include "sys.h"
/*****************辰哥单片机设计******************
STM32
* 文件 : 28BYJ-48步进电机h文件
* 版本 : V1.0
* 日期 : 2024.8.31
* MCU : STM32F103C8T6
* 接口 : 见代码
* BILIBILI : 辰哥单片机设计
* CSDN : 辰哥单片机设计
* 作者 : 辰哥
**********************BEGIN***********************/
/***************根据自己需求更改****************/
// 步进电机 GPIO宏定义
#define MOTOR_CLK RCC_APB2Periph_GPIOA
#define MOTOR_A GPIO_Pin_1
#define MOTOR_B GPIO_Pin_2
#define MOTOR_C GPIO_Pin_3
#define MOTOR_D GPIO_Pin_4
#define MOTOR_PROT GPIOA
#define MOTOR_A_HIGH GPIO_SetBits(MOTOR_PROT,MOTOR_A)
#define MOTOR_A_LOW GPIO_ResetBits(MOTOR_PROT,MOTOR_A)
#define MOTOR_B_HIGH GPIO_SetBits(MOTOR_PROT,MOTOR_B)
#define MOTOR_B_LOW GPIO_ResetBits(MOTOR_PROT,MOTOR_B)
#define MOTOR_C_HIGH GPIO_SetBits(MOTOR_PROT,MOTOR_C)
#define MOTOR_C_LOW GPIO_ResetBits(MOTOR_PROT,MOTOR_C)
#define MOTOR_D_HIGH GPIO_SetBits(MOTOR_PROT,MOTOR_D)
#define MOTOR_D_LOW GPIO_ResetBits(MOTOR_PROT,MOTOR_D)
/*********************END**********************/
void MOTOR_Init(void);
void MOTOR_Rhythm_4_1_4(u8 step,u8 dly);
void MOTOR_Direction(u8 dir,u8 num,u8 dly);
void MOTOR_Direction_Angle(u8 dir,u8 num,u16 angle,u8 dly);
void MOTOR_STOP(void);
#endif
stepmotor.c文件
#include "stepmotor.h"
/*****************辰哥单片机设计******************
STM32
* 文件 : 28BYJ-48步进电机c文件
* 版本 : V1.0
* 日期 : 2024.8.31
* MCU : STM32F103C8T6
* 接口 : 见代码
* BILIBILI : 辰哥单片机设计
* CSDN : 辰哥单片机设计
* 作者 : 辰哥
**********************BEGIN***********************/
void MOTOR_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(MOTOR_CLK, ENABLE ); //配置复用时钟
GPIO_InitStructure.GPIO_Pin = MOTOR_A|MOTOR_B|MOTOR_C|MOTOR_D;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(MOTOR_PROT,&GPIO_InitStructure);
GPIO_ResetBits(GPIOA, MOTOR_A|MOTOR_D|MOTOR_B|MOTOR_C);
}
void MOTOR_Rhythm_4_1_4(uint8_t step,uint8_t dly)
{
switch(step)
{
case 0 :
;;
break;
case 1 :
MOTOR_A_LOW;MOTOR_B_HIGH;MOTOR_C_HIGH;MOTOR_D_HIGH; //1
break;
case 2 :
MOTOR_A_HIGH;MOTOR_B_LOW;MOTOR_C_HIGH;MOTOR_D_HIGH; //2
break;
case 3 :
MOTOR_A_HIGH;MOTOR_B_HIGH;MOTOR_C_LOW;MOTOR_D_HIGH; //3
break;
case 4 :
MOTOR_A_HIGH;MOTOR_B_HIGH;MOTOR_C_HIGH;MOTOR_D_LOW; //4
break;
}
delay_ms(dly);
}
void MOTOR_Rhythm_4_2_4(uint8_t step,uint8_t dly)
{
switch(step)
{
case 0 :
;;
break;
case 1 :
MOTOR_A_LOW;MOTOR_B_HIGH;MOTOR_C_HIGH;MOTOR_D_LOW; //1
break;
case 2 :
MOTOR_A_LOW;MOTOR_B_LOW;MOTOR_C_HIGH;MOTOR_D_HIGH; //2
break;
case 3 :
MOTOR_A_HIGH;MOTOR_B_LOW;MOTOR_C_LOW;MOTOR_D_HIGH; //3
break;
case 4 :
MOTOR_A_HIGH;MOTOR_B_HIGH;MOTOR_C_LOW;MOTOR_D_LOW; //4
break;
}
delay_ms(dly);
}
void MOTOR_Rhythm_4_1_8(uint8_t step,uint8_t dly)
{
switch(step)
{
case 0 :
;;
break;
case 1 :
MOTOR_A_LOW;MOTOR_B_HIGH;MOTOR_C_HIGH;MOTOR_D_HIGH; //1
break;
case 2 :
MOTOR_A_LOW;MOTOR_B_LOW;MOTOR_C_HIGH;MOTOR_D_HIGH; //2
break;
case 3 :
MOTOR_A_HIGH;MOTOR_B_LOW;MOTOR_C_HIGH;MOTOR_D_HIGH; //3
break;
case 4 :
MOTOR_A_HIGH;MOTOR_B_LOW;MOTOR_C_LOW;MOTOR_D_HIGH; //4
break;
case 5 :
MOTOR_A_HIGH;MOTOR_B_HIGH;MOTOR_C_LOW;MOTOR_D_HIGH; //5
break;
case 6 :
MOTOR_A_HIGH;MOTOR_B_HIGH;MOTOR_C_LOW;MOTOR_D_LOW; //6
break;
case 7 :
MOTOR_A_HIGH;MOTOR_B_HIGH;MOTOR_C_HIGH;MOTOR_D_LOW; //7
break;
case 8 :
MOTOR_A_LOW;MOTOR_B_HIGH;MOTOR_C_HIGH;MOTOR_D_LOW; //8
break;
}
delay_ms(dly);
}
void MOTOR_Direction(uint8_t dir,uint8_t num,uint8_t dly) //方向 节拍 频率
{
if(dir)
{
switch(num)
{
case 0:for(uint8_t i=1;i<9;i++){MOTOR_Rhythm_4_1_8(i,dly);}break;
case 1:for(uint8_t i=1;i<5;i++){MOTOR_Rhythm_4_1_4(i,dly);}break;
case 2:for(uint8_t i=1;i<5;i++){MOTOR_Rhythm_4_2_4(i,dly);}break;
default:break;
}
}
else
{
switch(num)
{
case 0:for(uint8_t i=8;i>0;i--){MOTOR_Rhythm_4_1_8(i,dly);}break;
case 1:for(uint8_t i=4;i>0;i--){MOTOR_Rhythm_4_1_4(i,dly);}break;
case 2:for(uint8_t i=4;i>0;i--){MOTOR_Rhythm_4_2_4(i,dly);}break;
default:break;
}
}
}
void MOTOR_Direction_Angle(uint8_t dir,uint8_t num,u16 angle,uint8_t dly) //方向 节拍 角度 频率
{
for(u16 i=0;i<(64*angle/45);i++) //64*64=4096 64*180=256 //512
{
MOTOR_Direction(dir,num,dly);
}
}
void MOTOR_STOP(void)
{
GPIO_ResetBits(GPIOA, MOTOR_A|MOTOR_B|MOTOR_C|MOTOR_D);
}