步进电机实验

          通过 ULN2003 驱动模块控制 28BYJ48 步进电机运行方向和速度,按下 KEY1 键调节电机旋转方向;按下 KEY2 键,电机加速;当按下 KEY3 键,电机减速。实现对步进电机运动的简单控制。

步进电机简介

          步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。在非超载的情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响。即,给电机加一个脉冲信号,电机则转过一个步距角。由于这一线性关系的存在,加上步进电机只有周期性的误差而无累计误差等特点。使得步进电机广泛使用于速度、位置等控制领域。步进电机须由 “双环形脉冲信号、功率驱动电路等组成控制系统” 方可使用。下图为混合式步进电机组成图。

  步进电机工作原理

          通常步进电机的转子为永磁体,当电流流过定子绕组时,定子绕组产生一矢量磁场。磁场会带动转子旋转一定的角度,使得转子的一对磁场方向与定子的磁场方向一致。当定子的矢量磁场旋转一个角度。转子也随着该磁场转步距角。每输入一个电脉冲,电动机转动一个角度前进一步。它输出的角位移与输入的脉冲数成正比、转速与脉冲频率成正比。改变绕组通电的顺序,电机就会反转。所以可以控制脉冲数量、频率及电动机各相绕组的通电顺序来控制步进电机的转动。 以下是五相步进电机结构图:

          大致解释一下电机的步进顺序,下图就是单极性步进电机半步的通电顺序,具体看下图:

           由于电流决定磁场,同性相斥异性相吸,所以转子在电流产生的磁场变化下被相斥相吸而转动,如上图所示;步骤1->8的通电顺序为:A->AB->B->BC->C->CD->D->DA。

  1. A 相通电,B、C、D相断电
  2. A、B 相通电,且电流相同,产生相同磁性。C、D相断电
  3. B 相通电,A、C、D 相断电
  4. B、C 相通电,且电流相等,产生相同磁性。A、D 相断电
  5.  C相通电,A、B、D 相断电
  6. C、D 相通电,且电流相同,产生相同磁性。A、B 相断电
  7. D 相通电,A、B、C 相断电
  8.  A、D 相通电,且电流相同,产生相同磁性。B、C相断电

          转子每次只走半步 45 度,所以也被称为半步驱动,与整步相比半步的旋转方式旋转起来更加的顺滑。 步进电机详细信息请浏览这篇文章,解释得很清楚:一文搞懂步进电机特性、原理及驱动器设计

细分驱动原理

           细分驱动的原理,下图以单极性为例:

          上图均为双相激励;其中图(a)为 A 相电流很大,B 相的电流极其微弱,接近 0;图 (C) 为 A 相和 B 相的电流相同,电流决定磁场,所以说 A 相 和 B 相的磁场也是相同的,(a) 和(c)可以是极限特殊的情况,再看图(b) 和图(d)这两个是由于 A 相和 B 相的电流不同产生位置情况;由此可以得出,改变定子的电流比例就可以使得转子在任意角度停住。细分的原理就是:通过改变定子的电流比例,改变转子在一个整步中的不同位置,可以将一个整步分成多个小步来运行。

         可以理解为一个整步分成了 4 步来跑,从(a)~(d)是 A 相的电流逐渐减小,B 相电流逐渐增大的过程,如果驱动器的细分能力很强,可以将其分成 32 细分、64 细分等;这不仅提高了步进电机旋转的顺畅度而且提高了每步的精度。

         细分驱动具有转动顺畅、精度高、转矩大的特点,但控制复杂,一般需要专用的芯片来实现,例如东芝公司的 TB67S10xA 系列步进电机细分驱动芯片,最多可以把 1 个整步分为 32 个小步

步进电机技术指标

静态技术指标

  • 相数:产生不同对极 N、S 磁场的激磁线圈对数,可以理解为步进电机中线圈的组数,其中两相步进电机步距角为 1.8°,三相的步进电机步距角为 1.5°,相数越多的步进电机,其步距角就越小。
  • 拍数:完成一个磁场周期性变化所需脉冲数或导电状态用 n 表示,或指电机转过一个齿距角所需脉冲数,以四相电机为例,有四相四拍运行方式即 AB-BC-CD-DA-AB,四相八拍运行方式即 A-AB-B-BC-C-CD-D-DA-A。
  • 步距角:一个脉冲信号所对应的电机转动的角度,可以简单理解为一个脉冲信号驱动的角度,电机上都有写,一般 42 步进电机的步距角为 1.8°
  • 定位转矩:电机在不通电状态下,电机转子自身的锁定力矩(由磁场齿形的谐波以及机械误差造成的)。
  • 静转矩:电机在额定静态电压作用下,电机不作旋转运动时,电机转轴的锁定力矩。此力矩是衡量电机体积的标准,与驱动电压及驱动电源等无关。

 动态技术指标

  • 步距角精度:步进电机转动一个步距角度的理论值与实际值的误差。用百分比表示:误差/步距角 *100%。
  • 失步:电机运转时运转的步数,不等于理论上的步数。也可以叫做丢步,一般都是因负载太大或者是频率过快。
  • 失调角:转子齿轴线偏移定子齿轴线的角度,电机运转必存在失调角,由失调角产生的误差,采用细分驱动是不能解决的。
  • 最大空载起动频率:在不加负载的情况下,能够直接起动的最大频率。
  • 最大空载的运行频率:电机不带负载的最高转速频率。
  • 运行转矩特性:电机的动态力矩取决于电机运行时的平均电流(而非静态 电流),平均电流越大,电机输出力矩越大,即电机的频率特性越硬。
  • 电机正反转控制:通过改变通电顺序而改变电机的正反转。

硬件部分

        使用到硬件资源如下:

  1. 步进电机驱动模块
  2. 28BYJ-48 步进电机

步进电机驱动模块

        该电路在前面直流电机实验中已介绍,此处不再重复。

 28BYJ-48 步进电机简介

        28BYJ48 为四相无线步进电机,自带减速器,直径为 28mm,实物如下所示:

        28BYJ48 电机内部结构等效图如下所示:

         28BYJ48 步进电机旋转驱动方式如下表(类似于:D-DC-C-CB-B-BA-A-AD,8步完成旋转一周):

         28BYJ48 步进电机主要参数如下所示:

         主要参数中有一个减速比:1:64,步进角为 5.625/64 度,也就是说,如果要转动一圈,那么需要 360/5.625*64=4096 个脉冲信号。 减速比这个和之前介绍的直流减速电机有点类似,所以 28BYJ48 步进电机实际上是:减速齿轮+步进电机组成,28BYJ48 步进电机减速齿轮实物图如下所示:

          减速齿轮计算方法如下所示:

 软件部分

           实现的功能是:通过 ULN2003 驱动模块控制 28BYJ48 步进电机运行方向及速度,按下 KEY1 键可调节电机旋转方向;当按下 KEY2 键,电机加速; 当按下 KEY3 键,电机减速。

          STEP_MOTOR_28BYJ48_SEND_PULSE(u8 step,u8 dir)函数用于输出一个数据给 ULN2003,向步进电机发送一个脉冲信号。第一个形参为 step,指定步进序号,可选值为 0-7,代表步进电机控制信号的 8 个节拍。第二个形参为 dir,指定电机的旋转方向,其中, 1为顺时针旋转。如果为 0,则为逆时针旋转,将 step 值变为 8 的互补数,其实就是将 8 个节拍反向输出,即,从第八步开始向第一步运行。

           KEY_SCAN函数用来扫描按键是否按下,并将按键的键值返回到主函数if语句中,执行按键对应的操作。

          主函数的结构功很简单,首先定义一些需要使用的变量,然后进入while无限循环,程序一直在这个循环中进行。

          解释一下在while循环中发生了什么,在while的每一次循环中,步进电机执行前进一步操作,并检测是否有按键按下。所以代码的逻辑就体现在while中,比如,CPU正在while循环中,按下KEY1,此时KEY_SCAN检查到KEY1按下,并返回KEY1_PRESS给主函数中的变量key,满足if语句:if(key==KEY1_PRESS),从而执行反向dir=!dir;接着将dir的变化通过函数调用传达给函数:STEP_MOTOR_28BYJ48_SEND_PULSE(u8 step,u8 dir),从而实现从KEY1按下到执行方向的过程,然后继续下一个while循环。

源代码:

#include "reg52.h"

typedef unsigned int u16;	//对系统默认数据类型进行重定义
typedef unsigned char u8;

//定义ULN2003控制步进电机管脚
sbit IN1_A=P1^1;
sbit IN2_B=P1^2;
sbit IN3_C=P1^3;
sbit IN4_D=P1^4;

//定义独立按键控制脚
sbit KEY1=P3^1;
sbit KEY2=P3^2;
sbit KEY3=P3^3;
sbit KEY4=P3^4;

//使用宏定义独立按键按下的键值
#define KEY1_PRESS 1
#define KEY2_PRESS 2
#define KEY3_PRESS 3
#define KEY4_PRESS 4
#define KEY_UNPRESS 0

//定义步进电机的速度,值越小,速度越快
#define MOTOR_MAXSPEED 1 //也就用来设定步进电机执行每一步之间的时间,
#define MOTOR_MINSPEED 5

void delay_10us(u16 ten_us)//延时函数,ten_us=1时,大约延时10us
{
 	while(ten_us--);
}

void delay_1ms(u16 ms)	// ms延时函数,ms=1时,大约延时1ms
{
	u16 i,j;
	for(i=ms;i>0;i--)
		for(j=110;j>0;j--);
}

void STEP_MOTOR_28BYJ48_SEND_PULSE(u8 step,u8 dir)
{
 	u8 temp=step;//需要执行的那一步

	if(dir==0) //如果为逆时针旋转
		temp=7-step; //调换节拍信号,相当于从第八步向第一步执行,执行的方向反过来了
	switch(temp)   //8个节拍控制:A->AB->B->BC->C->CD->D->DA ,ULN2003芯片输入为高是输出为低
	{
	 	case 0:IN1_A=1;IN2_B=0;IN3_C=0;IN4_D=0;break;
		case 1:IN1_A=1;IN2_B=1;IN3_C=0;IN4_D=0;break;
		case 2:IN1_A=0;IN2_B=1;IN3_C=0;IN4_D=0;break;
		case 3:IN1_A=0;IN2_B=1;IN3_C=1;IN4_D=0;break;
		case 4:IN1_A=0;IN2_B=0;IN3_C=1;IN4_D=0;break;
		case 5:IN1_A=0;IN2_B=0;IN3_C=1;IN4_D=1;break;
		case 6:IN1_A=0;IN2_B=0;IN3_C=0;IN4_D=1;break;
		case 7:IN1_A=1;IN2_B=0;IN3_C=0;IN4_D=1;break;
		default:IN1_A=0;IN2_B=0;IN3_C=0;IN4_D=0;break;	//停止相序
	}
}

u8 KEY_SCAN(u8 mode)//检测独立按键是否按下,按下则返回对应键值
{
 	static u8 key=1;//定义一个返回给主函数的变量,代表按下的键值

	if(mode) key=1;//扫描模式(0为单次扫描按键,1为连续扫描按键),比如说,当mode为0,则不会执行这条语句,此时key=1,
	               //当有按键按下不松开,此时已执行if里的key=0,此时key=0,当再次执行KEY_SCAN时,由于key=0
				   //进入不了下面的if判断语句中,从而只能单次扫描按键。连续扫描按键也是同理。
	if(key==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0)) //任意按键按下,GPIO默认高电平,按键按下则接地为低电平
	{
	 	delay_10us(1000); //消抖
		key=0;//扫描模式的关键点
		if(KEY1==0)
			return KEY1_PRESS;
		else if(KEY2==0)
			return KEY2_PRESS;
		else if(KEY3==0)
			return KEY3_PRESS;
		else if(KEY4==0)
			return KEY4_PRESS;
	}
	else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1)
	{
	 	key=1;
	}
	return KEY_UNPRESS;
}										

void main()
{	
	u8 key=0;//接收按键扫描函数返回的键值
	u8 dir=0;//电机运转方向,0为逆时针,1位顺时针
	u8 speed=MOTOR_MAXSPEED;//点击运转速度
	u8 step=0;//电机执行的其中一步
	
	while(1)
	{
	 	key=KEY_SCAN(0);//程序扫描是否有按键按下,哪一个按下,并返回那个按下的键值KEY*_PRESS
		/*按下对应键执行的操作*/
		if(key==KEY1_PRESS)//换运转方向
		{
		 	dir=!dir;  //取反,注意别用成~了
		}
		else if(key==KEY2_PRESS)//加速
		{
		 	if(speed<MOTOR_MAXSPEED)//没达到最大速度之前,速度可以再增加
				speed+=1;
		}
		else if(speed==KEY3_PRESS)//减速
		{
		 	if(speed>MOTOR_MINSPEED)//没达到最小速度之前,速度可以再减小
				speed-=1;
		}
		STEP_MOTOR_28BYJ48_SEND_PULSE(step++,dir); //while的一次循环,电机执行一步操作
		if(step==8)//如果执行完了第八步,表示完成了一轮转动,回到第一步。就像自行车轮胎一样
			step=0;
		delay_1ms(speed);//电机执行每一步之间的时间间隔,从而影响电机的运转速度
	}		
}

现象

          按下 KEY1 键调节电机旋转方向;按下 KEY2 键,电机加速;当按下 KEY3 键,电机减速。实现对步进电机运动的简单控制。

版权声明:本文为CSDN博主「風清掦」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_60461563/article/details/122460040

          通过 ULN2003 驱动模块控制 28BYJ48 步进电机运行方向和速度,按下 KEY1 键调节电机旋转方向;按下 KEY2 键,电机加速;当按下 KEY3 键,电机减速。实现对步进电机运动的简单控制。

步进电机简介

          步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。在非超载的情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响。即,给电机加一个脉冲信号,电机则转过一个步距角。由于这一线性关系的存在,加上步进电机只有周期性的误差而无累计误差等特点。使得步进电机广泛使用于速度、位置等控制领域。步进电机须由 “双环形脉冲信号、功率驱动电路等组成控制系统” 方可使用。下图为混合式步进电机组成图。

  步进电机工作原理

          通常步进电机的转子为永磁体,当电流流过定子绕组时,定子绕组产生一矢量磁场。磁场会带动转子旋转一定的角度,使得转子的一对磁场方向与定子的磁场方向一致。当定子的矢量磁场旋转一个角度。转子也随着该磁场转步距角。每输入一个电脉冲,电动机转动一个角度前进一步。它输出的角位移与输入的脉冲数成正比、转速与脉冲频率成正比。改变绕组通电的顺序,电机就会反转。所以可以控制脉冲数量、频率及电动机各相绕组的通电顺序来控制步进电机的转动。 以下是五相步进电机结构图:

          大致解释一下电机的步进顺序,下图就是单极性步进电机半步的通电顺序,具体看下图:

           由于电流决定磁场,同性相斥异性相吸,所以转子在电流产生的磁场变化下被相斥相吸而转动,如上图所示;步骤1->8的通电顺序为:A->AB->B->BC->C->CD->D->DA。

  1. A 相通电,B、C、D相断电
  2. A、B 相通电,且电流相同,产生相同磁性。C、D相断电
  3. B 相通电,A、C、D 相断电
  4. B、C 相通电,且电流相等,产生相同磁性。A、D 相断电
  5.  C相通电,A、B、D 相断电
  6. C、D 相通电,且电流相同,产生相同磁性。A、B 相断电
  7. D 相通电,A、B、C 相断电
  8.  A、D 相通电,且电流相同,产生相同磁性。B、C相断电

          转子每次只走半步 45 度,所以也被称为半步驱动,与整步相比半步的旋转方式旋转起来更加的顺滑。 步进电机详细信息请浏览这篇文章,解释得很清楚:一文搞懂步进电机特性、原理及驱动器设计

细分驱动原理

           细分驱动的原理,下图以单极性为例:

          上图均为双相激励;其中图(a)为 A 相电流很大,B 相的电流极其微弱,接近 0;图 (C) 为 A 相和 B 相的电流相同,电流决定磁场,所以说 A 相 和 B 相的磁场也是相同的,(a) 和(c)可以是极限特殊的情况,再看图(b) 和图(d)这两个是由于 A 相和 B 相的电流不同产生位置情况;由此可以得出,改变定子的电流比例就可以使得转子在任意角度停住。细分的原理就是:通过改变定子的电流比例,改变转子在一个整步中的不同位置,可以将一个整步分成多个小步来运行。

         可以理解为一个整步分成了 4 步来跑,从(a)~(d)是 A 相的电流逐渐减小,B 相电流逐渐增大的过程,如果驱动器的细分能力很强,可以将其分成 32 细分、64 细分等;这不仅提高了步进电机旋转的顺畅度而且提高了每步的精度。

         细分驱动具有转动顺畅、精度高、转矩大的特点,但控制复杂,一般需要专用的芯片来实现,例如东芝公司的 TB67S10xA 系列步进电机细分驱动芯片,最多可以把 1 个整步分为 32 个小步

步进电机技术指标

静态技术指标

  • 相数:产生不同对极 N、S 磁场的激磁线圈对数,可以理解为步进电机中线圈的组数,其中两相步进电机步距角为 1.8°,三相的步进电机步距角为 1.5°,相数越多的步进电机,其步距角就越小。
  • 拍数:完成一个磁场周期性变化所需脉冲数或导电状态用 n 表示,或指电机转过一个齿距角所需脉冲数,以四相电机为例,有四相四拍运行方式即 AB-BC-CD-DA-AB,四相八拍运行方式即 A-AB-B-BC-C-CD-D-DA-A。
  • 步距角:一个脉冲信号所对应的电机转动的角度,可以简单理解为一个脉冲信号驱动的角度,电机上都有写,一般 42 步进电机的步距角为 1.8°
  • 定位转矩:电机在不通电状态下,电机转子自身的锁定力矩(由磁场齿形的谐波以及机械误差造成的)。
  • 静转矩:电机在额定静态电压作用下,电机不作旋转运动时,电机转轴的锁定力矩。此力矩是衡量电机体积的标准,与驱动电压及驱动电源等无关。

 动态技术指标

  • 步距角精度:步进电机转动一个步距角度的理论值与实际值的误差。用百分比表示:误差/步距角 *100%。
  • 失步:电机运转时运转的步数,不等于理论上的步数。也可以叫做丢步,一般都是因负载太大或者是频率过快。
  • 失调角:转子齿轴线偏移定子齿轴线的角度,电机运转必存在失调角,由失调角产生的误差,采用细分驱动是不能解决的。
  • 最大空载起动频率:在不加负载的情况下,能够直接起动的最大频率。
  • 最大空载的运行频率:电机不带负载的最高转速频率。
  • 运行转矩特性:电机的动态力矩取决于电机运行时的平均电流(而非静态 电流),平均电流越大,电机输出力矩越大,即电机的频率特性越硬。
  • 电机正反转控制:通过改变通电顺序而改变电机的正反转。

硬件部分

        使用到硬件资源如下:

  1. 步进电机驱动模块
  2. 28BYJ-48 步进电机

步进电机驱动模块

        该电路在前面直流电机实验中已介绍,此处不再重复。

 28BYJ-48 步进电机简介

        28BYJ48 为四相无线步进电机,自带减速器,直径为 28mm,实物如下所示:

        28BYJ48 电机内部结构等效图如下所示:

         28BYJ48 步进电机旋转驱动方式如下表(类似于:D-DC-C-CB-B-BA-A-AD,8步完成旋转一周):

         28BYJ48 步进电机主要参数如下所示:

         主要参数中有一个减速比:1:64,步进角为 5.625/64 度,也就是说,如果要转动一圈,那么需要 360/5.625*64=4096 个脉冲信号。 减速比这个和之前介绍的直流减速电机有点类似,所以 28BYJ48 步进电机实际上是:减速齿轮+步进电机组成,28BYJ48 步进电机减速齿轮实物图如下所示:

          减速齿轮计算方法如下所示:

 软件部分

           实现的功能是:通过 ULN2003 驱动模块控制 28BYJ48 步进电机运行方向及速度,按下 KEY1 键可调节电机旋转方向;当按下 KEY2 键,电机加速; 当按下 KEY3 键,电机减速。

          STEP_MOTOR_28BYJ48_SEND_PULSE(u8 step,u8 dir)函数用于输出一个数据给 ULN2003,向步进电机发送一个脉冲信号。第一个形参为 step,指定步进序号,可选值为 0-7,代表步进电机控制信号的 8 个节拍。第二个形参为 dir,指定电机的旋转方向,其中, 1为顺时针旋转。如果为 0,则为逆时针旋转,将 step 值变为 8 的互补数,其实就是将 8 个节拍反向输出,即,从第八步开始向第一步运行。

           KEY_SCAN函数用来扫描按键是否按下,并将按键的键值返回到主函数if语句中,执行按键对应的操作。

          主函数的结构功很简单,首先定义一些需要使用的变量,然后进入while无限循环,程序一直在这个循环中进行。

          解释一下在while循环中发生了什么,在while的每一次循环中,步进电机执行前进一步操作,并检测是否有按键按下。所以代码的逻辑就体现在while中,比如,CPU正在while循环中,按下KEY1,此时KEY_SCAN检查到KEY1按下,并返回KEY1_PRESS给主函数中的变量key,满足if语句:if(key==KEY1_PRESS),从而执行反向dir=!dir;接着将dir的变化通过函数调用传达给函数:STEP_MOTOR_28BYJ48_SEND_PULSE(u8 step,u8 dir),从而实现从KEY1按下到执行方向的过程,然后继续下一个while循环。

源代码:

#include "reg52.h"

typedef unsigned int u16;	//对系统默认数据类型进行重定义
typedef unsigned char u8;

//定义ULN2003控制步进电机管脚
sbit IN1_A=P1^1;
sbit IN2_B=P1^2;
sbit IN3_C=P1^3;
sbit IN4_D=P1^4;

//定义独立按键控制脚
sbit KEY1=P3^1;
sbit KEY2=P3^2;
sbit KEY3=P3^3;
sbit KEY4=P3^4;

//使用宏定义独立按键按下的键值
#define KEY1_PRESS 1
#define KEY2_PRESS 2
#define KEY3_PRESS 3
#define KEY4_PRESS 4
#define KEY_UNPRESS 0

//定义步进电机的速度,值越小,速度越快
#define MOTOR_MAXSPEED 1 //也就用来设定步进电机执行每一步之间的时间,
#define MOTOR_MINSPEED 5

void delay_10us(u16 ten_us)//延时函数,ten_us=1时,大约延时10us
{
 	while(ten_us--);
}

void delay_1ms(u16 ms)	// ms延时函数,ms=1时,大约延时1ms
{
	u16 i,j;
	for(i=ms;i>0;i--)
		for(j=110;j>0;j--);
}

void STEP_MOTOR_28BYJ48_SEND_PULSE(u8 step,u8 dir)
{
 	u8 temp=step;//需要执行的那一步

	if(dir==0) //如果为逆时针旋转
		temp=7-step; //调换节拍信号,相当于从第八步向第一步执行,执行的方向反过来了
	switch(temp)   //8个节拍控制:A->AB->B->BC->C->CD->D->DA ,ULN2003芯片输入为高是输出为低
	{
	 	case 0:IN1_A=1;IN2_B=0;IN3_C=0;IN4_D=0;break;
		case 1:IN1_A=1;IN2_B=1;IN3_C=0;IN4_D=0;break;
		case 2:IN1_A=0;IN2_B=1;IN3_C=0;IN4_D=0;break;
		case 3:IN1_A=0;IN2_B=1;IN3_C=1;IN4_D=0;break;
		case 4:IN1_A=0;IN2_B=0;IN3_C=1;IN4_D=0;break;
		case 5:IN1_A=0;IN2_B=0;IN3_C=1;IN4_D=1;break;
		case 6:IN1_A=0;IN2_B=0;IN3_C=0;IN4_D=1;break;
		case 7:IN1_A=1;IN2_B=0;IN3_C=0;IN4_D=1;break;
		default:IN1_A=0;IN2_B=0;IN3_C=0;IN4_D=0;break;	//停止相序
	}
}

u8 KEY_SCAN(u8 mode)//检测独立按键是否按下,按下则返回对应键值
{
 	static u8 key=1;//定义一个返回给主函数的变量,代表按下的键值

	if(mode) key=1;//扫描模式(0为单次扫描按键,1为连续扫描按键),比如说,当mode为0,则不会执行这条语句,此时key=1,
	               //当有按键按下不松开,此时已执行if里的key=0,此时key=0,当再次执行KEY_SCAN时,由于key=0
				   //进入不了下面的if判断语句中,从而只能单次扫描按键。连续扫描按键也是同理。
	if(key==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0)) //任意按键按下,GPIO默认高电平,按键按下则接地为低电平
	{
	 	delay_10us(1000); //消抖
		key=0;//扫描模式的关键点
		if(KEY1==0)
			return KEY1_PRESS;
		else if(KEY2==0)
			return KEY2_PRESS;
		else if(KEY3==0)
			return KEY3_PRESS;
		else if(KEY4==0)
			return KEY4_PRESS;
	}
	else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1)
	{
	 	key=1;
	}
	return KEY_UNPRESS;
}										

void main()
{	
	u8 key=0;//接收按键扫描函数返回的键值
	u8 dir=0;//电机运转方向,0为逆时针,1位顺时针
	u8 speed=MOTOR_MAXSPEED;//点击运转速度
	u8 step=0;//电机执行的其中一步
	
	while(1)
	{
	 	key=KEY_SCAN(0);//程序扫描是否有按键按下,哪一个按下,并返回那个按下的键值KEY*_PRESS
		/*按下对应键执行的操作*/
		if(key==KEY1_PRESS)//换运转方向
		{
		 	dir=!dir;  //取反,注意别用成~了
		}
		else if(key==KEY2_PRESS)//加速
		{
		 	if(speed<MOTOR_MAXSPEED)//没达到最大速度之前,速度可以再增加
				speed+=1;
		}
		else if(speed==KEY3_PRESS)//减速
		{
		 	if(speed>MOTOR_MINSPEED)//没达到最小速度之前,速度可以再减小
				speed-=1;
		}
		STEP_MOTOR_28BYJ48_SEND_PULSE(step++,dir); //while的一次循环,电机执行一步操作
		if(step==8)//如果执行完了第八步,表示完成了一轮转动,回到第一步。就像自行车轮胎一样
			step=0;
		delay_1ms(speed);//电机执行每一步之间的时间间隔,从而影响电机的运转速度
	}		
}

现象

          按下 KEY1 键调节电机旋转方向;按下 KEY2 键,电机加速;当按下 KEY3 键,电机减速。实现对步进电机运动的简单控制。

版权声明:本文为CSDN博主「風清掦」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_60461563/article/details/122460040

生成海报
点赞 0

風清掦

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

普中51-单核-A2单片机

合伙创业、商业需求 Q:1274510382 https://www.bilibili.com/video/av286413345/ 功能与使用 单核A2产品 基于STC89C52 低功耗,高性能的51内核的CMOS 8位单片

步进电机实验

通过 ULN2003 驱动模块控制 28BYJ48 步进电机运行方向和速度,按下 KEY1 键调节电机旋转方向;按下 KEY2 键,电机加速;当按下 KEY3 键,电机减速。

普中51-单核-A2单片机

合伙创业、商业需求 Q:1274510382 https://www.bilibili.com/video/av286413345/ 功能与使用 单核A2产品 基于STC89C52 低功耗,高性能的51内核的CMOS 8位单片