STM32实战总结:HAL之电机

电机基础知识参考:

51单片机外设篇:电机_路溪非溪的博客-CSDN博客

无刷电机和有刷电机

先详细了解有刷电机:

带你了解(有刷)电机工作原理_哔哩哔哩_bilibili

再详细了解无刷电机:

无刷直流电机工作原理_哔哩哔哩_bilibili

二者有何异同?

无刷电机和有刷电机都是一种直流电机。

有另外一种说法:很多人在知识上一直有这么个误区,以为无刷电机是直流电机,其实不然,无刷电机属于交流电机,是三相交流永磁电机的一种,输入模型无刷电机3根导线的电流是交流电,只不过这种交流电不是50HZ的市电正弦波,而是从无刷电机控制器(俗称无刷电调)调制出来的三相交变矩形波,频率比50HZ高很多,且随电机转速变化而变化。

输入的都是直流,只是无刷电机通过内部的控制器后,形成了一个交流电。了解即可,不必纠结。

有刷电机是所有电机中最基础的,不仅具有启动快速、制动及时、调速平稳、控制简单等优点,并且结构简单,价格便宜。比如我们小时候玩得四驱车里面就有一个小的装置(马达)这就是有刷电机。

但是电刷也是让有刷电机寿命短的主要原因。由于电刷持续的相互滑动和摩擦,电刷会不断磨损消耗,有刷电机必须经常进行维护更换电刷。

带刷的电机是磁极固定、线圈转动;而无刷马达则为线圈固定、磁极旋转。在无刷电机中,通过霍尔传感器,感知永磁体磁极的位置,然后根据这种感知,利用电子线路,在保证产生正确方向磁力的线圈中适时切换电流的方向来驱动电机。将有刷电机的不足消除。

没有电刷的摩擦,电机里的火花跟电机都没有;无刷电机没有摩擦力、转速快且省电;无刷电机在没有电刷摩擦的情况下,几乎不需要额外保养。
无刷电机比有刷电机在很多性能方面都要高一些,在价格方面也是。无论是控制电路还是电机本身,其成本和价格都比同级别的有刷电机高很多。

再谈步进电机

电机分为直流电机和交流电机,直流电机分为有刷直流电机和无刷直流电机。

那么,步进电机是什么呢?它是直流电机还是交流电机?

步进电机没有分交流与直流,如果是单极性控制方式,步进电机流过的电流是单方向,双极性控制时,步进电机流过电流是交流电。但控制步进电机的驱动器的供电电源分直流版和交流版,不同厂家的产品是有些差异,如EZM872是直流版,工作电压是18~80VDC;EZM872H是交流版,工作电压是18~80VAC。一般情况下,建议用直流版本,交流版本易出现电机急刹车时导致驱动器损坏。

先了解大概原理:

【动画演示】步进电机的原理,学了这么多年电工,终于搞明白了_哔哩哔哩_bilibili

步进电机相对于无刷电机来说,可以精准控制。

更多参考:

什么是步进电机?步进电机的特点,分类与原理!-电子发烧友网

单极性和双极性步进电机:

15.2-步进电机实验--步进电机极性区分_哔哩哔哩_bilibili

电机相数:

所谓“相数”,就是线圈组数(不要认为是定子数)。二、三、四、五相步进电机分别对应有2、3、4、5组线圈。这 N 个绕组要均匀地镶嵌在定子上,因此定子的磁极数必定是 N 的整数倍,因此,转子转一圈的步数应该是 N 的整数倍。步进电机外部的接线和定子相数没有必然的联系。是根据实际运用的需要来决定的。

看这个:

会不会认为是8相的?因为有8个定子;会不会认为是4相的?因为可能两个定子绕一组线圈;其实,相数和定子数并没有必然联系。

上面的是2相的,因为有2组线圈,引出来4根线。

所以该图是两项四线步进电机。

线圈有各种各样的绕法,也有不同的引线方式,所以,相数和线数等并不是固定的,需要针对特定的电机进行具体分析。无特定规律。不必纠结。

四大驱动方式:

步进电机4大驱动方式:单拍、双拍、半步、细分_哔哩哔哩_bilibili

伺服电机

简单来说,步进电机加上反馈电路,就构成了伺服电机。

对比直流电机、步进电机和伺服电机:

3种电机介绍(直交流、步进、伺服)_哔哩哔哩_bilibili

有刷直流电机的功能实现

选择有刷直流电机时通常需要考虑:

尺寸

扭力

驱动电压

驱动电流

等等

要求:实现有刷直流电机的启停、正反转和加减速。

驱动方式1:

只能打开和关闭,不能变速与换向,用继电器、BJT或MOS开关控制通断即可。

驱动方式2:

可以打开和关闭,可以变速但不能换向,此时用PWM波来控制电子开关即可。其实,改变驱动电压也是可以的,但是频繁改变驱动电压比较麻烦。通过改变PWM波地占空比可以灵活地调整电机速度,改变PWM占空比实际上就是改变其有效电流。

驱动方式3:

可以打开和关闭,可以变速,也可以换向,就需要用PWM控制桥路。通常使用集成IC,比如LV8548MC

注意:单片机本身的电压不足以驱动电机,所以通常会通过单片机的高低电平来控制某些开关的通断,以此来接通电路,实现更高电压的接入。

MX初始化

因为是使用PWM波,所以,按照之前的定时器来初始化即可。

这里使用TIM3的其中一个空闲通道即可。

具体参考:

STM32实战总结:HAL之PWM蜂鸣器_路溪非溪的博客-CSDN博客

关键代码实现

/* Includes ------------------------------------------------------------------*/
#include "MyApplication.h"

/* Private define-------------------------------------------------------------*/

/* Private variables----------------------------------------------------------*/

/* Private function prototypes------------------------------------------------*/      
static void Start(void);    //直流电机启动
static void Stop(void);	    //直流电机停止
static void Direction_Adjust(void);        //直流电机方向调整
static void Speed_Adjust(Speed_Change_t);  //直流电机速度调整
	
/* Public variables-----------------------------------------------------------*/

//定义结构体类变量
DC_Motor_t DC_Motor = 
{
  Stop_State,
	Forward_State, 
	Speed_50,
	
	Start,
	Stop,
	Direction_Adjust,
	Speed_Adjust
};

/*
	* @name   Start
	* @brief  直流电机启动
	* @param  None
	* @retval None      
*/
static void Start(void)
{
	//启动电机
	if(DC_Motor.Direction == Forward_State)
	{
		HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_3);
	}
	else
	{
		HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);
	}
	
	//更新电机状态
	DC_Motor.Status = Start_State;
}

/*
	* @name   Stop
	* @brief  直流电机停止
	* @param  None
	* @retval None      
*/
static void Stop(void)
{
	//停止电机
	HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_3);
	HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_4);
	//更新电机状态
	DC_Motor.Status = Stop_State;
}

/*
	* @name   Direction_Adjust
	* @brief  直流电机方向调整
	* @param  None
	* @retval None      
*/
static void Direction_Adjust(void)
{
	if(DC_Motor.Status == Start_State)
	{
		if(DC_Motor.Direction == Reverse_State)
		{
			//停止转动电机
			HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_4);
			//延时100ms,待电机停止
			HAL_Delay(100);
			//正向转动电机
			HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_3);
			//更新电机方向标识
			DC_Motor.Direction = Forward_State;
		}
		else
		{
			//停止转动电机
			HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_3);
			//延时100ms,待电机停止
			HAL_Delay(100);
			//反向转动电机
			HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);
			//更新电机方向标识
			DC_Motor.Direction = Reverse_State;
		}
	}
}

/*
	* @name   Speed_Adjust
	* @brief  直流电机速度调整
	* @param  Speed_Change -> 速度变化
	* @retval None      
*/
static void Speed_Adjust(Speed_Change_t Speed_Change)
{
	if(DC_Motor.Status == Start_State)
	{
		if(Speed_Change == Speed_up)
		{
			//增大电机速度
			switch(DC_Motor.Speed)
			{
				case Speed_50:	DC_Motor.Speed = Speed_60;  break;
				case Speed_60:	DC_Motor.Speed = Speed_70;  break;
				case Speed_70:	DC_Motor.Speed = Speed_80;  break;
				case Speed_80:	DC_Motor.Speed = Speed_90;  break;
				case Speed_90:	DC_Motor.Speed = Speed_100; break;
				case Speed_100:	DC_Motor.Speed = Speed_100; break;
				default: DC_Motor.Speed = Speed_50;         
			}
		}
		else
		{
			//减小电机速度
			switch(DC_Motor.Speed)
			{
				case Speed_50:	DC_Motor.Speed = Speed_50;  break;
				case Speed_60:	DC_Motor.Speed = Speed_50;  break;
				case Speed_70:	DC_Motor.Speed = Speed_60;  break;
				case Speed_80:	DC_Motor.Speed = Speed_70;  break;
				case Speed_90:	DC_Motor.Speed = Speed_80;  break;
				case Speed_100:	DC_Motor.Speed = Speed_90;  break;
				default: DC_Motor.Speed = Speed_90;         
			}
		}
		
		//更新PWM占空比
		TIM3->CCR3 = DC_Motor.Speed;
		TIM3->CCR4 = DC_Motor.Speed;
	}
}
/********************************************************
  End Of File
********************************************************/

单极性步进电机的功能实现

注意:

在非超载的情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响。

具体驱动的拍数参考:

51单片机外设篇:电机_路溪非溪的博客-CSDN博客

步进电机的转速通常不会太快。有的最大为500HZ,即2ms走一步。

MX中初始化相关的GPIO即可。

另外,可初始化一个定时器,用来实现各节拍之间的延时。

关键代码:

/* Includes ------------------------------------------------------------------*/
#include "MyApplication.h"

/* Private define-------------------------------------------------------------*/

/* Private variables----------------------------------------------------------*/

/* Private function prototypes------------------------------------------------*/      
static void Direction_Adjust(void);        //步进电机方向调整
static void Speed_Adjust(Speed_Change_t);  //步进电机速度调整
static void Step_One_Pulse(void);          //步进电机步进一个脉冲

/* Public variables-----------------------------------------------------------*/

//定义结构体类变量
Unipolar_Step_Motor_t Unipolar_Step_Motor = 
{
  Stop_State,
	Forward_State, 
	Speed_6,
	0,
	Drive_Mode_8_Beats,
	0,
	(uint16_t)4096,
	
	Direction_Adjust,
	Speed_Adjust,
	Step_One_Pulse
};

/*
	* @name   Direction_Adjust
	* @brief  直流电机方向调整
	* @param  None
	* @retval None      
*/
static void Direction_Adjust(void)
{
	if(Unipolar_Step_Motor.Status == Start_State)
	{
		//调整电机运行方向
		if(Unipolar_Step_Motor.Direction == Reverse_State)
		{
			Unipolar_Step_Motor.Direction = Forward_State;
		}
		else
		{
			Unipolar_Step_Motor.Direction = Reverse_State;
		}
		
		Unipolar_Step_Motor.Circle = Circle_Set_Value;
		Unipolar_Step_Motor.Pulse_Cnt = 0;
		Display.Disp_HEX(Disp_NUM_6,Unipolar_Step_Motor.Circle,Disp_DP_OFF);
	}
}

/*
	* @name   Speed_Adjust
	* @brief  直流电机速度调整
	* @param  Speed_Change -> 速度变化
	* @retval None      
*/
static void Speed_Adjust(Speed_Change_t Speed_Change)
{
	uint8_t temp;
	
	if(Unipolar_Step_Motor.Status == Start_State)
	{
		if(Speed_Change == Speed_up)
		{
			//增大电机速度
			switch(Unipolar_Step_Motor.Speed)
			{
				case Speed_1: Unipolar_Step_Motor.Speed = Speed_2; temp = 2; break;
				case Speed_2: Unipolar_Step_Motor.Speed = Speed_3; temp = 3; break;
				case Speed_3: Unipolar_Step_Motor.Speed = Speed_4; temp = 4; break;
				case Speed_4: Unipolar_Step_Motor.Speed = Speed_5; temp = 5; break;
				case Speed_5: Unipolar_Step_Motor.Speed = Speed_6; temp = 6; break;
				case Speed_6: Unipolar_Step_Motor.Speed = Speed_7; temp = 7; break;
				case Speed_7: Unipolar_Step_Motor.Speed = Speed_8; temp = 8; break;
				case Speed_8: Unipolar_Step_Motor.Speed = Speed_9; temp = 9; break;
				case Speed_9: Unipolar_Step_Motor.Speed = Speed_9; temp = 9; break;
				default:Unipolar_Step_Motor.Speed = Speed_6; temp = 6; 
			}
		}
		else
		{
			//减小电机速度
			switch(Unipolar_Step_Motor.Speed)
			{
				case Speed_1: Unipolar_Step_Motor.Speed = Speed_1; temp = 1; break;
				case Speed_2: Unipolar_Step_Motor.Speed = Speed_1; temp = 1; break;
				case Speed_3: Unipolar_Step_Motor.Speed = Speed_2; temp = 2; break;
				case Speed_4: Unipolar_Step_Motor.Speed = Speed_3; temp = 3; break;
				case Speed_5: Unipolar_Step_Motor.Speed = Speed_4; temp = 4; break;
				case Speed_6: Unipolar_Step_Motor.Speed = Speed_5; temp = 5; break;
				case Speed_7: Unipolar_Step_Motor.Speed = Speed_6; temp = 6; break;
				case Speed_8: Unipolar_Step_Motor.Speed = Speed_7; temp = 7; break;
				case Speed_9: Unipolar_Step_Motor.Speed = Speed_8; temp = 8; break;
				default:Unipolar_Step_Motor.Speed = Speed_6; temp = 6; 
			}
		}
		
		//更新定时器7的计时重装载寄存器
		TIM7 ->ARR = Unipolar_Step_Motor.Speed;
		
		//更新数码管速度显示
		Display.Disp_HEX(Disp_NUM_1,temp,Disp_DP_OFF);
	}
}

/*
	* @name   Step_One_Pulse
	* @brief  步进电机步进一个脉冲
	* @param  Speed_Change -> 速度变化
	* @retval None      
*/
static void Step_One_Pulse(void)
{
	static uint8_t Position = 0;
	
	//单四拍
	if(Unipolar_Step_Motor.Drive_Mode == Drive_Mode_Single_4_Beats)
	{
		if(Unipolar_Step_Motor.Direction == Forward_State)
		{
			//正向步进  A - D - C - B
			switch(Position)
			{
				case 0: SET_Motor_A; CLR_Motor_B; CLR_Motor_C; CLR_Motor_D; break;
				case 1: CLR_Motor_A; CLR_Motor_B; CLR_Motor_C; SET_Motor_D; break;
				case 2: CLR_Motor_A; CLR_Motor_B; SET_Motor_C; CLR_Motor_D; break;
				case 3: CLR_Motor_A; SET_Motor_B; CLR_Motor_C; CLR_Motor_D; break;
				default: System.Error_Handler();
			}
		}
		else
		{
			//反向步进  A - B - C - D
			switch(Position)
			{
				case 0: SET_Motor_A; CLR_Motor_B; CLR_Motor_C; CLR_Motor_D; break;
				case 1: CLR_Motor_A; SET_Motor_B; CLR_Motor_C; CLR_Motor_D; break;
				case 2: CLR_Motor_A; CLR_Motor_B; SET_Motor_C; CLR_Motor_D; break;
				case 3: CLR_Motor_A; CLR_Motor_B; CLR_Motor_C; SET_Motor_D; break;
				default: System.Error_Handler();
			}
		}
		
		//更新位置信息
		if((++Position) == 4)
				Position = 0;
	}
	
	//双四拍
	if(Unipolar_Step_Motor.Drive_Mode == Drive_Mode_Double_4_Beats)
	{
		if(Unipolar_Step_Motor.Direction == Forward_State)
		{
			//正向步进  DA - CD - BC - AB
			switch(Position)
			{
				case 0: SET_Motor_A; CLR_Motor_B; CLR_Motor_C; SET_Motor_D; break;
				case 1: CLR_Motor_A; CLR_Motor_B; SET_Motor_C; SET_Motor_D; break;
				case 2: CLR_Motor_A; SET_Motor_B; SET_Motor_C; CLR_Motor_D; break;
				case 3: SET_Motor_A; SET_Motor_B; CLR_Motor_C; CLR_Motor_D; break;
				default: System.Error_Handler();
			}
		}
		else
		{
			//反向步进  DA - AB - BC - CD
			switch(Position)
			{
				case 0: SET_Motor_A; CLR_Motor_B; CLR_Motor_C; SET_Motor_D; break;
				case 1: SET_Motor_A; SET_Motor_B; CLR_Motor_C; CLR_Motor_D; break;
				case 2: CLR_Motor_A; SET_Motor_B; SET_Motor_C; CLR_Motor_D; break;
				case 3: CLR_Motor_A; CLR_Motor_B; SET_Motor_C; SET_Motor_D; break;
				default: System.Error_Handler();
			}
		}
		
		//更新位置信息
		if((++Position) == 4)
				Position = 0;
	}
	
	//单八拍
	if(Unipolar_Step_Motor.Drive_Mode == Drive_Mode_8_Beats)
	{
		if(Unipolar_Step_Motor.Direction == Forward_State)
		{
			//正向步进 A - DA - D - CD - C - BC - B - AB
			switch(Position)
			{
				case 0: SET_Motor_A; CLR_Motor_B; CLR_Motor_C; CLR_Motor_D; break;
				case 1: SET_Motor_A; CLR_Motor_B; CLR_Motor_C; SET_Motor_D; break;
				case 2: CLR_Motor_A; CLR_Motor_B; CLR_Motor_C; SET_Motor_D; break;
				case 3: CLR_Motor_A; CLR_Motor_B; SET_Motor_C; SET_Motor_D; break;
				case 4: CLR_Motor_A; CLR_Motor_B; SET_Motor_C; CLR_Motor_D; break;
				case 5: CLR_Motor_A; SET_Motor_B; SET_Motor_C; CLR_Motor_D; break;
				case 6: CLR_Motor_A; SET_Motor_B; CLR_Motor_C; CLR_Motor_D; break;
				case 7: SET_Motor_A; SET_Motor_B; CLR_Motor_C; CLR_Motor_D; break;
				default:System.Error_Handler();
			}
		}
		else
		{
			//反向步进 A - AB - B - BC - C -CD - D - DA 
			switch(Position)
			{
				case 0: SET_Motor_A; CLR_Motor_B; CLR_Motor_C; CLR_Motor_D; break;
				case 1: SET_Motor_A; SET_Motor_B; CLR_Motor_C; CLR_Motor_D; break; 
				case 2: CLR_Motor_A; SET_Motor_B; CLR_Motor_C; CLR_Motor_D; break;
				case 3: CLR_Motor_A; SET_Motor_B; SET_Motor_C; CLR_Motor_D; break;
				case 4: CLR_Motor_A; CLR_Motor_B; SET_Motor_C; CLR_Motor_D; break; 
				case 5: CLR_Motor_A; CLR_Motor_B; SET_Motor_C; SET_Motor_D; break;
				case 6: CLR_Motor_A; CLR_Motor_B; CLR_Motor_C; SET_Motor_D; break;
				case 7: SET_Motor_A; CLR_Motor_B; CLR_Motor_C; SET_Motor_D; break;
				default: System.Error_Handler();
			}
		}
		
		//更新位置信息
		if((++Position) == 8)
				Position = 0;
	}
}
/********************************************************
  End Of File
********************************************************/

双极性步进电机的功能实现

双极性成本高(因为有两个电流方向,所以需要2个H桥共8个MOS管),但是结构简单。

驱动方式:

关键代码如下:

/* Includes ------------------------------------------------------------------*/
#include "MyApplication.h"

/* Private define-------------------------------------------------------------*/

/* Private variables----------------------------------------------------------*/

/* Private function prototypes------------------------------------------------*/      
static void Direction_Adjust(void);        //步进电机方向调整
static void Speed_Adjust(Speed_Change_t);  //步进电机速度调整
static void Step_One_Pulse(void);          //步进电机步进一个脉冲

/* Public variables-----------------------------------------------------------*/

//定义结构体类变量
Bipolar_Step_Motor_t Bipolar_Step_Motor = 
{
  Stop_State,
	Forward_State,
	Speed_6,
	0,
	//Drive_Mode_Single_4_Beats,
	Drive_Mode_Double_4_Beats,
	//Drive_Mode_8_Beats,
	0,
	(uint8_t)48,  //4拍,一圈转48次
	//(uint8_t)96,  //8拍,一圈转96次
	
	Direction_Adjust,
	Speed_Adjust,
	Step_One_Pulse
};

/*
	* @name   Direction_Adjust
	* @brief  直流电机方向调整
	* @param  None
	* @retval None      
*/
static void Direction_Adjust(void)
{
	if(Bipolar_Step_Motor.Status == Start_State)
	{
		//调整电机运行方向
		if(Bipolar_Step_Motor.Direction == Reverse_State)
		{
			Bipolar_Step_Motor.Direction = Forward_State;
		}
		else
		{
			Bipolar_Step_Motor.Direction = Reverse_State;
		}
		
		Bipolar_Step_Motor.Circle = Circle_Set_Value;
		Bipolar_Step_Motor.Pulse_Cnt = 0;
		Display.Disp_HEX(Disp_NUM_6,Bipolar_Step_Motor.Circle/10,Disp_DP_OFF);
		Display.Disp_HEX(Disp_NUM_5,Bipolar_Step_Motor.Circle%10,Disp_DP_OFF);
	}
}

/*
	* @name   Speed_Adjust
	* @brief  直流电机速度调整
	* @param  Speed_Change -> 速度变化
	* @retval None      
*/
static void Speed_Adjust(Speed_Change_t Speed_Change)
{
	uint8_t temp;
	
	if(Bipolar_Step_Motor.Status == Start_State)
	{
		if(Speed_Change == Speed_up)
		{
			//增大电机速度
			switch(Bipolar_Step_Motor.Speed)
			{
				case Speed_1: Bipolar_Step_Motor.Speed = Speed_2; temp = 2; break;
				case Speed_2: Bipolar_Step_Motor.Speed = Speed_3; temp = 3; break;
				case Speed_3: Bipolar_Step_Motor.Speed = Speed_4; temp = 4; break;
				case Speed_4: Bipolar_Step_Motor.Speed = Speed_5; temp = 5; break;
				case Speed_5: Bipolar_Step_Motor.Speed = Speed_6; temp = 6; break;
				case Speed_6: Bipolar_Step_Motor.Speed = Speed_7; temp = 7; break;
				case Speed_7: Bipolar_Step_Motor.Speed = Speed_8; temp = 8; break;
				case Speed_8: Bipolar_Step_Motor.Speed = Speed_9; temp = 9; break;
				case Speed_9: Bipolar_Step_Motor.Speed = Speed_9; temp = 9; break;
				default:Bipolar_Step_Motor.Speed = Speed_6; temp = 6; 
			}
		}
		else
		{
			//减小电机速度
			switch(Bipolar_Step_Motor.Speed)
			{
				case Speed_1: Bipolar_Step_Motor.Speed = Speed_1; temp = 1; break;
				case Speed_2: Bipolar_Step_Motor.Speed = Speed_1; temp = 1; break;
				case Speed_3: Bipolar_Step_Motor.Speed = Speed_2; temp = 2; break;
				case Speed_4: Bipolar_Step_Motor.Speed = Speed_3; temp = 3; break;
				case Speed_5: Bipolar_Step_Motor.Speed = Speed_4; temp = 4; break;
				case Speed_6: Bipolar_Step_Motor.Speed = Speed_5; temp = 5; break;
				case Speed_7: Bipolar_Step_Motor.Speed = Speed_6; temp = 6; break;
				case Speed_8: Bipolar_Step_Motor.Speed = Speed_7; temp = 7; break;
				case Speed_9: Bipolar_Step_Motor.Speed = Speed_8; temp = 8; break;
				default:Bipolar_Step_Motor.Speed = Speed_6; temp = 6; 
			}
		}
		
		//更新定时器7的计时重装载寄存器
		TIM7 ->ARR = Bipolar_Step_Motor.Speed;
		
		//更新数码管速度显示
		Display.Disp_HEX(Disp_NUM_1,temp,Disp_DP_OFF);
	}
}

/*
	* @name   Step_One_Pulse
	* @brief  步进电机步进一个脉冲
	* @param  Speed_Change -> 速度变化
	* @retval None      
*/
static void Step_One_Pulse(void)
{
	static uint8_t Position = 0;
	
	//单四拍
	if(Bipolar_Step_Motor.Drive_Mode == Drive_Mode_Single_4_Beats)
	{
		if(Bipolar_Step_Motor.Direction == Forward_State)
		{
			//正向步进  A1 - B2 - A2 - B1
			switch(Position)
			{
				case 0: SET_Motor_A1; CLR_Motor_B1; CLR_Motor_A2; CLR_Motor_B2; break;
				case 1: CLR_Motor_A1; CLR_Motor_B1; CLR_Motor_A2; SET_Motor_B2; break;
				case 2: CLR_Motor_A1; CLR_Motor_B1; SET_Motor_A2; CLR_Motor_B2; break;
				case 3: CLR_Motor_A1; SET_Motor_B1; CLR_Motor_A2; CLR_Motor_B2; break;
				default: System.Error_Handler();
			}
		}
		else
		{
			//反向步进  A1 - B1 - A2 - B2
			switch(Position)
			{
				case 0: SET_Motor_A1; CLR_Motor_B1; CLR_Motor_A2; CLR_Motor_B2; break;
				case 1: CLR_Motor_A1; SET_Motor_B1; CLR_Motor_A2; CLR_Motor_B2; break;
				case 2: CLR_Motor_A1; CLR_Motor_B1; SET_Motor_A2; CLR_Motor_B2; break;
				case 3: CLR_Motor_A1; CLR_Motor_B1; CLR_Motor_A2; SET_Motor_B2; break;
				default: System.Error_Handler();
			}
		}
		
		//更新位置信息
		if((++Position) == 4)
				Position = 0;
	}
	
	//双四拍
	if(Bipolar_Step_Motor.Drive_Mode == Drive_Mode_Double_4_Beats)
	{
		if(Bipolar_Step_Motor.Direction == Forward_State)
		{
			//正向步进  A1B2 - B2A2 - A2B1 - B1A1
			switch(Position)
			{
				case 0: SET_Motor_A1; CLR_Motor_B1; CLR_Motor_A2; SET_Motor_B2; break;
				case 1: CLR_Motor_A1; CLR_Motor_B1; SET_Motor_A2; SET_Motor_B2; break;
				case 2: CLR_Motor_A1; SET_Motor_B1; SET_Motor_A2; CLR_Motor_B2; break;
				case 3: SET_Motor_A1; SET_Motor_B1; CLR_Motor_A2; CLR_Motor_B2; break;
				default: System.Error_Handler();
			}
		}
		else
		{
			//反向步进  A1B1 - B1A2 - A2B2 - B2A1
			switch(Position)
			{
				case 0: SET_Motor_A1; SET_Motor_B1; CLR_Motor_A2; CLR_Motor_B2; break;
				case 1: CLR_Motor_A1; SET_Motor_B1; SET_Motor_A2; CLR_Motor_B2; break;
				case 2: CLR_Motor_A1; CLR_Motor_B1; SET_Motor_A2; SET_Motor_B2; break;
				case 3: SET_Motor_A1; CLR_Motor_B1; CLR_Motor_A2; SET_Motor_B2; break;
				default: System.Error_Handler();
			}
		}
		
		//更新位置信息
		if((++Position) == 4)
				Position = 0;
	}
	
	//单八拍
	if(Bipolar_Step_Motor.Drive_Mode == Drive_Mode_8_Beats)
	{
		if(Bipolar_Step_Motor.Direction == Forward_State)
		{
			//正向步进  A1 - A1B2 - B2 - B2A2 - A2 - A2B1 - B1 - B1A1
			switch(Position)
			{
				case 0: SET_Motor_A1; CLR_Motor_B1; CLR_Motor_A2; CLR_Motor_B2; break;
				case 1: SET_Motor_A1; CLR_Motor_B1; CLR_Motor_A2; SET_Motor_B2; break;
				case 2: CLR_Motor_A1; CLR_Motor_B1; CLR_Motor_A2; SET_Motor_B2; break;
				case 3: CLR_Motor_A1; CLR_Motor_B1; SET_Motor_A2; SET_Motor_B2; break;
				case 4: CLR_Motor_A1; CLR_Motor_B1; SET_Motor_A2; CLR_Motor_B2; break;
				case 5: CLR_Motor_A1; SET_Motor_B1; SET_Motor_A2; CLR_Motor_B2; break;
				case 6: CLR_Motor_A1; SET_Motor_B1; CLR_Motor_A2; CLR_Motor_B2; break;
				case 7: SET_Motor_A1; SET_Motor_B1; CLR_Motor_A2; CLR_Motor_B2; break;
				default:System.Error_Handler();
			}
		}
		else
		{
			//反向步进 A1 - A1B1 - B1 - B1A2 - A2 - A2B2 - B2 - B2A1
			switch(Position)
			{
				case 0: SET_Motor_A1; CLR_Motor_B1; CLR_Motor_A2; CLR_Motor_B2; break;
				case 1: SET_Motor_A1; SET_Motor_B1; CLR_Motor_A2; CLR_Motor_B2; break;
				case 2: CLR_Motor_A1; SET_Motor_B1; CLR_Motor_A2; CLR_Motor_B2; break;
				case 3: CLR_Motor_A1; SET_Motor_B1; SET_Motor_A2; CLR_Motor_B2; break;
				case 4: CLR_Motor_A1; CLR_Motor_B1; SET_Motor_A2; CLR_Motor_B2; break;
				case 5: CLR_Motor_A1; CLR_Motor_B1; SET_Motor_A2; SET_Motor_B2; break;
				case 6: CLR_Motor_A1; CLR_Motor_B1; CLR_Motor_A2; SET_Motor_B2; break;
				case 7: SET_Motor_A1; CLR_Motor_B1; CLR_Motor_A2; SET_Motor_B2; break;
				default:System.Error_Handler();
			}
		}
		
		//更新位置信息
		if((++Position) == 8)
				Position = 0;
	}
}
/********************************************************
  End Of File
********************************************************/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值