以前没有搞过这东西,拿着实验室一个上一届用的步进电机(没有一点资料),电机六根线,驱动10个接口,不知道怎么连线!更关键的是不知道怎么找到这个步进电机的使用说明书!没办法呀,加入一个步进电机群,连一些最基本的常识都没有,问了一些很不专业的话,搞得别人一头雾水,哭笑不得!只听到群里一哥们儿一直说“真是不可思议”!我也只好忍着被别人笑话,向别人学东西就得谦虚!呵呵!摸索了一晚上终于有点眉目了,对步进电机也有一个大体的认识了!
步进电机
一般电动机都是连续旋转,而步进电动却是一步一步转动的,故叫步进电动机。每输入一个冲信号,该电动机就转过一定的角度(有的步进电动机可以直接输出线位移,称为直线电动机)。因此步进电动机是一种把脉冲变为角度位移(或直线位移)的执行元件。
步进电动机的转子为多极分布,定子上嵌有多相星形连接的控制绕组,由专门电源输入电脉冲信号,每输入一个脉冲信号,步进电动机的转子就前进一步。由于输入的是脉冲信号,输出的角位移是断续的,所以又称为脉冲电动机
步进电机的静态指标术语
相数:产生不同对极N、S磁场的激磁线圈对数。常用m表示。
拍数:完成一个磁场周期性变化所需脉冲数或导电状态用n表示,或指电机转过一个齿距角所需脉冲数,以四相电机为例,有四相四拍运行方式即AB-BC-CD-DA-AB,四相八拍运行方式即 A-AB-B-BC-C-CD-D-DA-A.
步距角:对应一个脉冲信号,电机转子转过的角位移用θ表示。θ=360度(转子齿数J*运行拍数),以常规二、四相,转子齿为50齿电机为例。四拍运行时步距角为θ=360度/(50*4)=1.8度(俗称整步),八拍运行时步距角为θ=360度/(50*8)=0.9度(俗称半步)。
定位转矩:电机在不通电状态下,电机转子自身的锁定力矩(由磁场齿形的谐波以及机械误差造成的)
静转矩:电机在额定静态电作用下,电机不作旋转运动时,电机转轴的锁定力矩。此力矩是衡量电机体积(几何尺寸)的标准,与驱动电压及驱动电源等无关。
虽然静转矩与电磁激磁安匝数成正比,与定齿转子间的气隙有关,但过份采用减小气隙,增加激磁安匝来提高静力矩是不可取的,这样会造成电机的发热及机械噪音。
步进电机动态指标及术语:
1、步距角精度:
步进电机每转过一个步距角的实际值与理论值的误差。用百分比表示:误差/步距角*100%。不同运行拍数其值不同,四拍运行时应在5%之内,八拍运行时应在15%以内。
2、失步:
电机运转时运转的步数,不等于理论上的步数。称之为失步。
3、失调角:
转子齿轴线偏移定子齿轴线的角度,电机运转必存在失调角,由失调角产生的误差,采用细分驱动是不能解决的。
4、最大空载起动频率:
电机在某种驱动形式、电压及额定电流下,在不加负载的情况下,能够直接起动的最大频率。
5、最大空载的运行频率:
电机在某种驱动形式,电压及额定电流下,电机不带负载的最高转速频率。
下面这些从网上抄的,没怎么仔细看不是很理解!以后用到时再说,现在先记下来!
(一)步进电机的选择
步进电机有步距角(涉及到相数)、静转矩、及电流三大要素组成。一旦三大要素确定,步进电机的型号便确定下来了。
1、步距角的选择
电机的步距角取决于负载精度的要求,将负载的最小分辨率(当量)换算到电机轴上,每个当量电机应走多少角度(包括减速)。电机的步距角应等于或小于此角度。目前市场上步进电机的步距角一般有0.36度/0.72度(五相电机)、0.9度/1.8度(二、四相电机)、1.5度/3度 (三相电机)等。
2、静力矩的选择
步进电机的动态力矩一下子很难确定,我们往往先确定电机的静力矩。静力矩选择的依据是电机工作的负载,而负载可分为惯性负载和摩擦负载二种。单一的惯性负载和单一的摩擦负载是不存在的。直接起动时(一般由低速)时二种负载均要考虑,加速起动时主要考虑惯性负载,恒速运行进只要考虑摩擦负载。一般情况下,静力矩应为摩擦负载的2-3倍内好,静力矩一旦选定,电机的机座及长度便能确定下来(几何尺寸)
3、电流的选择
静力矩一样的电机,由于电流参数不同,其运行特性差别很大,可依据矩频特性曲线图,判断电机的电流(参考驱动电源、及驱动电压)
综上所述选择电机一般应遵循以下步骤:
负载→步距角→净转矩→电流→电机型号
↑____↓↑
矩频特性曲线
4、力矩与功率换算
步进电机一般在较大范围内调速使用、其功率是变化的,一般只用力矩来衡量,力矩与功率换算如下:
P= Ω·M
Ω=2π·n/60
P=2πnM/60
其P为功率单位为瓦,Ω为每秒角速度,单位为弧度,n为每分钟转速,M为力矩单位为牛顿·米
P=2πfM/400(半步工作)
其中f为每秒脉冲数(简称PPS)
(二)、应用中的注意点
1、步进电机应用于低速场合---每分钟转速不超过1000转,(0.9度时6666PPS),最好在1000-3000PPS(0.9度)间使用,可通过减速装置使其在此间工作,此时电机工作效率高,噪音低。
2、步进电机最好不使用整步状态,整步状态时振动大。
3、由于历史原因,只有标称为12V电压的电机使用12V外,其他电机的电压值不是驱动电压伏值 ,可根据驱动器选择驱动电压(建议:57BYG采用直流24V-36V,86BYG采用直流50V,110BYG采用高于直流80V),当然12伏的电压除12V恒压驱动外也可以采用其他驱动电源, 不过要考虑温升。
4、转动惯量大的负载应选择大机座号电机。
5、电机在较高速或大惯量负载时,一般不在工作速度起动,而采用逐渐升频提速,一电机不失步,二可以减少噪音同时可以提高停止的定位精度。
6、高精度时,应通过机械减速、提高电机速度,或采用高细分数的驱动器来解决,也可以采用5相电机,不过其整个系统的价格较贵,生产厂家少,其被淘汰的说法是外行话。
7、电机不应在振动区内工作,如若必须可通过改变电压、电流或加一些阻尼的解决。
8、电机在600PPS(0.9度)以下工作,应采用小电流、大电感、低电压来驱动。
9、应遵循先选电机后选驱动的原则。
在网上终于找到电机接线资料了
3.接线端子说明
3.1电源接线:VDD :直流电源正端(不大于40VDC)
GND:直流电源地线(与输入信号CW-,CP-不共地)
3.2电机接线:A+、A-接电机线A相,B+、B-接电机线B相。
3.3控制信号:
CP+,CW+:为输入控制信号的公共阳端
CW-: 方向控制信号输入端(此端子加低电平,电机立即按反方向旋转。)
CP-: 脉冲信号输入端(在CP停止施加时,即电机锁定时,要保证CP为高电平,使内部光耦戴止。)
注:控制信号输入电流为5mA~20 mA,一般使用输入电流15 mA。
3.4指示灯:加电后电源指示灯亮,表示有电。
经常会遇到给了电机不知道电机各个接线头是属性,比如那些线是一组的,那些线是抽头!我在网上搜了一个方法试了试还挺管用的,于是复制过来了!方法如下:
六根线一般是两组的,先用万用表表笔接其中一个线,然后依次点其他的线,凡是不通的都是另外一个组的,剩下的两个是跟你接的这个是一组的,一组里面的三个线,其中一个是中心抽头,用表笔反复测试三根线,两者之间电阻最大的是线圈的两头抽头,剩下的就是中心抽头的。这样就可以测出所有的线的定义了!结合这个电机,我测了一下,黑白两根线是中间抽头,其余的为电机的四相。还有一个问题就是如何确定驱动正转和反转的顺序问题。一般步进电机的标称值是没有电压这一个参数的,但也有很多的步进电机上面标了,如果是标了电压值,那么这个标称值就是最低驱动电压,比如说标称值为5V,那么一般就要5V以上的驱动电压才能带动负载。所以你要根据你的步进电机的标称来测试你的电机,我的这个电机电压标称值是3.6V,所以我就用5V的直流稳压电源来测试了,方法如下:1、先把两个线圈的中心抽头连接起来并接5V电源的正极(也可以是负极);2、用电源负极去碰另外的4个线头,碰一次,先看电机是正转还是反转,如果是正转,那么再碰下一个,看是反的还是正的,反的就说明这个线不是你目前需要的,正的话,就是了,然后再重新来一次刚才的过程,确认一下。如此这般,就可以确定步进电机的驱动顺序了。这里还要介绍一个小细节,就是需要在电机轴上贴个小标签,以方便观察电机是否有转动,我刚开始没有贴标签,以为电机没有转动呢,比较泄气,后来想想不对劲,仿佛听到了电机内部有转动的响声啊,后来我就想是不是因为转动角度比较小,肉眼不容易察觉到,所以我就贴了一个指示标签在上面,这次果然发现碰线的时候,电机有转动的角度啦:)测试结果为:四相顺序依次为:蓝、绿、黄、红。
驱动程序:
先简单的写了一个驱动程序测试一下,还真行了!不过这个程序肯定不适用!考虑以后使用PIC的PWM功能来控制!
#ifndef MOTOR_H
#define MOTOR_H
#include "main.h"
#define CP RD0
#define CW RD1
void init_motor() ;
void motor_delay(uint count) ;
void motor_run() ;
#endif
#include "motor.h"
/***********************************
count=2 delay 40us
count=5 delay 80us
count=10 delay 136us
***************************************/
void motor_delay(uint count)
{
while(count--) ;
}
void init_motor()
{
TRISD0=0 ;
TRISD1=0 ;
}
void motor_posrun()
{
CP=1 ;
motor_delay(25) ;
CP=0 ;
motor_delay(25) ;
}
void main()
{
uint i=0 ;
init_motor() ;
while(1)
{
CW=1;
for(i=0;i<10000;i++)
{
motor_run() ;
}
motor_delay(5) ;
CW=0 ;
for(i=0;i<10000;i++)
{
motor_run() ;
}
}
}
编译一下OK,电机转动起来了,初战告捷!但是
这样电机转动的控制占用整个主程序,肯定是不适用的!所以考虑使用PIC 的PWM中断来实现电机的控制!同时准备添加上位机控制或者遥控控制功能,实现电机的步进长度和步进速度的控制!
下面是改进程序可以实现上位机的简单控制,并且程序有很好的扩展性!
头文件
#ifndef MOTOR_H
#define MOTOR_H
#include "main.h"
//if we define a motor struct and the parameter transform through pointer,the program is more perfect
//but I don't want to do it now ,the key factor is time!!!;
//define command word
#define MOTOR_START 0x01
#define MOTOR_STOP 0x02
#define MOTOR_RUN 0x03
#define MOTOR_REVERSERUN 0x04
#define MOTOR_SPEED1 0x05
#define MOTOR_SPEED2 0x06
#define MOTOR_SPEED3 0x07
//define control pin
#define CP RD0
#define CW RD1
//define function
#define motor_on() TMR2ON=1
#define motor_off() TMR2ON=0
void init_motor() ;
void motor_delay(uint count) ;
void ch_dir(uchar flag) ;
void ch_speed(uchar count) ;
void ch_state(uchar state) ;//封装所有的细节
#endif
子程序
#include "motor.h"
/***********************************
count=2 delay 40us
count=5 delay 80us
count=10 delay 136us
***************************************/
void motor_delay(uint count)
{
while(count--) ;
}
void init_motor()
{
TRISD1=0 ;//RD1引脚控制电机的方向
TRISC2=0 ;//CCP1脉宽调制输出引脚
CCP1CON=0x0c ;//定义CCP模块为脉宽调制模式
T2CON=0x7B ;//定义TMR2的前后分频比为1:16 和1:16 ;
PR2=0xf0 ;//设置信号周期为255*16*4us ;
CCPR1L=0xf0 ;//设置脉宽
// TMR2ON=1 ;
// CCP1IE=1 ;//使能CCP中断
// TMR2IE=1 ;//使能TMR2
//PEIE=1 ;
// GIE=1 ;
}
void ch_dir(uchar flag)
{
if(flag)
CW=1 ;
else
CW=0 ;
}
void ch_speed(uchar count)
{
motor_off() ;
PR2=count ;
CCPR1L=count ;
motor_on() ;
}
//there is already many extensions here ,for example ,user custom speed and speed limit and so on ;
void ch_state(uchar state)
{
switch(state)
{
case MOTOR_START :
init_motor() ;
break ;
case MOTOR_STOP :
motor_off() ;
break ;
case MOTOR_RUN :
motor_on() ;
ch_dir(1) ;
break ;
case MOTOR_REVERSERUN :
motor_on() ;
ch_dir(0) ;
break ;
case MOTOR_SPEED1 :
ch_speed(0x60) ;
break ;
case MOTOR_SPEED2 :
ch_speed(0x80) ;
break ;
case MOTOR_SPEED3 :
ch_speed(0xA0) ;
break ;
default :
motor_off() ;
}
}
主程序
#include "main.h"
#include "t232.h"
#include "motor.h"
t232_frame t_frame ;
void interrupt main_int()
{
t232_int(&t_frame) ;
}
void init_all()
{
init_232() ;
// init_motor() ;
init_t232_frame(&t_frame) ;
ch_state(MOTOR_START) ;
}
void main()
{
const char str[]= "hello world !" ;
init_all() ;
send_str(str) ;//测试串口
ch_state(MOTOR_RUN) ;
while(1)
{
if(t_frame.ready)
{
t_frame.ready=0 ;//命令已经执行
//ofcourse there is only one user here,so we don't process differet user ID and process cmd directly
ch_state(t_frame.data) ;
put_char(t_frame.data) ;//test
}
}
}
该程序还有扩展的空间,比如说电机速度到距离的转换控制等等!今晚如果时间充裕,再搞定!如果不充裕就算了!明天开始搞DS18B20温度传感器组网!将是一个难题,但我更把它看为挑战!