电机基础知识参考:
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 ********************************************************/