基于STM32F103ZET6单片机的步进电机控制,用的步进电机为28BYJ-48 步进电机,驱动板为ULN2003A 驱动板。主要实现了步进电机的正反转控制,速度控制,以及控制步进电机转过一定的角度。
步进电机是一种能够把数字信号转变成执 行机构、线位移或者角位移的电机,属于数控 电机中的一种[4]。28BYJ-48 的内部结构图如图所示,这是一款永磁式、减速度比为 1:64、 四相八拍的一款步进电机。四相步进电机采用 单极性直流电源供电。只要对步进电机的各相 绕组按合适的时序供电,步进电机就能按照供 电时序步进转动[5]。它的步距角为步距的角度 为 5.625-64 而且带有减速齿轮是 1:64 因此 转 64 乘 64 个脉冲才是 1 圈。因此一个脉冲转 过 5.625 除 64=0.08789 度。四相步进电机可以 在不同的通电方式下运行,常见的通电方式有 单相绕组通电(四拍 A-B-C-D-A),双相绕组通 电 ( 四 拍 AB-BC-CD-DA-AB ) , 八 拍 (A-AB-B-BC-C-CD-D-DA-A)。而本设计则是采 用八拍通电控制的方法,利用单片机的四个 I/O 口依次对 A-AB-B-BC-C-CD-D-DA-A 相通电, 当通电的频率达到一定值时步进电机就会正向 运转,实测时这个最低的频率和步进电机供电 电压有直接关系当步进电机的供电电压越大所 需的频率就越大。改变频率则会改变步进电机 的转速。依次对 A-AD-D-DC-C-CB-B-BA-A 相通 电则会实现步进电机的反转。对四相全部输入 低电平步进电机则进入停止状态。进行一个八 拍通电后步进电机转过的角度为 0.703125° 利用这个特性就可以实现对步进电机转过角度 的控制。
?
因为单片机 I/O 端口的驱动能力不足输出 电流极小不足以驱动步进电机所以本设计就用 到了 ULN2003A 驱动板。ULN2003A 是大电流高 压驱动芯片, ULN2003A 驱动步进电机工作电压 高、工作电流大、可以较为精确的控制电机转 向、步距和速度[6]。ULN2003A 为集成达林顿管, 集成消线圈反电动势二极管,为其驱动继电器 提供了硬件条件[7]。驱动板的原理图如图五所 示,IN1 到 IN4 端口作为输入口接单片机 I/O 端口,分别于输出端口 OUT1 到 OUT4 相对应, 输出端口则接入步进电机的四相。单片机输出 的信号经由 ULN2003A 芯片放大口输入至步进 电机这样单片机就可以控制步进电机。
程序的主要设计如下:
步进电机的控制主要由 4 个 I/O 端口(LA、 LB、LC、LD)来完成,控制步进电机正转时一 个通电循环四相的电压值如表一所示,控制反 转则使正转的通电循环反转即可。程序主要通 过位带操作对 I/O 端口赋值,使用一个八元素 数组依次和 PLA、PLB、PLC、PLD 相与再赋值给 LA、LB、LC、LD 这样就实现了一个循环内四相 电压的变化。 延时是为了控制相位通电之间的间隔时间,通 过这个延时时间也可以控制步进电机的转速。 步进电机旋转角度的控制是在控制步进电机的 旋转的基础之上加了一层 for 循环,一个通电 循环步进电机旋转的角度为 0.7°所以循环的 次数则为设定的角度除以 0.7 所得的整数。
工程的主函数如下
int main() { ?? ?SysTick_Init(72); ?? ?NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); ?//中断优先级分组 分2组 ?? ?step_motor_Init(); ?? ?while(1) ?? ?{ ? ?? ??? ??? ?Step_Motor_Backward(900); ?? ??? ? ?? ?} }
控制步进电机正转
void Step_Motor_Forward(u32 nus) { ? ? volatile u8 i; ? ? u8 temp = 0; ? ? for(i = 0; i < 8; i++) ? ? { ? ? ? ? temp = steps[i]; ? ? ? ? LA = (u8)((temp&PLA) >> 0); ? ? ? ? LB = (u8)((temp&PLB) >> 1); ? ? ? ? LC = (u8)((temp&PLC) >> 2); ? ? ? ? LD = (u8)((temp&PLD) >> 3); ? ? ? ?? ? ? ? ? delay_us(nus); ? ? } ? ? Step_Motor_Stop(); }
控制电机转一定的角度
void Motor_Ctrl_Direction_Angle(u8 direction, u8 angle) { ?? ?u16 j; ?? ?if(direction == 1) ?? ?{ ?? ??? ?for(j=0;j<64*angle/45;j++)? ?? ??? ?{ ?? ??? ??? ?Step_Motor_Forward(1000);//正转 ?? ??? ?} ?? ??? ?Step_Motor_Stop();//停止 ? } ?? ?else ?? ?{ ?? ??? ?for(j=0;j<64*angle/45;j++)? ?? ??? ?{ ?? ??? ??? ?Step_Motor_Backward(1000);//反转 ?? ??? ?} ?? ??? ? Step_Motor_Stop();//停止 ?? ?}
}
|