ULN2003驱动28BYJ-48步进电机详解(附:51 32代码讲解)

ULN2003驱动28BYJ-48步进电机详解(附:51 32代码讲解)

ULN2003使用方法

ULN2003 是一款 16 引脚芯片,由 7 个达林顿对(每对受抑制二极管保护)组成,因此能够处理最多 7 个负载。每个达林顿对可以处理最大 500mA 的负载,而峰值为 600mA。
ULN2003引脚图
其应用电路如下,在其每个输出端需要上拉500欧电阻,增加其驱动能力,亲测去过不加上拉电阻的话会导致输出高电平达不到VCC;如果IO口的驱动能力过低,需要在其输入端增加10K上拉电阻,提高IO口的驱动能力,保证输出高电平的时候能够实现。(51系列除了P0口其他口需要上拉,32全部需要上拉)
在电源和地之间需要连接104电容(100000pf=0.1uf)对输入电源进行滤波。
应用电路
注意:由其内部结构可知,其输出与输入是相反的,即:输入低电平信号,输出的是高电平,输入高电平信号输出的是低电平。

28YJ-48步进电机工作原理

首先介绍名称定义
28:步进电机的有效最大外径是28毫米
B:表示是步进电机
Y:表示是永磁式
J:表示是减速型(减速比1:64)
48:表示四相八拍(驱动方式比较重要)
驱动原理

什么是四相八拍?首先介绍定义
1、相数:是指产生不同对极N、S磁场的激磁线圈对数。如上图所示28YJ-48有四对线圈 A、B、C、D,所以其为四相。
2、拍数:完成一个磁场周期性变化所需脉冲数。
以四相电机为例,如下图所示,有两种四拍、一种八拍三种驱动方式
驱动原理
有此步进电机的名字可知,其为四相驱动方式为八拍。相对于另外两种驱动方式此驱动方式,步进电机运行更流畅。
运行参数
其运行参数入上图所示,通过参数可知其空载牵入频率>=500;其空载牵出频率>=800。也就是说其启动时,每步之间的时间间隔至少为2ms,在启动后可以减少每部之间的时间。
步进角为5.625/64 :因为减速比为1/64.所以步进角需要除以64。也就是说实际实际一步转动角度为:0.087890625。实测在刚启动的时候时是小于这个值的,因为启动的时候阻力大会导致慢一些。到速度稳定后,会满足这个值。

驱动代码详解

51驱动代码

sbit IN1_A=P1^4; //引脚定义,根据实际情况修改
sbit IN1_B=P1^3;
sbit IN1_C=P1^2;
sbit IN1_D=P1^1; 
/******
step:为拍数 0-7对应1-8拍
dir:方向 0为正方向 1为反方向
*******/
void step_28byj48_control(uchar step,uchar dir)//步进电机驱动函数
{
	uchar temp=step;
	if(dir==0) temp=7-step;
	switch(temp)  //4相8拍驱动方式
	{
		case 0:	IN1_A=1;IN1_B=1;IN1_C=1;IN1_D=0;break;
		case 1:	IN1_A=1;IN1_B=1;IN1_C=0;IN1_D=0;break;
		case 2:	IN1_A=1;IN1_B=1;IN1_C=0;IN1_D=1;break;
		case 3:	IN1_A=1;IN1_B=0;IN1_C=0;IN1_D=1;break;
		case 4:	IN1_A=1;IN1_B=0;IN1_C=1;IN1_D=1;break;
		case 5:	IN1_A=0;IN1_B=0;IN1_C=1;IN1_D=1;break;
		case 6:	IN1_A=0;IN1_B=1;IN1_C=1;IN1_D=1;break;
		case 7:	IN1_A=0;IN1_B=1;IN1_C=1;IN1_D=0;break;	
	}
}

这里开启了1个1ms的定时器终端,来控制步进电机

void Timer0Init()  //定时器0初始化
{
	TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。  定时模式 
	TH0=0XFC;	//给定时器赋初值,定时1ms
	TL0=0X66;	
	ET0=1;//打开定时器0中断允许   GATE=0所以软件打开就可以了
	TR0=1;//打开定时器			
}
//定时器0中断服务函数
void Timer0() interrupt 1      //0 1 2 3   外0   定0  外1   定1
{
static uchar i;
	i++;
	if(i%2==0)  //2ms		
	step_28byj48_control(i/2,0)	;
	if(i==16) i=0;
}

在主函数中初始化定时器后就可以实现步进电机的运动了。
32代码

void MX_GPIO_Init(void)  //引脚初始化、配置为推挽输出
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  __HAL_RCC_GPIOB_CLK_ENABLE();
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2, GPIO_PIN_SET);
  GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  }
//输出状态宏定义
#define IN1_A(a)  GPIOB->ODR=GPIOB->ODR & 0XFFFFFFFFE | (a<<0)  //PB0
#define IN1_B(a)  GPIOB->ODR=GPIOB->ODR & 0XFFFFFFFFD | (a<<1)  //PB1
#define IN1_C(a)  GPIOB->ODR=GPIOB->ODR & 0XFFFFFFFFB | (a<<2)  //PB2
#define IN1_D(a)  GPIOB->ODR=GPIOB->ODR & 0XFFFFFFFF7 | (a<<3)  //PB3
void step_28byj48_control(uchar step,uchar dir)//步进电机驱动函数
{
	uchar temp=step;
	if(dir==0) temp=7-step;
	switch(temp)  //4相8拍驱动方式
	{
		case 0:	IN1_A(1);IN1_B(1);IN1_C(1);IN1_D(0);break;
		case 1:	IN1_A(1);IN1_B(1);IN1_C(0);IN1_D(0);break;
		case 2:	IN1_A(1);IN1_B(1);IN1_C(0);IN1_D(1);break;
		case 3:	IN1_A(1);IN1_B(0);IN1_C(0);IN1_D(1);break;
		case 4:	IN1_A(1);IN1_B(0);IN1_C(1);IN1_D(1);break;
		case 5:	IN1_A(0);IN1_B(0);IN1_C(1);IN1_D(1);break;
		case 6:	IN1_A(0);IN1_B(1);IN1_C(1);IN1_D(1);break;
		case 7:	IN1_A(0);IN1_B(1);IN1_C(1);IN1_D(0);break;	
	}
}

最后开一个定时器调用此函数就可以了。

  • 7
    点赞
  • 87
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
以下是使用 ULN2003 驱动 28BYJ-48 步进电机进行旋转控制的代码示例(使用 Arduino IDE 编写): ``` // 定义步进电机控制引脚 const int IN1 = 8; const int IN2 = 9; const int IN3 = 10; const int IN4 = 11; // 步进电机控制顺序表 int stepOrder[8][4] = { {HIGH, LOW, LOW, LOW}, {HIGH, HIGH, LOW, LOW}, {LOW, HIGH, LOW, LOW}, {LOW, HIGH, HIGH, LOW}, {LOW, LOW, HIGH, LOW}, {LOW, LOW, HIGH, HIGH}, {LOW, LOW, LOW, HIGH}, {HIGH, LOW, LOW, HIGH} }; // 设置步进电机步数 const int STEPS_PER_REVOLUTION = 2048; // 设置旋转方向 const int CLOCKWISE = 1; const int COUNTER_CLOCKWISE = -1; // 初始化步进电机 void setup() { pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT); pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT); } // 控制步进电机旋转 void rotate(int direction, float angle) { int steps = angle / 360 * STEPS_PER_REVOLUTION; for (int i = 0; i < steps; i++) { for (int j = 0; j < 8; j++) { digitalWrite(IN1, stepOrder[j][0]); digitalWrite(IN2, stepOrder[j][1]); digitalWrite(IN3, stepOrder[j][2]); digitalWrite(IN4, stepOrder[j][3]); delayMicroseconds(1000); } } } // 主程序 void loop() { rotate(CLOCKWISE, 90); // 向顺时针方向旋转 90 度 delay(1000); rotate(COUNTER_CLOCKWISE, 180); // 向逆时针方向旋转 180 度 delay(1000); } ``` 在上述代码中,`IN1`、`IN2`、`IN3` 和 `IN4` 分别对应 ULN2003 驱动板上的四个控制引脚,`stepOrder` 是一个步进电机控制顺序表,用于控制步进电机旋转方向,`STEPS_PER_REVOLUTION` 是步进电机每转一圈所需的步数,`rotate()` 函数用于控制步进电机旋转,参数 `direction` 表示旋转方向,参数 `angle` 表示旋转角度。在 `loop()` 函数中,我们可以通过调用 `rotate()` 函数来控制步进电机的旋转。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值