最新51单片机控制四相步进电机电路图汇总
基于51单片机步进电机的控制及细分驱动电路-简易软件

基于51单片机步进电机的控制及细分驱动电路悬赏分:20|解决时间:2009-6-22 21:11 |提问者:sailorman123我的邮箱sailor3848352@拜求高手指点,希望能附带相应的电路图,和一定的说明。
谢谢给位大虾了!!!最佳答案参考:/chary8088/blog/item/177332ce39cef70a92457ea9.html接触单片机快两年了,不过只是非常业余的兴趣,实践却不多,到现在还算是个初学者吧。
这几天给自己的任务就是搞定步进电机的单片机控制。
以前曾看过有关步进电机原理和控制的资料,毕竟自己没有做过,对其具体原理还不是很清楚。
今天从淘宝网买了一个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单片机驱动步进电机的方法默认分类2007-08-27 09:06 阅读6456 评论15 字号:大大中中小小在这里介绍一下用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 0000HLJMP MAINORG 0100HMAIN:MOV R3,#144 正转3 圈共144 脉冲START:MOV R0,#00HSTART1:MOV P2,#00HMOV A,R0MOV DPTR,#TABLEMOVC A,@A+DPTRJZ START 对A 的判断,当A = 0 时则转到STARTMOV P2,ALCALL DELAYINC R0DJNZ R3,START1MOV P2,#00HLCALL DELAY1;-----------------------------反转------------------------MOV R3,#144 反转一圈共144 个脉冲START2:MOV P2,#00HMOV R0,#05START3:MOV A,R0MOV DPTR,#TABLEMOVC A,@A+DPTRJZ START2MOV P2,ACALL DELAYINC R0DJNZ R3,START3MOV P2,#00HLCALL DELAY1LJMP MAINDELAY: MOV R7,#40 步进电机的转速M3: MOV R6,#248DJNZ R6,$DJNZ R7,M3RETDELAY1: MOV R4,#20 2S 延时子程序DEL2: MOV R3,#200DEL3: MOV R2,#250DJNZ R2,$DJNZ R3,DEL3DJNZ R4,DEL2RETTABLE:DB 30H,60H,0C0H,90H 正转表DB 00 正转结束DB 30H,90H,0C0H,60H 反转表DB 00 反转结束END51单片机控制四相步进电机拿到步进电机,根据以前看书对四相步进电机的了解,我对它进行了初步的测试,就是将5伏电源的正端接上最边上两根褐色的线,然后用5伏电源的地线分别和另外四根线(红、兰、白、橙)依次接触,发现每接触一下,步进电机便转动一个角度,来回五次,电机刚好转一圈,说明此步进电机的步进角度为360/(4×5)=18度。
51单片机驱动步进电机的方法(详解)

51单片机驱动步进电机的方法默认分类2007-08-27 09:06 阅读6456 评论15 字号:大大中中小小在这里介绍一下用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 0000HLJMP MAINORG 0100HMAIN:MOV R3,#144 正转3 圈共144 脉冲START:MOV R0,#00HSTART1:MOV P2,#00HMOV A,R0MOV DPTR,#TABLEMOVC A,@A+DPTRJZ START 对A 的判断,当A = 0 时则转到STARTMOV P2,ALCALL DELAYINC R0DJNZ R3,START1MOV P2,#00HLCALL DELAY1;-----------------------------反转------------------------MOV R3,#144 反转一圈共144 个脉冲START2:MOV P2,#00HMOV R0,#05START3:MOV A,R0MOV DPTR,#TABLEMOVC A,@A+DPTRJZ START2MOV P2,ACALL DELAYINC R0DJNZ R3,START3MOV P2,#00HLCALL DELAY1LJMP MAINDELAY: MOV R7,#40 步进电机的转速M3: MOV R6,#248DJNZ R6,$DJNZ R7,M3RETDELAY1: MOV R4,#20 2S 延时子程序DEL2: MOV R3,#200DEL3: MOV R2,#250DJNZ R2,$DJNZ R3,DEL3DJNZ R4,DEL2RETTABLE:DB 30H,60H,0C0H,90H 正转表DB 00 正转结束DB 30H,90H,0C0H,60H 反转表DB 00 反转结束END51单片机控制四相步进电机拿到步进电机,根据以前看书对四相步进电机的了解,我对它进行了初步的测试,就是将5伏电源的正端接上最边上两根褐色的线,然后用5伏电源的地线分别和另外四根线(红、兰、白、橙)依次接触,发现每接触一下,步进电机便转动一个角度,来回五次,电机刚好转一圈,说明此步进电机的步进角度为360/(4×5)=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单片机按键控制步进电机加减速及正反转

51单片机按键控制步进电机加减速及正反转之前尝试用单片机控制42步进电机正反转,电机连接导轨实现滑台前进后退,在这里分享一下测试程序及接线图,程序部分参考网上找到的,已经实际测试过,可以实现控制功能。
所用硬件:步进电机及驱动器、STC89C52单片机、直流电源1、硬件连接图•注意:上图为共阳极接法,实际连接参考总体线路连接。
•驱动器信号端定义:PUL+:脉冲信号输入正。
( CP+ )PUL-:脉冲信号输入负。
( CP- )DIR+:电机正、反转控制正。
DIR-:电机正、反转控制负。
EN+:电机脱机控制正。
EN-:电机脱机控制负。
•电机绕组连接A+:连接电机绕组A+相。
A-:连接电机绕组A-相。
B+:连接电机绕组B+相。
B-:连接电机绕组B-相。
•电源连接VCC:电源正端“+”GND:电源负端“-”注意:DC直流范围:9-32V。
不可以超过此范围,否则会无法正常工作甚至损坏驱动器.•总体线路连接输入信号共有三路,它们是:①步进脉冲信号PUL+,PUL-;②方向电平信号DIR+,DIR-③脱机信号EN+,EN-。
输入信号接口有两种接法,可根据需要采用共阳极接法或共阴极接法。
在这里我采用的是共阴极接法:分别将PUL-,DIR-,EN-连接到控制系统的地端(接入单片机地端);脉冲输入信号通过PUL+接入单片机(代码中给的P2^6脚),方向信号通过DIR+接入单片机(代码中给的P2^4脚),使能信号通过EN+接入(不接也可,代码中未接,置空)。
按键连接见代码,分别用5个按键控制电机启动、反转、加速、减速、正反转。
注意:接线时请断开电源,电机接线需注意不要错相,相内相间短路,以免损坏驱动器。
2、代码1.#include<reg51.h>2.#define MotorTabNum 53.unsigned char T0_NUM;4.sbit K1 = P3^5; // 启动5.sbit K2 = P3^4; // 反转6.sbit K3 = P3^3; // 加速7.sbit K4 = P3^2; // 减速8.sbit K5 = P3^1; //正反转9.10.sbit FX = P2^4; // 方向11.//sbit MotorEn = P2^5; // 使能12.sbit CLK = P2^6; // 脉冲13.14.inttable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};15.16.unsigned char g_MotorSt = 0; //17.unsigned char g_MotorDir = 0; //18.unsigned char MotorTab[7] = {12, 10, 8, 6, 4, 2,1};19.20.signed char g_MotorNum = 0;21.22.void delayms(xms);23.void mDelay(unsigned int DelayTime);24.void T0_Init();25.26.void KeyScan(void);27.28.29.30.void main(void)31.{32.T0_Init();33.// MotorEn = 0; //34.FX = 0;35.while(1)36.{37.KeyScan(); //38.}39.40.41.}42.43.void T0_Init()44.{45.TMOD = 0x01;46.TH0 = (65535-100)/256; // 1ms47.TL0 = (65535-100)%256;48.EA = 1;49.ET0 = 1;50.// TR0 = 1;51.52.}53.54.void T0_time() interrupt 155.{56.// TR0 = 0;57.TH0 = (65535-100)/256;58.TL0 = (65535-100)%256;59.T0_NUM++;60.if(T0_NUM >= MotorTab[g_MotorNum]) //61.{62.T0_NUM = 0;63.CLK=CLK^0x01; //64.}65.// TR0 = 1;66.}67.68.69.//--------------------------70.void KeyScan(void)71.{72.if(K1 == 0)73.{74.delayms(10);75.if(K1 == 0)76.{77.g_MotorSt = g_MotorSt ^ 0x01;78.// MotorEn ^= 1;79.TR0 = 1;80.FX ^= 0; //反转81.}82.}83.84.if(K2 == 0)85.{86.delayms(10); //正转87.if(K2 == 0)88.{89.g_MotorDir = g_MotorDir ^ 0x01;90.FX ^= 1; //加速91.}92.}93.94.if(K3 == 0) //95.{96.delayms(5); //加速97.if(K3 == 0)98.{99.g_MotorNum++;100.if(g_MotorNum > MotorTabNum) 101.g_MotorNum = MotorTabNum; 102.}103.}105.if(K4 == 0) //106.{107.delayms(5); // 减速108.if(K4 == 0)109.{110.g_MotorNum--;111.if(g_MotorNum < 0)112.g_MotorNum = 0;113.}114.}115.116.if(K5 == 0) //117.{118.delayms(10); // 正反转119.if(K5 == 0)120.{121.g_MotorSt = g_MotorSt ^ 0x01; 122.g_MotorDir = g_MotorDir ^ 0x01; 123.MotorEn ^= 1;124.TR0 = 1;125.while(1)126.{127.FX ^= 1; //128.delayms(90000);129.FX ^= 0; //130.delayms(90000);131.}132.}133.}135.136.void delayms(xms)//延时137.{138.unsigned int x,y;139.for(x=xms;x>0;x--)140.for(y=110;y>0;y--);141.}3、常见问题解答•控制信号高于5v一定要串联电阻,否则可能会烧坏驱动器控制接口电路。
51单片机电路图

12864液晶插针及对比度调节电位器
573供电跳线端子,控制数码管独立供电 连接到573电源引脚 非易失性存储器EEPROM AT24C02
RP1 VCC U7 1 2 3 4 A0 A1 A2 GND 24C02 VCC WP SCL SDA 8 7 6 5 SCL SDA J8 CON3 1 2 3 510 YELLOW LED4 1 2 3 4 5 6 7 8 9 VCC
U12A 1 U12B 3 U12C 5 6 U12D 9 J14 1 2 3 4 5 6 CON8 11 U12F 13 CD4069 12 U12E 10 8 J15 1 2 3 4 5 6 CON8 4 J6 1 2 3 4 5 6 7 8 CON8 3 VCC 8 C29 104 R1-R8 510 7 6 4 2 1 9 10 5 DS3 DPY_7-SEG_DP_2 DPY a a b c f b g d e e c d f dp g dp C C 2
6路反相器 CD4069
R
8个LED灯
LED1 J9 1 2 3 4 5 6 7 8 CON8 A1 A A2 A3 A A A4 VCC A 1 2 3 4 Y1 32768Hz U10 VCC2 VCC1 X1 SCLK X2 I/O GND RST DS1302 R18 R19 R20 10K 10K 10K 8 7 6 5 CON3 1 2 3 J13 BT1 BATTERY
U2 74HC573 OC C 1D 2D 3D 4D 5D 6D 7D 8D U3 74HC573 OC C 1D 2D 3D 4D 5D 6D 7D 8D 1Q 2Q 3Q 4Q 5Q 6Q 7Q 8Q 1Q 2Q 3Q 4Q 5Q 6Q 7Q 8Q
基于51单片机的步进电机控制原理

1步进电机设计模块1.1步进电机的基本工作原理及选型步进电机有三线式、五线式和六线式,但是其控制方式均相同,都要以脉冲信号电流来驱动,假设每转动一圈要200个脉冲信号来励磁,可以计算出每个励磁信号能使步进电机前进1.8°,其旋转的角度与脉冲的个数成正比。
因为六线式四相步进电机控制简单,步进精确,因此我们选用六线式四相步进电机进行设计。
他的控制等效电路如图1.1所示,他有四条励磁信号引线A,A*,B,B*, 通过控制这四条引线上的励磁脉冲产生的时刻,即可控制步进电机的转动,每出现一个脉冲信号,步进电机只走一步,因此,只要依照顺序不断地送出脉冲信号,步进电机就能实现连续转动。
A1A2B1B2A1A2红红黑B1B2绿绿白(a)等效电路(b)绕组说明图1.1步进电机的控制等效电路1.2励磁方式选择步进电机的励磁方式主要分为全步励磁和半步励磁两种,其中全步励磁又有一相励磁和二相励磁之分:半步励磁又称一-二相励磁。
1.2.1一相励磁在每一瞬间,步进电机只有一个线圈导通。
每送出一个励磁信号,步进电机旋转1.8°,这是三种励磁方式中最简单的一种。
其特点是:精确度好、消耗电力小,但输出转矩小,震动较大。
1.2.2二相励磁在每一瞬间,步进电机有两个线圈同时导通。
每送一个励磁信号,步进电机旋转1.8°。
其特点是:输出转矩大,振动小。
1.2.3一-二相励磁为一相励磁与二相励磁交替导通的方式。
每送一个励磁信号,步进电机旋转0.9°。
其特点是:分辨率高,运转平滑。
1.2.4 小结本次设计中,步进电机的工作任务是带动载物台做精确的水平移动,综合考虑各种励磁方式的优点与缺点,最终选择一-二相励磁方式,励磁顺序见表1.1。
励磁顺序说明:1-2-3-4-5-6-7-8-11.3步进电机的驱动步进电机的驱动可以选用专用的点击驱动模块,如L298,FT5754等,这类驱动模块接口简单,操作方便,它们既可以驱动步进电机,也可驱动直流电机。
51单片机驱动步进电机电路及程序

相绕组通断,P1.1控制B相,P1.2
控制C相。
2021/8/5
13
以A相控制为例:
当 P1 . 0 输 出 为 1 , 发 光管不发光,因此光敏二极 管截止,使担负驱动任务的 达林顿管导通。A相绕组通电。
相反,当P1.0=0→发 光管发光→光敏管导通→达 林顿管截止→A相绕组不通 电。
2021/8/5
2021/8/511 NhomakorabeaSUB: SETB P3.0
SETB P3.0 ;保证输出高电平的时间>5μs
SETB P3.0
CLR P3.0
;变为低电平
MOV R7,30H
LOOP: NOP
;软件延时程序:
NOP
;基本延时(10μs×时间常数)
NOP
DJNZ R7,LOOP
RET
※时间常数事先可装入30H单元,改变30H单元的内容就可改
所以按照 A→AB→B→BC→C→CA→A
的顺序控制,电机将按顺时针方向旋转, 每步转动1.5°,即步距角=1.5°,
由于要经过6步才走完一个齿距 (6×1.5°=9°),所以叫三相六拍。
2021/8/5
7
如果要使步进电机反转,只要按
A→AC→C→CB→B→BA
顺序通电就行了。
结论:从上面两种运行方式可看出,错齿是促使步
进电机旋转的根本原因,当某相通电,相应的齿对
齐,迫使电机旋转一个步距角,未通电的各相的齿
出现了新的错位。改变通电的顺序和通电的相数,
可组合出其它的运行方式。
讨论:三项三拍和三项六拍运行方式,哪种定位
2021更/8/5精确?
8
三、步进电机有如下特点:
❖ 给步进脉冲电机就转,不给步进脉冲电机就不转; ❖ 步进脉冲频率高,步进电机转得快;步进脉冲频率
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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位模式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度。
所以,我将程序代码改进了一下,如下:代码二#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位模式1ET0 = 1; //定时器0中断允许TH0 = 0xFE;TL0 = 0x0C; //设定时每隔0.5ms中断一次TR0 = 1; //开始计数do{gorun(1,60);}while(1);}//定时器0中断处理void timeint(void) interrupt 1{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){case 0:P1_0 = 1;P1_1 = 0;P1_2 = 0;P1_3 = 0;break;case 1: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;case 3: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; case 5:P1_0 = 0;P1_1 = 0;P1_2 = 1;P1_3 = 1;break; case 6:P1_0 = 0;P1_1 = 0;P1_2 = 0;P1_3 = 1;case 7: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;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{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) {case 0: //0P1_0 = 1;P1_1 = 0;P1_2 = 0;P1_3 = 0;break;case 1: //0、1P1_0 = 1;P1_1 = 1;P1_2 = 0;P1_3 = 0;break;case 2: //1P1_0 = 0;P1_1 = 1;P1_2 = 0;P1_3 = 0;break;case 3: //1、2P1_0 = 0;P1_2 = 1;P1_3 = 0;break; case 4: //2P1_0 = 0;P1_1 = 0;P1_2 = 1;P1_3 = 0;break; case 5: //2、3P1_0 = 0;P1_1 = 0;P1_2 = 1;P1_3 = 1;break; case 6: //3P1_0 = 0;P1_1 = 0;P1_2 = 0;P1_3 = 1;break; case 7: //3、0P1_0 = 1;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的转速转起来,几秒种后,再把speedlevel 设为1,此时电机就能以3000RPM的转速高速转动,这就是“加速”的效果。