众所周知,步进电机由于使用脉冲控制,会比直流电机的控制稍难一些,但开环控制时也更加稳定。
落到做项目的时候,目前来说我都会先考虑步进电机,再去考虑直流,无刷这样的电机。包括毕设时所用的机械臂也是用3个42步进电机控制自由度,剩下一个八线四相步进电机byj-28作为末端夹爪的电机。
技术系列的文章都是在总结和捋顺我自己得到的一些经验,如有错漏欢迎讨论
控制原理
定时器中断完成脉冲计数与脉冲引脚翻转,脉冲等于设定脉冲后关闭定时器中断,重新控制步进电机时,打开相应定时器中断即可。
简单的速度控制方法
1.通过改变arr和psc的值来改变速度,其中arr控制电机转速,psc控制电机计数频率。以stm32f103为例,单片机主频为72M,说明每1000个时钟周期产生一次中断,并将输入时钟的频率分频为720倍。arr和psc值越小,速度越大。
2.通过改变步进电机驱动器的细分数,细分数越小,速度越大,步进电机步距角1.8度,转一圈需要200个脉冲,所以最小细分数是200,细分数为400的时候步进电机转动0.9度,细分数800时步进电机转动0.45度,以此类推。
3.PWM方式调速,这个方式我最初会用,后面发现在实际应用中,使用脉冲计数显然更好控制一些。
注:速度较快时步进电机可能丢转,或者是和目标位置有较大差距,所以速度要控制在合适范围内
由脉冲数计算运动距离(丝杠滑台步进电机)
假设步进电机细分数为800,步距角为1.8度,可知步进电机每次脉冲都会运动0.45度,假设丝杠螺距为5mm,说明步进电机每转一整圈就会让滑台向前运动5mm,此时:
步进电机每完成800个脉冲就会让滑台向前运动5mm
如果需要移动100mm,需要16000个脉冲
由脉冲数计算运动距离(同步轮或者齿轮)
在机械臂这样的项目里,没有丝杠这么直观的距离换算方式,以下是我选用的方式:
不算直线距离,只把角度换算成脉冲。
通过正解或逆解,输入末端位置xmm,ymm,zmm后换算成机械臂需要运动的角度,后查看大小齿轮传动比。
假设步进电机齿轮齿数是9,机械臂齿数是32:
void angle_to_pulse(void)
{
pulse_we_need = (low*9/32) / per_angle;
pulse2_we_need = (rot*9/32) / per_angle;
pulse3_we_need = (high_all*9/32) / per_angle;
printf("normalized low_pulse: %d, rot_pulse: %d, high_all_pulse: %d\r\n", pulse_we_need, pulse2_we_need, pulse3_we_need); // 调试输出
}
硬件连接
使用步进电机驱动器(其他方法会放在之后介绍),PUL-引脚控制脉冲,DIR-引脚控制方向,另外两个引脚DIR+和PUL+引出到5v,用于引脚供电,使能引脚可接可不接。
VCC和GND常接开关电源,为步进电机驱动器供电。由图片也能看出来,它可以承受9~42V的直流电压。
B+,B-,A+,A-是步进电机的接线
判断步进电机AB同相/异相的方式
一般步进电机上会有接线方式:
如果标签被撕毁,没有办法辨认,可以把四根步进电机的线两两相连,如果两条线连上之后很难拧动螺杆,说明两线同相。
控制代码解析
在中断内完成引脚翻转和中断标志位的清除
在这里面,GPIO_PIN_SET是1,GPIO_PIN_RESET是0,为了保证只运行一次相关状态,x为其他值时都保持引脚下电的状态,举个例子:MOTER1(0)、MOTER2(0)......
在这个枚举类型定义中:
-
GPIO_PIN_RESET 被定义为 0u,表示 GPIO 引脚处于低电平状态。
-
GPIO_PIN_SET 表示 GPIO 引脚处于高电平状态。
-
这种枚举类型定义常常用于创建相关常量值
在主函数中设置和重置好定时器标志位,pulse计数值后,可以通过重新开启中断的方式完成定时器计数,方向引脚上电和脉冲引脚翻转
这个函数可以设置初始速度,改变arr和psc的值,使能定时器时钟,使能定时器,设置中断优先级,是一个比较重要的定时器初始化函数