文章目录
-
- 1.步进电机的驱动原理
- 2.步进电机驱动设计
- 3.步进电机驱动编写
- 4、源码
1.步进电机的驱动原理
之前在网上看到一张动态图,详细描述了步进电机的驱动过程。不懂专业知识的同学也可以看看,通俗易懂! 让我们回到本文使用的步进电机。常见的电机和驱动器如下所示。ULN2003驱动模块也有贴片式,但都差不多,差别不大,可以自己选择!
- 步进电机是将电脉冲转化为角位移的执行机构。
- 2.当步进驱动器接收到脉冲信号时,驱动步进电机按设定方向旋转固定角度(和步进角)。
- 3.通过控制脉冲个来控制角位移,从而达到准确定位的目的。
- 4、通过控制脉冲频率来控制电机的转速和加速,从而达到调速的目的。
具体到本文提到的电机,28BYJ48步进电机:
- 1.驱动电压为DC5V—DC12V。
- 2.每个脉冲信号对应步进电机某一相或两相绕组的通电状态,即对应转子转向一定角度(一个步距角)。
- 3.当通电状态改变完成循环时,转子转动齿距。
- 四相步进电机可以以不同的通电方式运行,
2.步进电机驱动设计
上述拍数对应的关系图如下:
我把他列成表格:
四项八拍
绕组 | 一 | 二 | 三 | 四 | 五 | 六 | 七 | 八 |
---|---|---|---|---|---|---|---|---|
A | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 |
B | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
C | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 1 |
D | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |
对应示意图
四项单四拍
绕组 | 一 | 二 | 三 | 四 |
---|---|---|---|---|
A | 0 | 1 | 1 | 1 |
B | 1 | 0 | 1 | 1 |
C | 1 | 1 | 0 | 1 |
D | 1 | 1 | 1 | 0 |
对应示意图 四项双四拍
绕组 | 一 | 二 | 三 | 四 |
---|---|---|---|---|
A | 0 | 0 | 1 | 1 |
B | 1 | 0 | 0 | 0 |
C | 1 | 1 | 1 | 0 |
D | 0 | 1 | 1 | 0 |
计算旋转角度:
28BYJ-48步进电机的步距角为5.625度,即每个脉冲转5度.625度而360/5.625=64,所以64个脉冲转一圈,但这是指电机的转子和转子与输出轴有齿轮减速器连接,减速比为64,,所以结论是输出轴只有脉冲才能转动。
对应四拍和八拍的计算角度来看:
8拍计算公式 = 64角度/360/8,4拍计算公式 = 64角度/360/4。
3、步进电机驱动编写
首先我们在cubemx中初始化对应的引脚: 根据上面讲到的时序编写四项单四拍对应的程序 根据上面讲到的时序编写四项双四拍对应的程序 根据上面讲到的时序编写四项八拍对应的程序
当然要想做的更好一点,我们还可以准备下方向速度函数,改变方向其实就是把前面说的四拍八拍这个顺序倒着来一下就行了,也是很方便的!
这里我还加入了角度函数,也是在上面讲到的角度计算方法里面讲的! 主函数中调用情况如下,这里我们让他正转180度,在反转180度
4、源码
uln2003.c
/* * uln2003.c * * Created on: Feb 17, 2022 * Author: LX */
#include "uln2003.h"
void motor_stop()
{
MA_LOW;MB_LOW;MC_LOW;MD_LOW;
}
void motor_start_sig4(uint8_t motor,uint8_t speed) //四项单四拍
{
switch(motor)
{
// 0111 1011 1101 1110,这个过程逆向为反向
case 0:
MA_LOW;MB_HIGH;MC_HIGH;MD_HIGH;
break;
case 1:
MA_HIGH;MB_LOW;MC_HIGH;MD_HIGH;
break;
case 2:
MA_HIGH;MB_HIGH;MC_LOW;MD_HIGH;
break;
case 3:
MA_HIGH;MB_HIGH;MC_HIGH;MD_LOW;
break;
}
HAL_Delay(speed);
motor_stop();
}
void motor_start_dou4(uint8_t motor,uint8_t speed) //四项双四拍
{
switch(motor)
{
// 0110 0011 1011 1100,这个过程逆向为反向
case 0:
MA_LOW;MB_HIGH;MC_HIGH;MD_LOW;
break;
case 1:
MA_LOW;MB_LOW;MC_HIGH;MD_HIGH;
break;
case 2:
MA_HIGH;MB_LOW;MC_HIGH;MD_HIGH;
break;
case 3:
MA_HIGH;MB_HIGH;MC_LOW;MD_LOW;
break;
}
HAL_Delay(speed);
motor_stop();
}
void motor_start_eig(uint8_t motor,uint8_t speed) //四项八拍
{
switch(motor)
{
// 0111 0011 1011 1001 1101 1100 1110 0110,这个过程逆向为反向
case 0:
MA_LOW;MB_HIGH;MC_HIGH;MD_HIGH;
break;
case 1:
MA_LOW;MB_LOW;MC_HIGH;MD_HIGH;
break;
case 2:
MA_HIGH;MB_LOW;MC_HIGH;MD_HIGH;
break;
case 3:
MA_HIGH;MB_LOW;MC_HIGH;MD_LOW;
break;
case 4:
MA_HIGH;MB_HIGH;MC_LOW;MD_HIGH;
break;
case 5:
MA_HIGH;MB_HIGH;MC_LOW;MD_HIGH;
break;
case 6:
MA_HIGH;MB_HIGH;MC_HIGH;MD_LOW;
break;
case 7:
MA_LOW;MB_HIGH;MC_HIGH;MD_LOW;
break;
}
HAL_Delay(speed);
motor_stop();
}
uint8_t motor;
void motor_uln2003(uint8_t dir,uint8_t speed)
{
for(uint8_t i = 0;i<8;i++)
{
if(dir == 1)
{
motor++;
if(motor > 7)motor = 0;
}
else
{
if(motor == 0)motor = 8;
motor--;
}
motor_start_eig(motor,speed);
}
}
void motor_angle(uint8_t dir,uint16_t angle,uint8_t speed)
{
static uint8_t flag = 1;
if(flag == 1)
{
for(uint16_t num;num<64*angle/45;num++)
{
motor_uln2003(dir,speed);
flag = 0;
}
flag = 1;
}
}
uln2003.h
#ifndef ULN2003_H_
#define ULN2003_H_
#include "main.h"
#define MA_HIGH HAL_GPIO_WritePin(INTC_GPIO_Port, INTC_Pin, GPIO_PIN_SET)
#define MA_LOW HAL_GPIO_WritePin(INTC_GPIO_Port, INTC_Pin, GPIO_PIN_RESET)
#define MB_HIGH HAL_GPIO_WritePin(INTD_GPIO_Port, INTD_Pin, GPIO_PIN_SET)
#define MB_LOW HAL_GPIO_WritePin(INTD_GPIO_Port, INTD_Pin, GPIO_PIN_RESET)
#define MC_HIGH HAL_GPIO_WritePin(INTB_GPIO_Port, INTB_Pin, GPIO_PIN_SET)
#define MC_LOW HAL_GPIO_WritePin(INTB_GPIO_Port, INTB_Pin, GPIO_PIN_RESET)
#define MD_HIGH HAL_GPIO_WritePin(INTA_GPIO_Port, INTA_Pin, GPIO_PIN_SET)
#define MD_LOW HAL_GPIO_WritePin(INTA_GPIO_Port, INTA_Pin, GPIO_PIN_RESET)
void motor_stop();
void motor_start_sig4(uint8_t motor,uint8_t speed);
void motor_start_dou4(uint8_t motor,uint8_t speed);
void motor_start_eig(uint8_t motor,uint8_t speed);
void motor_uln2003(uint8_t dir,uint8_t speed);
void motor_angle(uint8_t dir,uint16_t angle,uint8_t speed);
#endif /* ULN2003_H_ */