电机笔记
步进电机
什么是步进电机
步进电机是将电脉冲信号转变为角位移或者线位移的开环控制元步进电机件。
通过控制施加在电机线圈上的电脉冲顺序、频率和数量,可以实现对步进电机的转向、速度和旋转角度的控制。
在非超载的情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响。
当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度,成为“步距角”。
步进电机距频特性
以四相步进电机为例,所谓四相,是指电机内部有4对磁极,此外还有一个公共端(COM)接电源,另外的A、B、C、D是四相的接头。
而四相电机也可以向外引出六条线(两条COM共同接入VCC),也可以引出五条线,所以我们会看到有六线四相制和五线四相制的步进电机。
如下图所示,A、B、C、D四相接头需接到单片机的IO口上,通过一定的规律改变四相接口的通电状态来控制电机的正反转动。
步进电机关键参数
- 步距角
例如,步距角 = 5.625°/64,表示施加每64个脉冲,步进电机就转动5.625度。
旋转角度与脉冲个数的计算公式:pluse = (angle/5.625)*64
转一圈所需脉冲数则为,360/5.625*64 = 4096
步进电机驱动方式
单四拍
这是最简单的步进电机驱动方式。这种方式,电机在每个瞬间只有一个线圈导通,消耗电力小,但在切换瞬间没有任何的电磁作用在转子上,容易造成振动,也容易因为惯性而失步。
双四拍
这种方式输出的转矩较大,且振动较少,切换过程中至少有一个线圈通电且作用于转子,所以比单四拍平稳,不易失步。
八拍
八拍则是综合以上两种驱动信号,使用单四拍和双四拍交替进行的方式,每传送一个激励信号,步进电机前进半个步距角。
其特点是分辨率高,运转更加平滑,也是最常用的驱动方式。
以下是这三种驱动方式的时序波形图
驱动例程代码
void MOTOR_CONTROLD(uint8_t direction) // 8拍驱动模式
{
static uint8_t step = 0;
if(1 == direction){
if(0 == step) step = 8;
step--;
}
if(0 == step){
HAL_GPIO_WritePin(STEP_A_GPIO_Port, STEP_A_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(STEP_B_GPIO_Port, STEP_B_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(STEP_C_GPIO_Port, STEP_C_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(STEP_D_GPIO_Port, STEP_D_Pin, GPIO_PIN_RESET);
}else if(1 == step){
HAL_GPIO_WritePin(STEP_A_GPIO_Port, STEP_A_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(STEP_B_GPIO_Port, STEP_B_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(STEP_C_GPIO_Port, STEP_C_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(STEP_D_GPIO_Port, STEP_D_Pin, GPIO_PIN_RESET);
}else if(2 == step){
HAL_GPIO_WritePin(STEP_A_GPIO_Port, STEP_A_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(STEP_B_GPIO_Port, STEP_B_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(STEP_C_GPIO_Port, STEP_C_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(STEP_D_GPIO_Port, STEP_D_Pin, GPIO_PIN_RESET);
}else if(3 == step){
HAL_GPIO_WritePin(STEP_A_GPIO_Port, STEP_A_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(STEP_B_GPIO_Port, STEP_B_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(STEP_C_GPIO_Port, STEP_C_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(STEP_D_GPIO_Port, STEP_D_Pin, GPIO_PIN_RESET);
}else if(4 == step){
HAL_GPIO_WritePin(STEP_A_GPIO_Port, STEP_A_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(STEP_B_GPIO_Port, STEP_B_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(STEP_C_GPIO_Port, STEP_C_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(STEP_D_GPIO_Port, STEP_D_Pin, GPIO_PIN_RESET);
}else if(5 == step){
HAL_GPIO_WritePin(STEP_A_GPIO_Port, STEP_A_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(STEP_B_GPIO_Port, STEP_B_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(STEP_C_GPIO_Port, STEP_C_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(STEP_D_GPIO_Port, STEP_D_Pin, GPIO_PIN_SET);
}else if(6 == step){
HAL_GPIO_WritePin(STEP_A_GPIO_Port, STEP_A_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(STEP_B_GPIO_Port, STEP_B_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(STEP_C_GPIO_Port, STEP_C_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(STEP_D_GPIO_Port, STEP_D_Pin, GPIO_PIN_SET);
}else if(7 == step){
HAL_GPIO_WritePin(STEP_A_GPIO_Port, STEP_A_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(STEP_B_GPIO_Port, STEP_B_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(STEP_C_GPIO_Port, STEP_C_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(STEP_D_GPIO_Port, STEP_D_Pin, GPIO_PIN_SET);
}
if(0 == direction){
step++; if(8 == step) step = 0;
}
}
void Step_Motor_Start(uint16_t angle, uint8_t direction)
{
int i = 0;
int pulse = (int)((double)(angle / 5.625) * 64) ;
for(i=0; i<pulse; i++){
MOTOR_CONTROLD(direction);
}
}