51单片机控制四相步进电机(详细)
51单片机细分驱动步进电机
51单片机细分驱动步进步进电机一、引言步进电机是一种将电脉冲转化为角位移的执行机构。
步进电机与普通电机最大的不同就是步进电机能很好地控制电机的旋转角度。
当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(及步进角)。
您可以通过控制脉冲个数来控制角位移量,从而达到准确定位的目的;同时您可以通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的。
步进电机原理说明请参考/Article.asp?id=1699533。
大家看到配单片机学习开发板的大多是小巧的那种两相步进电机(六线、也称四相),而实际上应用最广泛的就是工业或专用设备的24V/2~4A的步进电机,这类电机则需要专门制作或购买带细分功能的步进驱动器来驱动,所以了解和学会使用这种驱动器是单片机应用的必修课。
不过无论电机大小,原理是一样的。
二、工业用步进电机典型介绍看到网上不少单片机初学者不知道如何用驱动器去驱动大的步进电机,其实并不难,笔者前不久从仓库中翻出一个BS(白山牌)的步进驱动器和步进电机一套,特用单片机控制实验示范给狼友,下面是步进电机和驱动器外观及参数图。
电机主要参数:步距角----- 1.8°(200步/1圈,即360° / 1.8° = 200)保持转矩----- 0.9N.m电压/电流----- 24V/3.0A相电阻----- 0.75Ω相电感----- 1.1mH转子惯量----- 300g.cm2步进驱动器主要参数:反应频率 ----- 200Kpps (最高)驱动电流 ----- 0.5~4A连续可调电压范围----- DC12~40V 特殊功能:双极恒流斩波方式;步进脉冲停止超过100ms 时,电机线圈自动减半。
设有12/8档等角度恒力矩细分,最高200细分。
细分数1248163264128 D0ON OFF ON OFF ON OFF ON OFF D1ON ON OFF OFF ON ON OFF OFF D2ON ON ON ON OFF OFF OFF OFF D3无效D4ON, 双脉冲:PU为正向步进脉冲信号,DR为反向步进脉冲信号OFF, 单脉冲:PU为步进脉冲信号,DR为方向控制信号D5自检测开关(OFF时接收外部脉冲,ON时驱动器内部发7.5KHz脉冲)二、用单片机驱动步进电机经过测试和电路了解,此驱动器内部各信号输入端具有光耦隔离电路,而且只需10MA左右即可驱动,因此单片机I/O直接接到驱动器即可。
51单片机步进电机控制原理
51单片机步进电机控制原理74LS04芯片带有6个非门的芯片,是六输入反相器,也就是有6个反相器,它的输出信号与输入信号相位相反。
六个反相器。
共用电源端和接地端,其它都是独立的。
输出信号手动负载的能力也有一定程度的放大。
ULN2003芯片ULN2003是大电流驱动阵列,输入5VTTL电平,输出可达500mA/50V。
ULN2003是高压大电流达林顿晶体管阵列系列产品,具有电流增益高、工作电压高、温度范围宽、带负载能力强等特点,适应于各类要求高速大功率驱动的系统。
可直接驱动继电器等负载。
ULN2003是一个非门电路,包含7个单元,单独每个单元驱动电流最大可达350mA,9脚可以悬空。
步进电机是一种将电脉冲转化为角位移的执行机构。
通俗一点讲:当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(及步进角)。
您可以通过控制脉冲个来控制角位移量,从而达到准确定位的目的;同时您可以通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的。
步进电机28BYJ48型四相八拍电机,步距角1.8°,电压为DC5V—DC12V。
当对步进电机施加一系列连续不断的控制脉冲时,它可以连续不断地转动。
每一个脉冲信号对应步进电机的某一相或两相绕组的通电状态改变一次,也就对应转子转过一定的角度(一个步距角)。
红线接电源5V,橙、黄、粉、蓝四条电线是定子的四相绕组。
由于单片机接口信号不够大需要通过ULN2003放大再连接到相应的电机接口四相八拍驱动(A-AB-B-BC-C-CD-D-DA-A)步距角:β=360/Kmz=360/2*4*8=5.625K-通电系数,相数等于拍数取1否则取2;m-定子相数;z-转子齿数。
51单片机控制四相步进电机电路图
51单片机控制四相步进电机接触单片机快两年了,不过只是非常业余的兴趣,实践却不多,到现在还算是个初学者吧。
这几天给自己的任务就是搞定步进电机的单片机控制。
以前曾看过有关步进电机原理和控制的资料,毕竟自己没有做过,对其具体原理还不是很清楚。
今天从淘宝网买了一个EPSON的UMX-1型步进电机,此步进电机为双极性四相,接线共有六根,外形如下图所示:拿到步进电机,根据以前看书对四相步进电机的了解,我对它进行了初步的测试,就是将5伏电源的正端接上最边上两根褐色的线,然后用5伏电源的地线分别和另外四根线(红、兰、白、橙)依次接触,发现每接触一下,步进电机便转动一个角度,来回五次,电机刚好转一圈,说明此步进电机的步进角度为360/(4×5)=18度。
地线与四线接触的顺序相反,电机的转向也相反。
如果用单片机来控制此步进电机,则只需分别依次给四线一定时间的脉冲电流,电机便可连续转动起来。
通过改变脉冲电流的时间间隔,就可以实现对转速的控制;通过改变给四线脉冲电流的顺序,则可实现对转向的控制。
所以,设计了如下电路图:C51程序代码为:代码一#include <AT89X51.h>static unsigned int count;static unsigned int endcount;void delay();void main(void){count = 0;P1_0 = 0;P1_1 = 0;P1_2 = 0;P1_3 = 0;EA = 1; //允许CPU中断TMOD = 0x11; //设定时器0和1为16位模式1 ET0 = 1; //定时器0中断允许TH0 = 0xFC;TL0 = 0x18; //设定时每隔1ms中断一次TR0 = 1; //开始计数startrun:P1_3 = 0;P1_0 = 1;delay();P1_0 = 0;P1_1 = 1;delay();P1_1 = 0;P1_2 = 1;delay();P1_2 = 0;P1_3 = 1;delay();goto startrun;}//定时器0中断处理void timeint(void) interrupt 1{TH0=0xFC;TL0=0x18; //设定时每隔1ms中断一次count++;}void delay(){endcount=2;count=0;do{}while(count<endcount);}将上面的程序编译,用ISP下载线下载至单片机运行,步进电机便转动起来了,初步告捷!不过,上面的程序还只是实现了步进电机的初步控制,速度和方向的控制还不够灵活,另外,由于没有利用步进电机内线圈之间的“中间状态”,步进电机的步进角度为18度。
51单片机控制四相步进电机解析
51单片机控制四相步进电机2009年07月21日星期二 12:4451单片机控制四相步进电机2009-03-01 18:53接触单片机快两年了,不过只是非常业余的兴趣,实践却不多,到现在还算是个初学者吧。
这几天给自己的任务就是搞定步进电机的单片机控制。
以前曾看过有关步进电机原理和控制的资料,毕竟自己没有做过,对其具体原理还不是很清楚。
今天从淘宝网买了一个EPSON的UMX-1型步进电机,此步进电机为双极性四相,接线共有六根,外形如下图所示:详细内容:/31907887_d.html拿到步进电机,根据以前看书对四相步进电机的了解,我对它进行了初步的测试,就是将5伏电源的正端接上最边上两根褐色的线,然后用5伏电源的地线分别和另外四根线(红、兰、白、橙)依次接触,发现每接触一下,步进电机便转动一个角度,来回五次,电机刚好转一圈,说明此步进电机的步进角度为360/(4×5)=18度。
地线与四线接触的顺序相反,电机的转向也相反。
如果用单片机来控制此步进电机,则只需分别依次给四线一定时间的脉冲电流,电机便可连续转动起来。
通过改变脉冲电流的时间间隔,就可以实现对转速的控制;通过改变给四线脉冲电流的顺序,则可实现对转向的控制。
所以,设计了如下电路图:C51程序代码为:代码一#include <AT89X51.h>static unsigned int count;static unsigned int endcount;void delay();void main(void){count = 0;P1_0 = 0;P1_1 = 0;P1_2 = 0;P1_3 = 0;EA = 1; //允许CPU中断TMOD = 0x11; //设定时器0和1为16位模式1ET0 = 1; //定时器0中断允许TH0 = 0xFC;TL0 = 0x18; //设定时每隔1ms中断一次TR0 = 1; //开始计数startrun:P1_3 = 0;P1_0 = 1;delay();P1_0 = 0;P1_1 = 1;delay();P1_1 = 0;P1_2 = 1;delay();P1_2 = 0;P1_3 = 1;delay();goto startrun;}//定时器0中断处理void timeint(void) interrupt 1 {TH0=0xFC;TL0=0x18; //设定时每隔1ms中断一次count++;}void delay(){endcount=2;count=0;do{}while(count<endcount);}将上面的程序编译,用ISP下载线下载至单片机运行,步进电机便转动起来了,初步告捷!不过,上面的程序还只是实现了步进电机的初步控制,速度和方向的控制还不够灵活,另外,由于没有利用步进电机内线圈之间的“中间状态”,步进电机的步进角度为18度。
51单片机驱动步进电机28BYJ-48
转载51单⽚机驱动步进电机28BYJ-4851单⽚机驱动步进电机 28BYJ-48步进电机 28BYJ-48介绍和驱动及编程28BYJ-48步进电机:步进电机是⼀种将电脉冲转化为⾓位移的执⾏机构。
通俗⼀点讲:当步进驱动器接收到⼀个脉冲信号,它就驱动步进电机按设定的⽅向转动⼀个固定的⾓度(及步进⾓)。
您可以通过控制脉冲个来控制⾓位移量,从⽽达到准确定位的⽬的;同时您可以通过控制脉冲频率来控制电机转动的速度和加速度,从⽽达到调速的⽬的。
步进电机28BYJ48型四相⼋拍电机,电压为DC5V—DC12V 。
当对步进电机施加⼀系列连续不断的控制脉冲时,它可以连续不断地转动。
每⼀个脉冲信号对应步进电机的某⼀相或两相绕组的通电状态改变⼀次,也就对应转⼦转过⼀定的⾓度(⼀个步距⾓)。
当通电状态的改变完成⼀个循环时,转⼦转过⼀个齿距。
四相步进电机可以在不同的通电⽅式下运⾏,常见的通电⽅式有单(单相绕组通电)四拍(A-B-C-D-A 。
),双(双相绕组通电)四拍(AB-BC-CD-DA-AB-。
),⼋拍(A-AB-B-BC-C-CD-D-DA-A 。
)红线接电源5V ,橙⾊电线接P1.3⼝,黄⾊电线接P1.2⼝,粉⾊电线接P1.1⼝,蓝⾊接P1.0⼝。
由于单⽚机接⼝信号不够⼤需要通过ULN2003放⼤再连接到相应的电机接⼝,如下:橙黄 粉蓝⼗六制(P1⼝) 10 0 0 0x08 11 0 0 0x0c 01 0 0 0x04 01 1 0 0x06 00 1 0 0x02 00 1 1 0x03 00 0 1 0x01 10 0 1 0x09顺序刚好相反所以可以定义旋转相序uchar code CCW[8]={0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09}; //逆时钟旋转相序表uchar code CW[8]={0x09,0x01,0x03,0x02,0x06,0x04,0x0c,0x08}; //正时钟旋转相序表C 语⾔代码:#include<AT89X52.h> #include<intrins.h> #define uchar unsigned char #define uint unsigned int uchar code CCW[8]={0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09}; //逆时钟旋转相序表 uchar code CW[8]={0x09,0x01,0x03,0x02,0x06,0x04,0x0c,0x08}; //正时钟旋转相序表sbit K1=P3^2; //反转按键 sbit K2=P3^3; //正转按键 sbit K3=P3^4; //停⽌按键 sbit FMQ=P3^6; // 蜂鸣器void delaynms(uint aa){ uchar bb; while(aa--) { for(bb=0;bb<115;bb++) //1ms 基准延时程序 { ; } } }void delay500us(void){ int j; for(j=0;j<57;j++) { ; }}void beep(void){ uchart; for(t=0;t<100;t++) { delay500us(); FMQ=!FMQ; //产⽣脉冲 } FMQ=1; //关闭蜂鸣器}void motor_ccw(void){ uchar i,j; for(j=0;j<8;j++) //电机旋转⼀周,不是外⾯所看到的⼀周,是⾥⾯的传动轮转了⼀周 { if(K3==0) { break; //如果K3按下,退出此循环 } for(i=0;i<8;i++) //旋转45度 { P1=CCW[i]; delaynms(10); //调节转速 } }}void motor_cw(void){ uchar i,j; for(j=0;j<8;j++) { if(K3==0) { break; //如果K3按下,退出此循环 } for(i=0;i<8;i++) //旋转45度 { P1=CW[i]; delaynms(2); //调节转速 } }}void main(void){ uchar r; uchar N=64; //因为步进电机是减速步进电机,减速⽐的1/64 , //所以N=64时,步进电机主轴转⼀圈 while(1) { if(K1==0) { beep(); for(r=0;r<N;r++) { motor_ccw(); //电机逆转 if(K3==0) { beep(); break; } } } elseif(K2==0) { beep(); for(r=0;r<N;r++) { motor_cw(); //电机反转 if(K3==0) { beep(); break; } } } else P1=0xf0; //电机停⽌ }}附:步进电机⼩知识(转)1.什么是步进电机?步进电机是⼀种将电脉冲转化为⾓位移的执⾏机构。
51单片机实现步进电机控制
摘要8051单片机控制步进电机进行简单的转速控制,包括启停变换转速控制等。
利用利用单片机实验箱以模拟电压提供电机转速设定值,使用并行模数转换芯片ADC0809 进行电压信号的采集和数据处理转换得到速度给定的数字量,通过单片机的P1 口控制步进电机的控制端,使其按一定的控制方式进行转动。
调节步进电机转速,使其与给定值相当,最后,利用ZLG7290模块驱动LED数码管显示速度设定值。
通过这个单片机控制系统的设计来掌握A/D转换的原理,了解步进电机的工作原理,掌握它的转速控制方式和调速方法,并且掌握LED显示原理和ZLG7290模块的使用方法,用LED数码管显示模数转换的结果,设计电路的硬件接线图和实现上述要求的程序。
最后实现通过改变模拟电压就可以改变步进电机的转速控制,并且在LED 数码管上显示步进电机的转速这一功能。
关键词:51单片机调速步进电机LED显示绪论在进行51单片机的学习和实验过程中曾利用51单片机对步进电机进行过简单的控制,包括利用单片机试验箱对步进电机进行转角控制,方向控制等。
即按照设定的转动角度步进电机进行动作,来实现步进电机的实时控制,通过设定的方向来实现步进电机的方向反转控制等,并利用利用ZLG7290模块驱动LED数码管显示步进电机的设定值与步进电机实际所转过过的角度,同时显示步进电机的旋转方向等。
这次所进行的步进电机转速控制系统是对步进电机的另一种控制,即实现步进电机的转速控制而不是单单的转动角度控制,并且是通过模拟量输入来时时的控制步进电机的转速。
并且通过数码管来显示出所设定的步进电机的转速。
第一章系统程序及分析1.1对步进电机控制系统的设计要求进行设计,主程序程序如下:#include<reg51.h>#include"VIIC_C51.h"#include"zlg7290.h"sbit PA=P1^0;sbit PB=P1^1;sbit PC=P1^2;sbit PD=P1^3;sbit SDA=P1^7;sbit SCL=P1^6;sbit RST=P1^4;sbit KEY_INT=P1^5;unsigned char xdata *port;unsigned char count,count1=0,c[3],n;/*****************ADC0809*******************************************/int1()interrupt 2{count=*port;*port=0;}/*******************************************************************//*****************延迟函数*****************************************/delay(unsigned int t){unsigned int i;for(i=0;i<t;i++){TMOD=0X11;TH0=-500/256;TL0=-500%256;TR0=1;while(TF0!=1);TF0=0;}}/*****************脉冲函数********************************************/ time1()interrupt 3{if(count==0X00)count1=4;TH1=-3*1000000/(256*count);TL1=-3*1000000%(256*count);switch(count1){ case 0:{PA=1;PB=1;PC=0;PD=0;}break;case 1:{PA=0;PB=1;PC=1;PD=0;}break;case 2:{PA=0;PB=0;PC=1;PD=1;}break;case 3:{PA=1;PB=0;PC=0;PD=1;}break;default:{PA=0;PB=0;PC=0;PD=0;}}count1++;if(count1>=4){count1=0;}}/************************主函数*******************************************/ main(){ RST=0;delay(1);RST=1;delay(10);port=0x7ff8;EA=1;ET1=1;ET0=1;TMOD=0X11;TH1=-100000/256;TL1=-100000%256;TR1=1;EX1=1;IT1=1;*port=0;while(1){c[0]=count/100;c[1]=count%100/10;c[2]=count%10;for(n=0;n<3;n++)ZLG7290_SendCmd(0x60+(2-n),c[n]);}}1.2程序分析:程序的开头包含了3个头文件,第一个头文件<reg51.h>中对所有的特殊功能寄存器进行了SFR定义,只要引用了<reg51.h> 就可以直接引用特殊功能寄存器名。
基于51单片机的步进电机控制系统设计与实现
步进电机工作原理
步进电机是一种基于磁场的控制系统,工作原理是当电流通过定子绕组时,会 产生一个磁场,该磁场会吸引转子铁芯到相应的位置,从而产生一定的角位移。 步进电机的角位移量与输入的脉冲数量成正比,因此,通过控制输入的脉冲数 量和频率,可以实现精确的角位移和速度控制。同时,步进电机具有较高的分 辨率和灵敏度,可以满足各种高精度应用场景的需求。
二、系统设计
1、硬件设计
本系统主要包括51单片机、步进电机、驱动器、按键和LED显示等部分。其中, 51单片机负责接收按键输入并控制步进电机的运动;步进电机用于驱动负载运 动;驱动器负责将51单片机的输出信号放大,以驱动步进电机。LED显示用于 显示当前步进电机的状态。
2、软件设计
软件部分主要包括按键处理、步进电机控制和LED显示等模块。按键处理模块 负责接收用户输入,并根据输入控制步进电机的运动;步进电机控制模块根据 按键输入和当前步进电机的状态,计算出步进电机下一步的运动状态;LED显 示模块则负责实时更新LED显示。
三、系统实现
1、按键输入的实现
为了实现按键输入,我们需要在主程序中定义按键处理函数。当按键被按下时, 函数将读取按键的值,并将其存储在全局变量中。这样,主程序可以根据按键 的值来控制步进电机的转动。
2、显示输出的实现
为了实现显示输出,我们需要使用单片机的输出口来控制显示模块的输入。在 中断服务程序中,我们根据设定的值来更新显示模块的输出,以反映步进电机 的实时转动状态。
基于单片机的步进电机控制系统需要硬件部分主要包括单片机、步进电机、驱 动器、按键和显示模块等。其中,单片机作为系统的核心,负责处理按键输入、 控制步进电机转动以及显示输出等功能。步进电机选用四相八拍步进电机,驱 动器选择适合该电机的驱动器,按键用于输入设定值,显示模块用于显示当前 步进电机的转动状态。
51单片机驱动步进电机__终极完整版
51单片机驱动步进电机__终极(完整版)在这里介绍一下用51单片机驱动步进电机的方法。
这款步进电机的驱动电压12V,步进角为 7.5度 . 一圈360 度 , 需要 48 个脉冲完成!!!该步进电机有6根引线,排列次序如下:1:红色、2:红色、3:橙色、4:棕色、5:黄色、6:黑色。
采用51驱动ULN2003的方法进行驱动。
ULN2003的驱动直接用单片机系统的5V电压,可能力矩不是很大,大家可自行加大驱动电压到12V。
;************************************************ ******************************;************************* 步进电机的驱动*************************************** ; DESIGN BY BENLADN911 FOSC = 12MHz 2005.05.19;---------------------------------------------------------------------------------; 步进电机的驱动信号必须为脉冲信号!!! 转动的速度和脉冲的频率成正比!!!; 本步进电机步进角为 7.5度 . 一圈 360 度 , 需要48 个脉冲完成!!!;---------------------------------------------------------------------------------; A组线圈对应 P2.4; B组线圈对应 P2.5; C组线圈对应 P2.6; D组线圈对应 P2.7; 正转次序: AB组--BC组--CD组--DA组 (即一个脉冲,正转 7.5 度);----------------------------------------------------------------------------------;----------------------------正转-------------------------- ORG 0000H LJMP MAIN ORG 0100HMAIN:MOV R3,#144 正转 3 圈共 144 脉冲 START: MOVR0,#00H START1: MOV P2,#00H MOV A,R0MOV DPTR,#TABLE MOVC A,@A+DPTRJZ START 对 A 的判断,当 A = 0 时则转到 START MOV P2,ALCALL DELAY INC R0DJNZ R3,START1MOV P2,#00H LCALL DELAY1;-----------------------------反转------------------------MOV R3,#144 反转一圈共 144 个脉冲 START2:MOV P2,#00H MOV R0,#05 START3: MOV A,R0MOV DPTR,#TABLE MOVC A,@A+DPTR JZ START2 MOV P2,A CALL DELAY INC R0DJNZ R3,START3 MOV P2,#00HLCALL DELAY1 LJMP MAINDELAY: MOV R7,#40 步进电机的转速 M3: MOV R6,#248 DJNZ R6,$ DJNZ R7,M3RETDELAY1: MOV R4,#20 2S 延时子程序 DEL2: MOV R3,#200 DEL3: MOV R2,#250 DJNZ R2,$ DJNZ R3,DEL3 DJNZ R4,DEL2 RET TABLE:DB 30H,60H,0C0H,90H 正转表 DB 00 正转结束DB 30H,90H,0C0H,60H 反转表 DB 00 反转结束 END 51单片机控制四相步进电机拿到步进电机,根据以前看书对四相步进电机的了解,我对它进行了初步的测试,就是将5伏电源的正端接上最边上两根褐色的线,然后用5伏电源的地线分别和另外四根线(红、兰、白、橙)依次接触,发现每接触一下,步进电机便转动一个角度,来回五次,电机刚好转一圈,说明此步进电机的步进角度为 360/(4×5)=18度。
51单片机驱动步进电机的方法
51单片机驱动步进电机的方法一、步进电机简介步进电机是一种将电脉冲转化为角位移的执行机构,广泛应用于各种自动化设备中。
其工作原理是,当一个脉冲信号输入时,电机转动一个步距角,从而实现电机的精确控制。
二、51单片机驱动步进电机的方法1、硬件连接需要将51单片机与步进电机连接起来。
通常,步进电机需要四个引脚,分别连接到单片机的四个GPIO引脚上。
同时,还需要连接一个驱动器来提高电机的驱动能力。
2、驱动程序编写接下来,需要编写驱动程序来控制步进电机的转动。
在51单片机中,可以使用定时器或延时函数来产生脉冲信号,然后通过GPIO引脚输出给电机。
同时,还需要设置电机的步距角和转向,以保证电机的精确控制。
3、示例程序以下是一个简单的示例程序,用于演示如何使用51单片机驱动步进电机:cinclude <reg52.h> //包含51单片机的头文件sbit motorPin1=P1^0; //定义连接到P1.0引脚的电机引脚sbit motorPin2=P1^1; //定义连接到P1.1引脚的电机引脚sbit motorPin3=P1^2; //定义连接到P1.2引脚的电机引脚sbit motorPin4=P1^3; //定义连接到P1.3引脚的电机引脚void delay(unsigned int time) //延时函数unsigned int i,j;for(i=0;i<time;i++)for(j=0;j<1275;j++);void forward(unsigned int step) //正转函数motorPin1=0;motorPin2=0;motorPin3=0;motorPin4=0; //清零电机引脚delay(step); //延时一段时间motorPin1=1;motorPin3=1;motorPin2=0;motorPin4=0; //设置转向和步距角delay(step); //延时一段时间void backward(unsigned int step) //反转函数motorPin1=0;motorPin2=0;motorPin3=0;motorPin4=0; //清零电机引脚delay(step); //延时一段时间motorPin2=1;motorPin4=1;motorPin3=0;motorPin1=0; //设置转向和步距角delay(step); //延时一段时间void main() //主函数unsigned int step=1000; //设置步距角为1000微步forward(step); //正转一圈backward(step); //反转一圈while(1); //循环等待,保持电机转动状态在这个示例程序中,我们使用了四个GPIO引脚来控制步进电机的转动。
用51单片机控制两相四线步进电机
用51单片机控制两相四线步进电机最近学习步进电机的驱动原理,照着教材自己实践了一下用ULN2003驱动28BYJ-48两相5线步进电机,可以正常转动。
手头有一个旧光驱,拆开发现里面有三个电机,其中有一个控制激光头寻迹的两相四线步进电机,我就用51的单片机让它也转起来。
一开始照葫芦画瓢用ULN2003驱动,结果发现无论如何也不行。
原来ULN2003基本没输出电流,只能驱动有公共端的两相五线、两相六线步进电机,不能驱动2相4线步进电机。
然后改用L293D驱动,可以转动。
通过按钮控制正反转时发现,按键释放后,电机迅速发热,烫手。
用万用表测量,发现电机A,A-或B,B-直接存在电位差!应该是按键释放时,IN1-IN4没有归零。
找到问题,就容易解决了。
修改程序,可以完美运行,键1按下正转,释放停下,键2按下反转,释放停下。
IN1-IN4分别接P1口的低四位。
工作方式选用8拍。
A 1 1 0 0 0 0 0 1A- 0 0 0 1 1 1 0 0B 0 1 1 1 0 0 0 0B- 0 0 0 0 0 1 1 1附上源程序,仅供参考。
#include#define uint unsigned int#define uchar unsigned charsbit K3=P2^5;sbit K4=P2^4;//k3正转。
k4反转。
释放停止uchar code step_table[]={0x8,0xa,0x2,0x6,0x4,0x5,0x1,0x9};void delay(unsigned int m){unsigned int i,j;for(i=m;i>0;i--)for(j=110;j>0;j--);}void xp()//x轴正转{while(!K3){uint i;for(i=0;i<8;i++){P1=step_table[ i];delay(10);}}P1=0;//按键释放时,反转P1停在table某处,导致电机有电压从而使电机发热,需要归零。
51单片机控制步进电机
设计方案与原理1 设计方案设计一个51单片机四相步进电机控制系统要求系统具有如下功能:(1)由I/O口产生的时序方波作为电机控制信号;(2)信号经过驱动芯片驱动电机的运转;(3)电机的状态通过键盘控制,包括正转,反转,加速,减速,停止和单步运行。
2 设计原理步进电机实际上是一个数字\角度转换器,也是一个串行的数\模转换器。
步进电机的基本控制包括启停控制、转向控制、速度控制、换向控制4个方面。
从结构上看,步进电机分为三相、四相、五相等类型,本次设计的是四相电机。
四相步进电机的工作方式有单四拍、双四拍和单双八拍三种。
在本次设计中,我们使用的是四相单八拍的工作方式。
通过P1口给A,B,C,D四相依次输出高电平即可实现步进电机的旋转,通过控制两次输出的间隔,即可实现对步进电机的速度控制。
图 2.1 步进电机内部结构截图根据步进电机的相关相序表我们可以正常的控制电机的步进运行。
3 硬件设计根据设计要求和设计原理,我们可以绘制出基本的功能方框图,以便之后我们连接实际电路时的方便和可靠。
用键盘控制具体的功能模块,这样更能直观方便的控制整体的系统,使其达到我们预期的操作效果。
图3.1中简单描述了整个单片机系统的控制模式和控制流程,包括通过时钟电路和键盘电路,来控制ULN2003驱动电机动作。
图表图 3.1 硬件电路功能方框图4 电路原理图4.C程序代码#include <reg52.h>#define KeyPort P3#define DataPort P0 //定义数据端口程序中遇到DataPort 则用P0 替换sbit LATCH1=P2^2;//定义锁存使能端口段锁存sbit LATCH2=P2^3;// 位锁存unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码unsigned char TempData[8]; //存储显示值的全局变量sbit A1=P1^0; //定义步进电机连接端口sbit B1=P1^1;sbit C1=P1^2;sbit D1=P1^3;#define Coil_AB1 {A1=1;B1=1;C1=0;D1=0;}//AB相通电,其他相断电#define Coil_BC1 {A1=0;B1=1;C1=1;D1=0;}//BC相通电,其他相断电#define Coil_CD1 {A1=0;B1=0;C1=1;D1=1;}//CD相通电,其他相断电#define Coil_DA1 {A1=1;B1=0;C1=0;D1=1;}//DA相通电,其他相断电#define Coil_A1 {A1=1;B1=0;C1=0;D1=0;}//A相通电,其他相断电#define Coil_B1 {A1=0;B1=1;C1=0;D1=0;}//B相通电,其他相断电#define Coil_C1 {A1=0;B1=0;C1=1;D1=0;}//C相通电,其他相断电#define Coil_D1 {A1=0;B1=0;C1=0;D1=1;}//D相通电,其他相断电#define Coil_OFF {A1=0;B1=0;C1=0;D1=0;}//全部断电unsigned char Speed=1;bit StopFlag;void Display(unsigned char FirstBit,unsigned char Num);void Init_Timer0(void);unsigned char KeyScan(void);/*------------------------------------------------uS延时函数,含有输入参数 unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编,大致延时长度如下 T=tx2+5 uS------------------------------------------------*/void DelayUs2x(unsigned char t){while(--t);}/*------------------------------------------------mS延时函数,含有输入参数 unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编------------------------------------------------*/void DelayMs(unsigned char t)while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}/*------------------------------------------------主函数------------------------------------------------*/ main(){unsigned int i=512;//旋转一周时间unsigned int n=0;unsigned char num,vo,v;Init_Timer0();Coil_OFF;while(1) //正向{num=KeyScan(); //循环调用按键扫描if(num==1)//第一个按键,速度等级增加{if(Speed<15)Speed=Speed+2;}if(num==2)//第二个按键,速度等级减小{if(Speed>1)Speed=Speed-2;}if(num==3)//第三个按键,电机停转{Coil_OFFStopFlag=1;}if(num==4)//第四个按键,电机启动{StopFlag=0;TR0=1;}if(num==5)//第五个按键,电机反转{TR0=0;TR1=1;}if(num==6)//第六个按键,电机正传{TR0=1;TR1=0;}vo=(0.25*(20-Speed)*64*32)/1000;v=60/vo;TempData[0]=dofly_DuanMa[v/10]; //分解显示信息,如要显示68,则68/10=6 68%10=8TempData[1]=dofly_DuanMa[v%10];}}/*------------------------------------------------显示函数,用于动态扫描数码管输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示如输入0表示从第一个显示。
基于51单片机的步进电机的控制设计
单片机应用系统设计报告设计题目:步进电机控制器设计专业班级:学生姓名:指导教师:设计时间: 2016年12月一、 设计要求及方案 1、设计要求可以实现步进电机正转和反转控制及速度的控制,同时实现步进电机步数的控制。
2、设计方案本次设计采用AT89C51单片机控制一个四相步进电机。
单片机输出脉冲序列,驱动步进电机转动;并设置开关、按键电路,来控制步进电机的2挡转速,即加速、减速;以及步数的变化,即四拍驱动方式、八拍驱动方式,同时控制步进电机的转动方向,即正转、反转。
设计方案总体框图:二、步进电机简介 1、步进电机工作原理步进电机是一种将电脉冲转化为角位移的执行机构。
当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(称为“步距角”),它的旋转是以固定的角度一步一步运行的。
可以通过控制脉冲个数来控制角位移量,从而达到准确定位的目的;同时可以通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的。
步进电机可以作为一种控制用的特种电机,利用其没有积累误差(精度为100%)的特点,广泛应用于各种开环控制。
步进电机是一种感应电机,它的工作原理是利用电子电路,将直流电变成分时供电的,多相时序控制电流,用这种电流为步进电机供电,步进电机才能正常工作,驱动器就是为步进电机分时供电的多相时序控制器。
虽然步进电机已被广泛地应用,但步进电机并不能象普通的直流电机,交流电机在常规下使用。
它必须由双环形脉冲信号、功率驱动电路等组成控制系统方可使用。
因此用好步进电机却非易事,它涉及到机械、电机、电子及计算机等许多专业知识。
步进电机作为执行元件,是机电一体化的关键产品之一, 广泛应用在各种自动化控制系统中。
随着微电子和计算机技术的发展,步进电机的需求量与日俱增,在各个国民经济领域都有应用。
2、步进电机磁力方式选择步进电机的励磁方式主要分为全步励磁和半步励磁两种,其中全步励磁又有一相励磁和二相励磁之分,半步励磁又称一-二相励磁。
基于51单片机的步进电机直线插补
基于51单片机的步进电机直线插补目录第1章概述............................................................................................. 错误!未定义书签。
第2章设计内容的介绍.. (2)2.1步进电机原理 (2)2.2步进电机的选择 (4)2.3直线插补原理 (5)2.4设计目标 (7)第3章设计思路具体内容 (7)3.1设计思路 (7)3.2单片机及其最小系统 (7)3.3 按键电路 (8)3.4 步进电机驱动电路 (9)3.5液晶显示 (9)第四章程序设计 (11)第五章总结 ............................................................................................ 错误!未定义书签。
参考文献 . (12)附录 (13)摘要本设计为基于51单片机,利用两个四相八拍步进电机,实现四个象限中直线插补的过程。
其中一个电机正反转实现X正负方向的插补,另一个电机正反转代表Y轴正负方向插补。
并对该插补算法的原理及其实现过程进行了阐述,通过按键启动插补过程,插补结束后电机自动停止。
通过LCD1602液晶实现插补过程中插补方向的显示,最终完成了步进电机的插补过程。
关键词步进电机直线插补液晶显示第1章概述数字控制是近代发展起来的一种自动控制技术,利用数字化信号对机床及其加工过程进行自动控制,主要用于数控机床、线切割机、焊接机、气割机以及低速小型数字绘图仪等。
数控机床可以加工形状复杂的零件,具有加工精度高、生产效率高、便于改变加工零件品种等众多优点,是实现机床自动化的一个重要发展方向。
逐点比较法是数控机床在加工曲线时常用的一种方法,是常用的脉冲增量插补方法。
它是以阶梯折线来逼近直线或圆弧等曲线,与规定的加工直线或圆弧之间的最大误差为一个脉冲当量,当脉冲当量足够小时,就可以达到相当高的加工精度。
51单片机控制步进电机硬件图及C语言编程
51单片机控制步进电机硬件图#include <reg51.h> //51芯片管脚定义头文件#include <intrins.h> //内部包含延时函数_nop_();#include<absacc.h>#define uchar unsigned char#define uint unsigned intuchar code FFW[8]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09}; //四相八拍正转编码uchar code REV[8]={0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01}; ////四相八拍反转编码sbit P14=P1^4; //将P14位定义为P1.4引脚sbit P15=P1^5; //将P15位定义为P1.5引脚sbit P16=P1^6; //将P16位定义为P1.6引脚sbit P17=P1^7; //将P17位定义为P1.7引脚sbit P20=P2^0; //将P20位定义为P2.0引脚sbit P21=P2^1; //将P21位定义为P2.1引脚sbit P22=P2^2; //将P22位定义为P2.2引脚sbit P23=P2^3; //将P23位定义为P2.3引脚sbit P24=P2^4; //将P24位定义为P2.4引脚sbit P25=P2^5; //将P25位定义为P2.5引脚sbit P26=P2^6; //将P26位定义为P2.6引脚sbit P27=P2^7; //将P27位定义为P2.7引脚sbit P34=P3^4; //将P34位定义为P3.4引脚sbit P35=P3^5; //将P35位定义为P3.5引脚sbit P36=P3^6; //将P36位定义为P3.6引脚sbit P37=P3^7; //将P37位定义为P3.7引脚sbit P30=P3^0; //将P30位定义为P3.0引脚sbit P31=P3^1; //将P31位定义为P3.1引脚sbit BEEP=P3^2; // 蜂鸣器bit on=0;bit off=1; //运行与停止标志bit zdirection=0; //方向标志bit fdirection=0; //方向标志uchar h,l,k; //定义行键值//定义列键值uchar idata count[3]; //0-9数值储存unsigned char code Tab[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //数字0~9的段码uchar keyval=0; //定义变量储存按键值uchar dat=0; //按键值uint run_i=0;uchar count_i=0;uint run=0; //需要运行的步数uint drun=0; //当前运行的步数bit flag;uint x=60;uint y=60;uint z=0;/* uint k=0; //调速按键次*//**************************************************************/ void led_delay1(void){unsigned char j;for(j=0;j<52;j++);}void beep(){uchar j;for (j=0;j<200;j++){led_delay1();BEEP=!BEEP; //BEEP取反}BEEP=1; //关闭蜂鸣器}/**************************************************************函数功能:数码管动态扫描延时**************************************************************/void led_delay(void){unsigned char j;for(j=0;j<200;j++);}/**************************************************************/**************************************************************函数功能:软件延时去抖动子程序**************************************************************/void delay20ms(void){unsigned char i,j;for(i=0;i<70;i++)for(j=0;j<60;j++);}void display(uint run){ //显示设点步数P31=1; //点亮数码管DS6P30=0;P34=0;P35=0;P36=0;P37=0;P14=0;P15=0;if((run/100)!=0){ P0=Tab[run/100]; //显示百位led_delay(); //动态扫描延时led_delay(); //动态扫描延时}P0=0xff;P30=1;P31=0;P34=0;P36=0;P37=0;P14=0;P15=0;if(((run%100/10)==0)&&(run/10==0)) { P0=0xff;led_delay(); //动态扫描延时led_delay();} //点亮数码管DS5else{ P0=Tab[run%100/10]; //显示十位led_delay(); //动态扫描延时led_delay(); //动态扫描延时}P0=0xff;P37=1; //点亮数码管DS4P30=0;P34=0;P35=0;P36=0;P31=0;P14=0;P15=0;if((run/10==0)&&(run%100/10==0)&&(run%10==0)){ P0=0xff;led_delay(); //动态扫描延时led_delay(); //动态扫描延时}else{ P0=Tab[run%10]; //显示个位led_delay(); //动态扫描延时led_delay(); //动态扫描延时}P0=0xff;}/*********************************************************************/void ddisplay(uint drun){ //显示运行步数P36=1; //点亮数码管DS3P30=0;P34=0;P35=0;P31=0;P37=0;P15=0;if((drun/100)!=0){P0=Tab[drun/100]; //显示百位led_delay(); //动态扫描延时led_delay(); //动态扫描延时}P0=0xff;P35=1; //点亮数码管DS2P30=0;P34=0;P31=0;P36=0;P37=0;P14=0;P15=0;if(((drun%100/10)==0)&&(drun/10==0)) { P0=0xff;led_delay(); //动态扫描延时led_delay();}//点亮数码管DS5else{ P0=Tab[drun%100/10]; //显示十位led_delay(); //动态扫描延时led_delay(); //动态扫描延时}P0=0xff;P34=1; //点亮数码管DS1P30=0;P31=0;P35=0;P36=0;P37=0;P14=0;P15=0;if((drun/10==0)&&(drun%100/10==0)&&(drun%10==0)){ P0=0xff;led_delay(); //动态扫描延时led_delay(); //动态扫描延时}else{ P0=Tab[drun%10]; //显示个位led_delay(); //动态扫描延时led_delay(); //动态扫描延时}P0=0xff;}void dddisplay(){ P15=1;P36=0;P30=0;P34=0;P35=0;P31=0;P37=0;P14=0;if((fdirection==1)&&(on==1)){P0=0xbf; led_delay(); led_delay(); }P0=0xff;P14=1;P36=0;P30=0;P34=0;P35=0;P31=0;P37=0;P15=0;if(y==60){P0=0x08;led_delay(); led_delay();}if(y==50){P0=0x03; led_delay(); led_delay(); }if(y==40){P0=0x46; led_delay(); led_delay();}if(y==30){P0=0x21 ;led_delay(); led_delay();}if(y==20){P0=0x86; led_delay(); led_delay(); }if(y==10){P0=0x8e; led_delay(); led_delay();}P0=0xff;}/************************************************************** 函数功能:主函数**************************************************************/ void main(void){ x=60;P14=0;P15=0;P16=0;P17=0;EA=1;EX1=1; //允许使用外中断IT1=1; //选择负跳变来触发外中断PT0=1;ET0=1; //定时器T0中断允许TMOD=0x01; //使用定时器T0的模式1TH0=0xec; //定时器T0的高8位赋初值TL0=0x78; //定时器T0的低8位赋初值TR0=1;P30=1; //启动定时器T0P34=1;P35=1;P36=1;P37=1;P31=1;P2=0xf0;while(1){if(flag){P2=0x0f; h=P2&0x0f; //所有行线置为高电平"1",所有列线置为低电平"0",并把值给hif((P2&0x0f)!=0x0f) //行线中有一位为低电平"0",说明有键按下delay20ms(); //延时一段时间、软件消抖else {keyval=16;}if(h!=0x0f) //确实有键按下{h=P2&0x0f; //读取行值P2=0xf0; //反转电位l=P2&0xf0; //读取列值k=h+l; //行列相加,为键位值if(k==0x7e) keyval=12;if(k==0x7d) keyval=0;if(k==0x7b) keyval=13;if(k==0x77) keyval=15;if(k==0xbe) keyval=1;if(k==0xbd) keyval=2;if(k==0xbb) keyval=3;if(k==0xb7) keyval=14; //键位与设定对应if(k==0xde) keyval=4;if(k==0xdd) keyval=5;if(k==0xdb) keyval=6;if(k==0xd7) keyval=11;if(k==0xee) keyval=7;if(k==0xed) keyval=8;if(k==0xeb) keyval=9;if(k==0xe7) keyval=10;}else keyval=16;dat=keyval;if((dat==10)&&(run!=0)) //正转键按下{zdirection=1; //方向标志fdirection=0;on=1; //运行与停止标志off=0;}if((dat==11)&&(run!=0)) //反转键按下{fdirection=1; //方向标志zdirection=0;on=1; //运行与停止标志off=0;}if(dat==12) //加速键{if(y==10) y=10;else y=y-10;}if(dat==13) //减速键{if(y==60) y=y;else y=y+10;}if((dat==14)&&(run!=0)) //开始键按下{ if(z==1) {on=1;}elseon=1;off=0;z=0;if((zdirection==0)&&(fdirection==0)){zdirection=1;}}if(dat==15) { z++;on=0; } //停止键按下一次if((on==0)&&(z==2)) //停止键按下二次{count[0]=0; //显示清零count[1]=0;count[2]=0;drun=0; run=0;z=0;on=0;off=1; //运行与停止标志}if((dat>=0)&&(dat<=9)&&(on==0)&&(off==1)){count[count_i]=dat;if(count[0]!=0){count_i++;}if((count_i==3)&&(on==0)&(off==1)){count_i=0;}if((count_i==0)&&(on==0)&(off==1)){ if(count[0]==0)run=0;else run=count[0]*100+count[1]*10+count[2];}if((count_i==1)&&(on==0)&(off==1)){run=count[0];}if((count_i==2)&&(on==0)&(off==1)){run=count[0]*10+count[1];}}if((dat==0)&&(on==1)){off=1;}if(dat==16);flag=0;}/*if(run!=0){*/ddisplay(drun);dddisplay();display(run);/*} */ //调用按键值的数码管显示子程序if((run==drun)&&run!=0){on=0;off=1;beep();drun=0; run=0;count[0]=0; //显示清零count[1]=0;count[2]=0;count_i=0;}}}/**************************************************************外部中断键盘扫描键值保存在dat中******************************************************************************* ************/void Interrupt1() interrupt 2 using 3{flag=1;}/*************************************************************************/ void Interrupt2() interrupt 1 using 1{ TR0=0;EX1=1;TH0=0xec;TL0=0x78;x--;if(x==0){if((zdirection==1)&&(fdirection==0)&&(on==1)&&(off==0)){P1=FFW[run_i];fdirection=0;led_delay(); //动态扫描延时led_delay(); //动态扫描延时led_delay(); //动态扫描延时led_delay(); //动态扫描延时drun++;run_i++;if(run_i==8)run_i=0;if(run==drun){on=0;off=1;}}if((zdirection==0)&&(fdirection==1)&&(on==1)&&(off==0)){P1=REV[run_i];led_delay(); //动态扫描延时led_delay(); //动态扫描延时led_delay(); //动态扫描延时led_delay(); //动态扫描延时zdirection=0;drun++;run_i++;if(run_i==8)run_i=0;if(run==drun){on=0;off=1;}}if((on==0)&&(off=1))P1=0x00; x=y;}TR0=1;}。
STC增强型51单片机利用PWM脉冲控制4个57步进电机的编程方法
IAP15W4K58S4单片机利用PWM脉冲控制4个步进电机的编程方法最近购入一块IAP15W4K58S4(图1)的STC单片机的最小系统,然后用它控制步进电机,步进电机驱动器为基于TB6600的MicroStep Driver(图2)驱动器。
为了能控制该驱动器,利用现有的单片机系统控制驱动器。
连接电路原理图如图3所示,图中Vcc=5V.图1 IAP15W4K58S4单片机最小系统图2 步进电机驱动器使IAP15W4K58S4单片机能够控制步进电机,首先需要产生PWM脉冲,本例子产生频率为1KHz,占空比为50%的脉冲,P2.1、P2.2、P2.3、P3.7口输出4路PWM脉冲。
生产PWM脉冲,单片机涉及到的寄存器(不考虑PWM中断)有P_SW2(端口配置寄存器)、PWMCFG(PWM配置寄存器,初始电平高低)、PWMCKS(PWM时钟选择寄存器)、由PWMCH(高7位)和PWMCL(低8位)组成的15位PWM计数器、由PWM n T1H、PWM n T1L和PWM n T2H、PWM n T2L组成的PWM脉冲翻转计数器(其中PWM n T1H、PWM n T1L组成第一次翻转15位计数器,其中PWM n T2H、PWM n T2L组成第二次翻转15位计数器,n取值范围为2、3、4、5、6、7)、PWM n CR(PWM n的控制寄存器,设置输出管脚选择和中断使能控制,n取值范围为2、3、4、5、6、7)和PWMCR(PWM控制寄存器,用于开启各个端口和PWM模块开关,该寄存器最后设置)。
由于生成PWM,需将I/O 口配置为准双向口或强推挽模式,所以还需配置P m M0和P m M1寄存器,m取值范围为0~3。
以上寄存器各个位配置可参考该单片机的数据手册,本项目的例程参考STC官方例程基础进行修改,如后文所述。
IAP15W4K58S4单片机的特殊功能寄存器区中要使用扩展的特殊功能寄存器需要配置P_SW2的bit7位,将其(bit7)置1。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
作者:易劲松QQ:371719025Email:yijingsong@接触单片机快两年了,不过只是非常业余的兴趣,实践却不多,到现在还算是个初学者吧。
这几天给自己的任务就是搞定步进电机的单片机控制。
以前曾看过有关步进电机原理和控制的资料,毕竟自己没有做过,对其具体原理还不是很清楚。
今天从淘宝网买了一个EPSON的UMX-1型步进电机,此步进电机为双极性四相,接线共有六根,外形如下图所示:拿到步进电机,根据以前看书对四相步进电机的了解,我对它进行了初步的测试,就是将5伏电源的正端接上最边上两根褐色的线,然后用5伏电源的地线分别和另外四根线(红、兰、白、橙)依次接触,发现每接触一下,步进电机便转动一个角度,来回五次,电机刚好转一圈,说明此步进电机的步进角度为3 60/(4×5)=18度。
地线与四线接触的顺序相反,电机的转向也相反。
如果用单片机来控制此步进电机,则只需分别依次给四线一定时间的脉冲电流,电机便可连续转动起来。
通过改变脉冲电流的时间间隔,就可以实现对转速的控制;通过改变给四线脉冲电流的顺序,则可实现对转向的控制。
所以,设计了如下电路图:制作的实物图如下:C51程序代码为:代码一#include<AT89X51.h>static unsigned int count;static unsigned int endcount;void delay();void main(void){count = 0;P1_0 = 0;P1_1 = 0;P1_2 = 0;P1_3 = 0;EA = 1; //允许CPU中断TMOD = 0x11; //设定时器0和1为16位模式1 ET0 = 1; //定时器0中断允许TH0 = 0xFC;TL0 = 0x18; //设定时每隔1ms中断一次TR0 = 1; //开始计数startrun:P1_3 = 0;P1_0 = 1;delay();P1_0 = 0;P1_1 = 1;delay();P1_1 = 0;P1_2 = 1;delay();P1_2 = 0;P1_3 = 1;delay();goto startrun;}//定时器0中断处理void timeint(void) interrupt1{TH0=0xFC;TL0=0x18; //设定时每隔1ms中断一次count++;}void delay(){endcount=2;count=0;do{}while(count<endcount);}将上面的程序编译,用ISP下载线下载至单片机运行,步进电机便转动起来了,初步告捷!不过,上面的程序还只是实现了步进电机的初步控制,速度和方向的控制还不够灵活,另外,由于没有利用步进电机内线圈之间的“中间状态”,步进电机的步进角度为18度。
所以,我将程序代码改进了一下,如下:代码二#include<AT89X51.h>static unsigned int count;static int step_index;void delay(unsigned int endcount);void gorun(bit turn, unsigned int speedlevel);void main(void){count = 0;step_index = 0;P1_0 = 0;P1_1 = 0;P1_2 = 0;P1_3 = 0;EA = 1; //允许CPU中断TMOD = 0x11; //设定时器0和1为16位模式1 ET0 = 1; //定时器0中断允许TH0 = 0xFE;TL0 = 0x0C; //设定时每隔0.5ms中断一次TR0 = 1; //开始计数do{gorun(1,60);}while(1);}//定时器0中断处理void timeint(void) interrupt1{TH0=0xFE;TL0=0x0C;//设定时每隔0.5ms中断一次count++;}void delay(unsigned int endcount){count=0;do{}while(count<endcount);}void gorun(bit turn,unsigned int speedlevel) {switch(step_index){case0:P1_0 = 1;P1_1 = 0;P1_2 = 0;P1_3 = 0;break;case1:P1_0 = 1;P1_1 = 1;P1_2 = 0;P1_3 = 0;break;case 2:P1_0 = 0;P1_1 = 1;P1_2 = 0;P1_3 = 0;break;case3:P1_0 = 0;P1_1 = 1;P1_2 = 1;P1_3 = 0;break;case 4:P1_0 = 0;P1_1 = 0;P1_2 = 1;P1_3 = 0;break;case5:P1_0 = 0;P1_1 = 0;P1_2 = 1;P1_3 = 1;break;case6:P1_0 = 0;P1_1 = 0;P1_2 = 0;P1_3 = 1;break;case7:P1_0 = 1;P1_1 = 0;P1_2 = 0;P1_3 = 1;}delay(speedlevel);if(turn==0){step_index++;if (step_index>7)step_index=0;}else{step_index--;if (step_index<0)step_index=7;}}改进的代码能实现速度和方向的控制,而且,通过step_index静态全局变量能“记住”步进电机的步进位置,下次调用gorun()函数时则可直接从上次步进位置继续转动,从而实现精确步进;另外,由于利用了步进电机内线圈之间的“中间状态”,步进角度减小了一半,只为9度,低速运转也相对稳定一些了。
但是,在代码二中,步进电机的运转控制是在主函数中,如果程序还需执行其它任务,则有可能使步进电机的运转收到影响,另外还有其它方面的不便,总之不是很完美的控制。
所以我又将代码再次改进:代码三#include<AT89X51.h>static unsigned int count; //计数static int step_index; //步进索引数,值为0-7static bit turn; //步进电机转动方向static bit stop_flag; //步进电机停止标志static int speedlevel; //步进电机转速参数,数值越大速度越慢,最小值为1,速度最快static int spcount; //步进电机转速参数计数void delay(unsigned int endcount); //延时函数,延时为endcount*0.5毫秒void gorun(); //步进电机控制步进函数void main(void){count = 0;step_index = 0;spcount = 0;stop_flag = 0;P1_0 = 0;P1_1 = 0;P1_2 = 0;P1_3 = 0;EA = 1; //允许CPU中断TMOD = 0x11;//设定时器0和1为16位模式1ET0 = 1; //定时器0中断允许TH0 = 0xFE;TL0 = 0x0C; //设定时每隔0.5ms中断一次TR0 = 1; //开始计数turn = 0;speedlevel = 2;delay(10000);speedlevel = 1;do{speedlevel = 2;delay(10000);speedlevel = 1;delay(10000);stop_flag=1;delay(10000);stop_flag=0;}while(1);}//定时器0中断处理void timeint(void) interrupt 1{TH0=0xFE;TL0=0x0C; //设定时每隔0.5ms中断一次count++;spcount--;if(spcount<=0){spcount = speedlevel;gorun();}}void delay(unsigned int endcount) {count=0;do{}while(count<endcount);}void gorun(){if(stop_flag==1){P1_0 = 0;P1_1 = 0;P1_2 = 0;P1_3 = 0;return;}switch(step_index){case0: //0P1_1 = 0;P1_2 = 0;P1_3 = 0; break;case1: //0、1 P1_0 = 1;P1_1 = 1;P1_2 = 0;P1_3 = 0; break;case2: //1P1_0 = 0;P1_1 = 1;P1_2 = 0;P1_3 = 0; break;case3: //1、2 P1_0 = 0;P1_1 = 1;P1_2 = 1;P1_3 = 0; break;case4: //2P1_0 = 0;P1_1 = 0;P1_2 = 1;P1_3 = 0; break;case5: //2、3 P1_0 = 0;P1_1 = 0;P1_2 = 1;P1_3 = 1; break;case6: //3P1_0 = 0;P1_1 = 0;P1_2 = 0;P1_3 = 1; break;case7: //3、0P1_1 = 0;P1_2 = 0;P1_3 = 1;}if (turn==0){step_index++;if(step_index>7)step_index=0;}else{step_index--;if(step_index<0)step_index=7;}}在代码三中,我将步进电机的运转控制放在时间中断函数之中,这样主函数就能很方便的加入其它任务的执行,而对步进电机的运转不产生影响。
在此代码中,不但实现了步进电机的转速和转向的控制,另外还加了一个停止的功能,呵呵,这肯定是需要的。
步进电机从静止到高速转动需要一个加速的过程,否则电机很容易被“卡住”,代码一、二实现加速不是很方便,而在代码三中,加速则很容易了。
在此代码中,当转速参数speedlevel 为2时,可以算出,此时步进电机的转速为1500RPM,而当转速参数speedlevel 1时,转速为3000RPM。
当步进电机停止,如果直接将speedlevel 设为1,此时步进电机将被“卡住”,而如果先把speedlevel 设为2,让电机以1500RPM的转速转起来,几秒种后,再把s peedlevel 设为1,此时电机就能以3000RPM的转速高速转动,这就是“加速”的效果。