51单片机控制步进电机程序及硬件电路图

合集下载

51单片机按键控制步进电机加减速及正反转

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单片机控制步进电机正反转

基于51单片机控制步进电机正反转

基于51单片机控制步进电机正反转此次采用uln2003模块来链接步进电机;## 步进电机工作原理步进电机是一种将电脉冲信号转换成相应角位移或线位移的电动机。

每输入一个脉冲信号,转子就转动一个角度或前进一步,其输出的角位移或线位移与输入的脉冲数成正比,转速与脉冲频率成正比。

步进电动机的结构形式和分类方法较多,一般按励磁方式分为磁阻式、永磁式和混磁式三种;按相数可分为单相、两相、三相和多相等形式。

因此我们可以控制单片机I/O口的电平来控制步进电机,此次设计中采用四相单拍工作方式,在这种工作方式下,A、B、C、D 三相轮流通电,电流切换三次,磁场旋转一周,转子向前转过一个齿距角。

因此这种通电方式叫做四相单四拍工作方式。

1.电机正转代码unsigned char code tableZ[8]={0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09};2.电机反转代码unsigned char code tableF[8]={0x09,0x01,0x03,0x02,0x06,0x04,0x0c,0x08};代码如下#include <reg52.h>#define uint unsigned int #define uchar unsigned charunsigned char code tableZ[8]={0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09};unsigned char code tableF[8]={0x09,0x01,0x03,0x02,0x06,0x04,0x0c,0x08};//²½½øµç»úzhengvoid delay(unsigned int t);sbit S3=P3^4; //反转sbit S4=P3^5; //反停sbit S5=P3^6; // 正停//正转写入数据void motor_z() { unsigned char i,j; for (i=0; i<8; i++) { if(S5==0){break;} for(j=0;j<8;j++){ P1 = tableZ[i]&0x1f; delay(50); } } }//反转写入数据void motor_f(){ unsigned char i,j; for (i=0; i<8; i++) { if(S4==0){break;} for(j=0;j<8;j++){ P1 = tableF[i]&0x1f;delay(50); } }}void delay(unsigned int t)//延时函数{ unsigned int k; while(t--) { for(k=0; k<60; k++) { } }}void main(){while(1){motor_z();if(S3 == 0){motor_f();}}}•1•2•3•4•5•6•7•8•9•10•11•12•13•14•15•16•17•18•19•20•21•22•23•24•25•26•27•29 •30 •31 •32 •33 •34 •35 •36 •37 •38 •39 •40 •41 •42 •43 •44 •45 •46 •47 •48 •49 •50 •51 •52 •53 •54 •55 •56 •1•3 •4 •5 •6 •7 •8 •9 •10 •11 •12 •13 •14 •15 •16 •17 •18 •19 •20 •21 •22 •23 •24 •25 •26 •27 •28 •29 •30 •31•33•34•35•36•37•38•39•40•41•42•43•44•45•46•47•48•49•50•51•52•53•54•55•56protel仿真图如下。

51单片机实现步进电机控制

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单片机驱动步进电机电路及程序

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
三、步进电机有如下特点:
❖ 给步进脉冲电机就转,不给步进脉冲电机就不转; ❖ 步进脉冲频率高,步进电机转得快;步进脉冲频率

基于51单片机的步进电机驱动电路设计

基于51单片机的步进电机驱动电路设计

基于51单片机的步进电机驱动电路设计
步进电机在控制系统中具有广泛的应用。

它可以把脉冲信号转换成角位移,并且可用作电磁制动轮、电磁差分器、或角位移发生器等。

有时从一些旧设备上拆下的步进电机(这种电机一般没有损坏)要改作它用,一般需自己设计驱动器。

本文介绍的就是为从一日本产旧式打印机上拆下的步进电机而设计的驱动器。

本文先介绍该步进电机的工作原理,然后介绍了其驱动器的软、硬件设计。

1. 步进电机的工作原理
该步进电机为一四相步进电机,采用单极性直流电源供电。

只要对步进电机的各相绕组按合适的时序通电,就能使步进电机步进转动。

图1 是该四相反应式步进电机工作原理示意图。

图1 四相步进电机步进示意图
开始时,开关SB 接通电源,SA、SC、SD 断开,B 相磁极和转子0、3 号齿对齐,同时,转子的1、4 号齿就和C、D 相绕组磁极产生错齿,2、5 号齿就和D、A 相绕组磁极产生错齿。

当开关SC 接通电源,SB、SA、SD 断开时,由于C 相绕组的磁力线和1、4 号齿之间磁力线的作用,使转子转动,
1、4 号齿和C 相绕组的磁极对齐。

而0、3 号齿和A、B 相绕组产生错齿,
2、5 号齿就和A、D 相绕组磁极产生错齿。

依次类推,A、B、C、D 四相绕组轮流供电,则转子会沿着A、B、C、D 方向转动。

四相步进电机按照通电顺序的不同,可分为单四拍、双四拍、八拍三种工作方式。

单四拍与双四拍的步距角相等,但单四拍的转动力矩小。

八拍工作方式的步距角是单四拍与双四拍的一半,因此,八拍工作方式既可以保持较高的转动力矩又可以提高控制。

51单片机控制步进电机程序及硬件电路图

51单片机控制步进电机程序及硬件电路图

#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位模式1 ET0 = 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){case 0: //0P1_0 = 1;P1_1 = 0;P1_2 = 0;P1_3 = 0; break; case 1: //0、1 P1_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、2 P1_0 = 0;P1_1 = 1;P1_2 = 1;P1_3 = 0;break; case 4: //2 P1_0 = 0;P1_1 = 0;P1_2 = 1;P1_3 = 0; break; case 5: //2、3 P1_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、0 P1_0 = 1;P1_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; }}。

51单片机控制两相四线步进电机

源程序如下:ENA EQU P1.0 ENB EQU P1.1IN1 EQU P1.2IN2 EQU P1.3IN3 EQU P1.4IN4 EQU P1.5 SWITCH EQU P3.3 FAST EQU P3.6 SLOW EQU P3.5CYCLENUM EQU 50H ;存放对应定时循环次数TEMP EQU 53H ;存放按键次数。

初值为5,每按加速叠加1,按减速递减MARK EQU 56H ;启动停止标识LEDBUF EQU 57HORG 0AJMP START;*****************检测是否开启启动电机键***************************START:MOV P0,#0 ;清显示SETB MARK ;预启动电机工作,标识为1MOV TEMP,#5 ;开始工作于5HzMOV CYCLENUM,#01H ;循环1次JNB SWITCH,NEXT ;按键按下?SJMP START ;没有返回继续检测NEXT:CALL DELAY ;消抖确认JNB SWITCH,MAIN ;再次确认按键,不为1说明按键按下SJMP START ;没有按下,继续检测;*****************开始运行电机***************************************MAIN:MOV A,TEMPMOV DPTR,#TAB4MOVC A,@A+DPTRMOV LEDBUF,A ;送显示CALL DISPLAYLOOP:JB MARK,WORK ;检测运行标识是否为1,为1则继续运行,为0则停止运行NOTWORK:CLR ENACLR ENBSJMP STARTWORK:MOV P1,#000010111B ;步进电机运行方式为两相四拍CALL TIMERCALL TESTSTOPMOV P1,#000011011B ;第二拍CALL TIMERCALL TESTSTOPMOV P1,#000101011B ;第三拍CALL TIMERCALL TESTSTOPMOV P1,#000100111B ;第四拍CALL TIMERCALL TESTSTOPCALL TESTKEYSJMP MAIN;***************************检测是否有按键按下************************TESTKEY:SETB FASTSETB SLOWNEXT1:JNB FAST,YES2NEXT2:JNB SLOW,YES3SJMP RETURN ;都没有键按下,则返回YES2:MOV A,TEMP ;FAST按下,若此时temp等于9,则保持速度不变,若小于则加1 CJNE A,#9,CANFASTDEC ACANFAST:INC AMOV TEMP,ASJMP RETURNYES3:MOV A,TEMPCJNE A,#1,CANSLOWINC ACANSLOW:DEC AMOV TEMP,ARETURN:RETTESTSTOP:SETB SWITCHJNB SWITCH,GOSJMP ENNDGO:CALL DELAYJNB SWITCH,YESSTOPSJMP ENNDYESSTOP:CPL MARKENND:RET;***********************定时器设置******************* TIMER:MOV TMOD,#10H ;T1工作于定时方式1CALL TIMERSETSETB TR1SETB EASETB ET1 ;启动定时器工作WAIT:JBC TF1,HERESJMP WAIT ;定时未到继续等待HERE:DJNZ CYCLENUM,TIMER ;循环次数未满继续定时MOV A,TEMPMOV DPTR,#TAB3MOVC A,@A+DPTRMOV CYCLENUM,ARETTIMERSET:MOV A,TEMPMOV DPTR,#TAB1 ;获取定时器高位MOVC A,@A+DPTRMOV TH1,A ;存放至定时器高位MOV A,TEMPMOV DPTR,#TAB2MOVC A,@A+DPTR ;获取定时器定位MOV TL1,A ;存放至定时器低位RET;***********************50ms延时**********************DELAY:MOV R0,#100DL1:MOV R1,#10DJNZ R1,$DJNZ R0,DL1RET;************显示子程序****************************DISPLAY:CLR P2.7CLR P2.6CLR P2.5SETB P2.4 ;关闭高三位,保留个位MOV P0,LEDBUFRETTAB1: DB 15H,0AH,07H,05H,04H,03H,03H,02H,02H ;定时器高位TH1TAB2: DB 0B3H,0D9H,3BH,6CH,57H,0A5H,19H,0B6H,69H ;定时器地位TL1 TAB3: DB 01H,01H,01H,01H,01H,01H,01H,01H,01H ;循环次数CYCLENUM TAB4: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;数码显示0~9。

51单片机控制四相步进电机

51单片机控制四相步进电机(上)我们研究组有一个纳米项目,现在要测量单根纳米线pn结,我们的方案是类似于原子力显微镜(AFM)一样,把电极探针放在一个微位移控制器上,粗逼近利用步进电机实现,细逼近利用压电陶瓷管实现。

虽然这样的控制器已经可以商品化了,但是我们想自己尝试做一个。

在网上看了些资料,感觉也不是很难,只要想做,花些时间应该可以实现。

先转一篇网上的文章,以后随时更新进展。

51单片机控制四相步进电机作者:易劲松QQ:371719025 Email:yijingsong@接触单片机快两年了,不过只是非常业余的兴趣,实践却不多,到现在还算是个初学者吧。

这几天给自己的任务就是搞定步进电机的单片机控制。

以前曾看过有关步进电机原理和控制的资料,毕竟自己没有做过,对其具体原理还不是很清楚。

今天从淘宝网买了一个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单片机控制步进电机

设计方案与原理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单片机的步进电机小车的控制程序

void timer1_init(); //定时器1初始化函数
voidmove_left(uintspeed_l,ucharcw,ucharen);//左电机运动函数
voidmove_right(uintspeed_r,ucharcw,ucharen);//右电机运动函数
void delay(unsignedintk);//延时函数
speed=speed_l;
if(cw==1)
{
cw_left=1;
}
else
{
cw_left=0;
}
if(en==1)
{
en_left=1;
}
else
{
en_left=0;
}
}
voidmove_right(uintspeed_r,ucharcw,ucharen)
{//speed_r速度控制变量cw方向控制变量en使能控制变量
speed=speed_r;//speed数值与速度成反比请结合实际情况进行调节,
if(cw==1)//但速度不能无限加快因为步进电机有速度上限
{//而且速度加快是力矩会下降,容易导致丢步现象
cw_right=1;//所以实际应用当中应调节到速度可力矩比较合适的数值
}//应考虑到电池电压,轮胎直径等因素
{
move_left(15,0,1);
move_right(15,0,1);
delay(800);
}
if(ir_left==0&&ir_mid==0&&ir_right==1)
{
move_left(15,0,1);
move_right(15,0,1);
delay(400);
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include <>
static unsigned int count; //计数
static int step_index; //步进索引数,值为0-7
static bit turn; //步进电机转动方向
static bit stop_flag; //步进电机停止标志
static int speedlevel; //步进电机转速参数,数值越大速度越慢,最小值为1,速度最快
static int spcount; //步进电机转速参数计数
void delay(unsigned int endcount); //延时函数,延时为endcount*毫秒
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位模式1
ET0 = 1; //定时器0中断允许
TL0 = 0x0C; //设定时每隔中断一次 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; //设定时每隔中断一次
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_2 = 0;
P1_3 = 0;
return;
}
switch(step_index) {
case 0: //0
P1_0 = 1;
P1_1 = 0;
P1_2 = 0;
P1_3 = 0;
break;
case 1: //0、1
P1_0 = 1;
P1_1 = 1;
P1_2 = 0;
P1_3 = 0;
break;
case 2: //1
P1_0 = 0;
P1_1 = 1;
P1_2 = 0;
P1_3 = 0;
break;
case 3: //1、2
P1_0 = 0;
P1_1 = 1;
P1_2 = 1;
P1_3 = 0;
break;
case 4: //2
P1_0 = 0;
P1_1 = 0;
P1_2 = 1;
P1_3 = 0;
break;
case 5: //2、3
P1_0 = 0;
P1_1 = 0;
P1_2 = 1;
P1_3 = 1;
break;
case 6: //3
P1_1 = 0;
P1_2 = 0;
P1_3 = 1;
break;
case 7: //3、0
P1_0 = 1;
P1_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; }
}。

相关文档
最新文档