单片机直驱两相四线步进电机研究及应用
【本文发布于https://blog.csdn.net/Stack_/article/details/132236329,未经允许不得转载,转载须注明出处】
双极性步进电机(两相四线步进电机),原理的东西就先不讲太多了,还没搞清楚,边查资料边写代码来理解吧。
此电路使用4片CMS6324去驱动2个H桥,每片CMS6324驱动的桥的同一侧,其自带硬件死区,所以不需要考虑死区插入的问题。如果不是这样的电路,则需要注意上下桥臂不能同时导通。
一、电机基本原理图 内部简化图
四拍,每个脉冲转 1.8°
八拍,每个脉冲转 0.9°
二、简单的驱动代码
#define MOTOR_A_P_PORT PORT1 //P15 A+
#define MOTOR_A_P_PIN PIN5
#define MOTOR_A_N_PORT PORT1 //P14 A-
#define MOTOR_A_N_PIN PIN4
#define MOTOR_B_P_PORT PORT1 //P13 B+
#define MOTOR_B_P_PIN PIN3
#define MOTOR_B_N_PORT PORT1 //P12 B-
#define MOTOR_B_N_PIN PIN2
#define MOTOR_A_P__SET() PORT_SetBit(MOTOR_A_P_PORT, MOTOR_A_P_PIN)
#define MOTOR_A_P__RESET() PORT_ClrBit(MOTOR_A_P_PORT, MOTOR_A_P_PIN)
#define MOTOR_A_N__SET() PORT_SetBit(MOTOR_A_N_PORT, MOTOR_A_N_PIN)
#define MOTOR_A_N__RESET() PORT_ClrBit(MOTOR_A_N_PORT, MOTOR_A_N_PIN)
#define MOTOR_B_P__SET() PORT_SetBit(MOTOR_B_P_PORT, MOTOR_B_P_PIN)
#define MOTOR_B_P__RESET() PORT_ClrBit(MOTOR_B_P_PORT, MOTOR_B_P_PIN)
#define MOTOR_B_N__SET() PORT_SetBit(MOTOR_B_N_PORT, MOTOR_B_N_PIN)
#define MOTOR_B_N__RESET() PORT_ClrBit(MOTOR_B_N_PORT, MOTOR_B_N_PIN)
PORT_Init(MOTOR_A_P_PORT, MOTOR_A_P_PIN, OUTPUT); //P15 A+
PORT_Init(MOTOR_A_N_PORT, MOTOR_A_N_PIN, OUTPUT); //P14 A-
PORT_Init(MOTOR_B_P_PORT, MOTOR_B_P_PIN, OUTPUT); //P13 B+
PORT_Init(MOTOR_B_N_PORT, MOTOR_B_N_PIN, OUTPUT); //P12 B-
PORT_Init(PORT3, PIN0, OUTPUT); //P30 CMS6021 POWER_EN, 使能CMS6324供电
PORT_SetBit(PORT3, PIN0);
while(1)
{
#if (0) //四拍
#if (0) //四拍正转
//A+
MOTOR_A_P__SET();
MOTOR_B_P__RESET();
MOTOR_A_N__RESET();
MOTOR_B_N__RESET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
//B+
MOTOR_A_P__RESET();
MOTOR_B_P__SET();
MOTOR_A_N__RESET();
MOTOR_B_N__RESET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
//A-
MOTOR_A_P__RESET();
MOTOR_B_P__RESET();
MOTOR_A_N__SET();
MOTOR_B_N__RESET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
//B-
MOTOR_A_P__RESET();
MOTOR_B_P__RESET();
MOTOR_A_N__RESET();
MOTOR_B_N__SET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
#else //四拍反转
//A+
MOTOR_A_P__SET();
MOTOR_B_P__RESET();
MOTOR_A_N__RESET();
MOTOR_B_N__RESET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
//B-
MOTOR_A_P__RESET();
MOTOR_B_P__RESET();
MOTOR_A_N__RESET();
MOTOR_B_N__SET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
//A-
MOTOR_A_P__RESET();
MOTOR_B_P__RESET();
MOTOR_A_N__SET();
MOTOR_B_N__RESET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
//B+
MOTOR_A_P__RESET();
MOTOR_B_P__SET();
MOTOR_A_N__RESET();
MOTOR_B_N__RESET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
#endif
#else //八拍
#if (0) //八拍正向
//A+
MOTOR_A_P__SET();
MOTOR_B_P__RESET();
MOTOR_A_N__RESET();
MOTOR_B_N__RESET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
//A+ B+
MOTOR_A_P__SET();
MOTOR_B_P__SET();
MOTOR_A_N__RESET();
MOTOR_B_N__RESET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
//B+
MOTOR_A_P__RESET();
MOTOR_B_P__SET();
MOTOR_A_N__RESET();
MOTOR_B_N__RESET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
//B+ A-
MOTOR_A_P__RESET();
MOTOR_B_P__SET();
MOTOR_A_N__SET();
MOTOR_B_N__RESET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
//A-
MOTOR_A_P__RESET();
MOTOR_B_P__RESET();
MOTOR_A_N__SET();
MOTOR_B_N__RESET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
//A- B-
MOTOR_A_P__RESET();
MOTOR_B_P__RESET();
MOTOR_A_N__SET();
MOTOR_B_N__SET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
//B-
MOTOR_A_P__RESET();
MOTOR_B_P__RESET();
MOTOR_A_N__RESET();
MOTOR_B_N__SET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
//B- A+
MOTOR_A_P__SET();
MOTOR_B_P__RESET();
MOTOR_A_N__RESET();
MOTOR_B_N__SET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
#else //八拍反向
//A+
MOTOR_A_P__SET();
MOTOR_B_P__RESET();
MOTOR_A_N__RESET();
MOTOR_B_N__RESET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
//B- A+
MOTOR_A_P__SET();
MOTOR_B_P__RESET();
MOTOR_A_N__RESET();
MOTOR_B_N__SET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
//B-
MOTOR_A_P__RESET();
MOTOR_B_P__RESET();
MOTOR_A_N__RESET();
MOTOR_B_N__SET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
//A- B-
MOTOR_A_P__RESET();
MOTOR_B_P__RESET();
MOTOR_A_N__SET();
MOTOR_B_N__SET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
//A-
MOTOR_A_P__RESET();
MOTOR_B_P__RESET();
MOTOR_A_N__SET();
MOTOR_B_N__RESET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
//B+ A-
MOTOR_A_P__RESET();
MOTOR_B_P__SET();
MOTOR_A_N__SET();
MOTOR_B_N__RESET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
//B+
MOTOR_A_P__RESET();
MOTOR_B_P__SET();
MOTOR_A_N__RESET();
MOTOR_B_N__RESET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
//A+ B+
MOTOR_A_P__SET();
MOTOR_B_P__SET();
MOTOR_A_N__RESET();
MOTOR_B_N__RESET();
UserTimer_Reset(&timer_delay);
while(UserTimer_Read(&timer_delay) < TIMEOUT_1MS);
#endif
#endif
}
黄波形为A+ 蓝波形为B+ 紫波形为A- 绿波形为B- |
四拍正转,每个正脉冲转1.8°,360°/1.8°=200个脉冲转一圈。一次循环A+ B+ A- B-四个脉冲,循环50次即转一圈。
四拍反转。四拍时,1ms切换太快了,会严重丢步,转动非常卡顿,将延时即切换时间适当拉长可获得较为平顺的效果。但导通时间过长会导致总电流很大。
八拍正转。拍数增加,转动相较于4拍平顺了不少
八拍反转
三、抓取步进电机驱动芯片/驱动器的四线波形进行对比
实际驱动时,不会像上面的那么“生硬”的,而是会不断调节输出的占空比的。例如下面抓取的波形
1、市面上驱动器驱动波形类型一。这种驱动方式横容易理解,跟上面相似
正转。可见,大体思路和上面的是一致的,只不过为了驱动更平顺以及功耗的考虑,各线通电时不是恒导通的,而是以PWM的方式进行输出
反转
每一相通电时,其正占空比都是先增后减,即电流先增后减
当速度提高,换相频率变高。一般地,功率也需要提高,速度不变负载增加,功率也需提高(需要接编码器),所以正占空比(平均)也变大了,电流变大
2、市面上驱动器驱动波形类型二。这种方式4根线上都是持续不断输出20kHz的波形的,分别控制A+和A-的占空比,以实现控制A相电流大小与方向的效果,如下列图中的红色波形。B+和B-同理。
① 正转
正转
A电流反向(A-流向A+)之前以及之后
A电流反向(A+流向A-)之前以及之后
② 反转
反转
A电流反向(A-流向A+)之前以及之后
A电流反向(A+流向A-)之前以及之后
以上为波形研究,待续
作者:Tyrion.Mon