步进电机控制程序 (2008-06-05 19:07:55) 转载
标签: 分类: 程序设计 it
步进电机(键盘控制可调速) #include  #define uchar unsigned char 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 ddelay(void);     //键盘扫描延时函数 void delay(unsigned int endcount);  //延时函数,延时为endcount*1毫秒 void gorun();          //步进电机控制步进函数  sbit P10=P2^0 ;  //电机端口定义  sbit P11=P2^1 ;  sbit P12=P2^2;  sbit P13=P2^3 ; void ddelay(void) { uchar i; for (i=300;i>0;i--); } uchar keyscan(void) { uchar scancode;  uchar tmpcode; P1 = 0xf8;         // 发全0行扫描码  if ((P1&0xf8)!=0xf8)     // 若有键按下  { ddelay();       // 延时去抖动 if ((P1&0xf8)!=0xf8)    // 延时后再判断一次,去除抖动影响   { scancode = 0xfe; while((scancode&0x08)!=0)  // 逐行扫描    { P1 = scancode;    // 输出行扫描码 if ((P1&0xf8)!=0xf8)  // 本行有键按下 { tmpcode = (P1&0xf8)|0x07; return((~scancode)+(~tmpcode)); // 返回特征字节码,为1的位即对应于行和列     } else scancode = (scancode<<1)|0x01;  // 行扫描码左移一位    }   }  } return(0);        // 无键按下,返回值为0   } void main(void) { uchar key;   count = 0; step_index = 0;   spcount = 0;    P10 = 0;   P11 = 0;   P12 = 0;   P13 = 0; EA = 1;             //允许CPU中断 TMOD = 0x11; //设定时器0和1为16位模式1   ET0 = 1;           //定时器0中断允许   TH0 = 0xFc; TL0 = 0x18;   //设定时每隔1ms中断一次   TR0 = 1;         //开始计数   stop_flag = 0;   turn=0; speedlevel = 20;     while(1)  { key = keyscan();    switch(key)    { case 0x09:   //按键#,正转以speedlevel = 1的速度转1000*0.5MS=0.5S   stop_flag=0;      turn = 0; speedlevel =10;          gorun();    delay(1000);   break; case 0x0c:   //按键*, 停止 2000*0.5MS=0.5S      stop_flag=1;   break; case 0x0a:    //按键0, 反转以speedlevel = 1的速度转1000*0.5MS=0.5S   stop_flag=0;      turn=1; speedlevel =10;   gorun(); delay(1000);   break; case 0x11:     // 按键9, 以--speedlevel的加速转1000*0.5MS=0.5S   stop_flag=0; if (speedlevel==1)        { speedlevel=1;}   else { --speedlevel;}   gorun();   delay(1000);   break; case 0x12:  // 按键8,以++speedlevel的减速转1000*0.5MS=0.5S   stop_flag=0;   ++speedlevel;   gorun(); delay(1000);   break;        }  }  } //定时器0中断处理 void timeint(void) interrupt 1 { TH0=0xFc; TL0=0x18; //设定时每隔1ms中断一次   count++;   spcount--; if(spcount<=0) //速度调整,SPEEDLEVEL越大,延时越长(延时约为1MS*SPEEDLEVEL),   {     // 频率越小,速度越慢    spcount = speedlevel;         gorun();   } } void delay(unsigned int endcount)//延时函数,延时为endcount*0.5毫秒  { count=0;   do{} while(count void gorun() { if (stop_flag==1)   { P10 = 0;     P11 = 0;     P12 = 0;     P13 = 0;     return;   } switch(step_index)   { case 0: //0     P10 = 1;     P11 = 0;     P12 = 0;     P13 = 0;     break; case 1: //0、1     P10 = 1;     P11 = 1;     P12 = 0;     P13 = 0;     break;   case 2: //1     P10 = 0;     P11 = 1;     P12 = 0;     P13 = 0;     break; case 3: //1、2     P10 = 0;     P11 = 1;     P12 = 1;     P13 = 0;     break;   case 4:  //2     P10 = 0;     P11 = 0;     P12 = 1;     P13 = 0;     break; case 5: //2、3 P10 = 0;     P11 = 0;     P12 = 1;     P13 = 1;     break;   case 6: //3     P10 = 0;     P11 = 0;     P12 = 0;     P13 = 1;     break; case 7: //3、0     P10 = 1;     P11 = 0;     P12 = 0;     P13 = 1;   } if (turn==0)    //正转  { step_index++;     if (step_index>7)       step_index=0;  }   else {       //反转     step_index--;     if (step_index<0)       step_index=7;  }     } 步进电机(键盘控制可调速加显示) #include  #define uchar unsigned char 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 ddelay(void);     //键盘扫描延时函数 void delay(unsigned int endcount);  //延时函数,延时为endcount*1毫秒 void gorun();          //步进电机控制步进函数 void Delay400Ms(void); void LCMInit(void); //LCM初始化 void WriteCommandLCM(unsigned char WCLCM,BuysC); //BuysC为0时忽略忙检测 void DisplayOneChar(uchar X, uchar Y, uchar DData); void DisplayListChar(uchar X, uchar Y,uchar ListLength, uchar  *DData,uchar n);  sbit P10=P3^0 ;  //电机端口定义  sbit P11=P3^1 ;  sbit P12=P3^2;  sbit P13=P3^3 ; uchar code speed[]={ 0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30};  uchar code stop[] = {\"stop\ uchar code go[] = {\"go:\ uchar code back[] = {\"back:\ uchar code max[] = {\"max:8\ void ddelay(void) { uchar i; for (i=300;i>0;i--); } uchar keyscan(void) { uchar scancode;  uchar tmpcode; P1 = 0xf8;         // 发全0行扫描码  if ((P1&0xf8)!=0xf8)     // 若有键按下  { ddelay();       // 延时去抖动 if ((P1&0xf8)!=0xf8)    // 延时后再判断一次,去除抖动影响   { scancode = 0xfe; while((scancode&0x08)!=0)  // 逐行扫描    { P1 = scancode;    // 输出行扫描码 if ((P1&0xf8)!=0xf8)  // 本行有键按下     { tmpcode = (P1&0xf8)|0x07; return((~scancode)+(~tmpcode)); // 返回特征字节码,为1的位即对应于行和列     } else scancode = (scancode<<1)|0x01;  // 行扫描码左移一位    } }  } return(0);        // 无键按下,返回值为0   } void main(void) { uchar key;   count = 0; step_index = 0;   spcount = 0;    P10 = 0;   P11 = 0;   P12 = 0;   P13 = 0; EA = 1;             //允许CPU中断 TMOD = 0x11; //设定时器0和1为16位模式1   ET0 = 1;           //定时器0中断允许   TH0 = 0xFc; TL0 = 0x18;   //设定时每隔1ms中断一次   TR0 = 1;         //开始计数   P0=0XFF; P3 &=0XEF;  //573片选   LCMInit(); //LCM初始化   Delay400Ms();   stop_flag = 0;   turn=0; speedlevel = 5; DisplayListChar(0,0,3,go,1); //每次扫描键盘显示更新一次uchar code go[]  DisplayOneChar(0,1,0x35); //每次扫描键盘显示更新一次     while(1)  { key = keyscan();    switch(key)    { case 0x09:   //按键#,正转以speedlevel = 1的速度转1000*0.5MS=0.5S   stop_flag=0;      turn = 0; speedlevel =5;          gorun(); WriteCommandLCM(0x01,1);//显示清屏, DisplayListChar(0,0,3,go,0); //每次扫描键盘显示更新一次uchar code go[]   DisplayOneChar(0,1,0x35); //每次扫描键盘显示更新一次    delay(1000);   break; case 0x0c:   //按键*, 停止 2000*0.5MS=0.5S      stop_flag=1; WriteCommandLCM(0x01,1);//显示清屏, DisplayListChar(0,0,4,stop,0); //每次扫描键盘显示更新一次   break; case 0x0a:    //按键0, 反转以speedlevel = 1的速度转1000*0.5MS=0.5S   stop_flag=0;      turn=1; speedlevel =5;   gorun(); WriteCommandLCM(0x01,1);//显示清屏, DisplayListChar(0,0,5,back,0); //每次扫描键盘显示更新一次   DisplayOneChar(0,1,0x35); //每次扫描键盘显示更新一次         delay(1000);   break; case 0x11:     // 按键9, 以--speedlevel的加速转1000*0.5MS=0.5S   stop_flag=0; if (speedlevel==2)        { speedlevel=2;}   else { speedlevel--;}   gorun(); if(speedlevel==2) { DisplayListChar(0,1,5,max,0);} else {DisplayOneChar(0,1, speed[speedlevel]);} //每次扫描键盘显示更新一次   delay(1000);   break; case 0x12:  // 按键8,以++speedlevel的减速转1000*0.5MS=0.5S   stop_flag=0;   speedlevel++;   gorun(); WriteCommandLCM(0x01,1);//显示清屏,   if(turn==0) {DisplayListChar(0,0,3,go,0); //每次扫描键盘显示更新一次uchar code go[]   DisplayOneChar(0,1, speed[speedlevel]);} //每次扫描键盘显示更新一次   else {DisplayListChar(0,0,5,back,0); //每次扫描键盘显示更新一次 DisplayOneChar(0,1,speed[speedlevel]);} //每次扫描键盘显示更新一次      delay(1000);   break;        }  }  } //定时器0中断处理 void timeint(void) interrupt 1 { TH0=0xFc; TL0=0x18; //设定时每隔1ms中断一次   count++;   spcount--; if(spcount<=0) //速度调整,SPEEDLEVEL越大,延时越长(延时约为1MS*SPEEDLEVEL),   {     // 频率越小,速度越慢    spcount = speedlevel;         gorun();   } } void delay(unsigned int endcount)//延时函数,延时为endcount*0.5毫秒  { count=0;   do{} while(count if (stop_flag==1)   { P10 = 0;     P11 = 0;     P12 = 0;     P13 = 0;     return;   } switch(step_index)   { case 0: //0     P10 = 1;     P11 = 0;     P12 = 0;     P13 = 0;     break; case 1: //0、1     P10 = 1;     P11 = 1;     P12 = 0;     P13 = 0;     break;   case 2: //1     P10 = 0; P11 = 1;     P12 = 0;     P13 = 0;     break; case 3: //1、2     P10 = 0;     P11 = 1;     P12 = 1;     P13 = 0;     break;   case 4:  //2     P10 = 0;     P11 = 0;     P12 = 1;     P13 = 0;     break; case 5: //2、3     P10 = 0;     P11 = 0;     P12 = 1;     P13 = 1;     break;   case 6: //3     P10 = 0;     P11 = 0;     P12 = 0;     P13 = 1;     break; case 7: //3、0     P10 = 1;     P11 = 0;     P12 = 0;     P13 = 1;   } if (turn==0)    //正转  { step_index++;     if (step_index>7)       step_index=0;  }   else {       //反转     step_index--;     if (step_index<0) step_index=7;  }     } 步进电机(自动循环调速) #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*0.5毫秒 void gorun();          //步进电机控制步进函数 void main(void) { count = 0; step_index = 0;   spcount = 0;   stop_flag = 0;   P00 = 0;   P01 = 0;   P02 = 0;   P03 = 0; EA = 1;             //允许CPU中断 TMOD = 0x11; //设定时器0和1为16位模式1   ET0 = 1;           //定时器0中断允许   TH0 = 0xFE; TL0 = 0x0C;   //设定时每隔0.5ms中断一次   TR0 = 1;         //开始计数   turn = 0;     do{ speedlevel =4; delay(10000);  //以speedlevel = 4的速度转2000*0.5MS=1S  speedlevel =4; delay(10000);  //以speedlevel = 4的速度转2000*0.5MS=1S     stop_flag=1; delay(6000);//停止,2000*0.5MS=3S     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 if (stop_flag==1)   { P00 = 0;     P01 = 0;     P02 = 0;     P03 = 0;     return;   } switch(step_index)   { case 0: //0     P00 = 1;     P01 = 0;     P02 = 0;     P03 = 0;     break; case 1: //0、1     P00 = 1;     P01 = 1;     P02 = 0; P03 = 0;     break;   case 2: //1     P00 = 0;     P01 = 1;     P02 = 0;     P03 = 0;     break; case 3: //1、2     P00 = 0;     P01 = 1;     P02 = 1;     P03 = 0;     break;   case 4:  //2     P00 = 0;     P01 = 0;     P02 = 1;     P03 = 0;     break; case 5: //2、3     P00 = 0;     P01 = 0;     P02 = 1;     P03 = 1;     break;   case 6: //3     P00 = 0;     P01 = 0;     P02 = 0;     P03 = 1;     break; case 7: //3、0     P00 = 1;     P01 = 0;     P02 = 0;     P03 = 1;   } if (turn==0)   { step_index++;     if (step_index>7)       step_index=0;   } else   { step_index--;     if (step_index<0)       step_index=7;   }     } 步进电机控制 Link - Thu, 17 Jan 2008 12:41:32 +0800 Description: 本设计采用的步进电机为35BYJ46型四相八拍电机,电压为DC12V。 工作原理:利用INTER 8255A对四相步进电机进行控制。当对步进电机施加一系列连续不断的控制脉冲时,它可以连续不断地转动。每一个脉冲信号对应步进电机的某一相或两相绕组的通电状态改变一次,也就对应转子转过一定的角度(一个步距角)。当通电状态的改变完成一个循环时,转子转过一个齿距。四相步进电机可以在不同的通电方式下运行,常见的通电方式有单(单相绕组通电)四拍(A-B-C-D-A。。。),双(双相绕组通电)四拍(AB-BC-CD-DA-AB-。。。),八拍(A-AB-B-BC-C-CD-D-DA-A。。。)等。 35BYJ46步进电机为四相八拍,其相序表如下: 步序 PA3 PA2 PA1 PA0 对应A口输出值           1 0 0 0 1 01H           2 0 0 1 1 03H           3 0 0 1 0 02H           4 0 1 1 0 06H           5 0 1 0 0 04H           6 1 1 0 0 0CH           7 1 0 0 0 08H           8 1 0 0 1 09H 实验程序如下: ;FILENAME: 步进电机控制.ASM ;内容: 步进电机控制 STACK   SEGMENT  STACK         DW      256 DUP(?) STACK   ENDS P55A      EQU     60H           ;8255A口输出 P55C      EQU    62H       ;8255C口输入 P55CTL    EQU   63H       ;8255控制口 DATA     SEGMENT BUF       DB      0 MES       DB      'K0-K6 ARE SPEED CONTROL', 0DH, 0AH DB       'K6 IS THE LOWEST SPEED', 0DH, 0AH           DB      'K0 IS THE HIGHEST SPEED', 0DH, 0AH DB      'K7 IS THE DIRECTION CONTROL', 0DH, 0AH, '$' TABLE     DB        01H,03H,02H,06H,04H,0CH,08H,09H TABLE1    DB        01H,09H,08H,0CH,04H,06H,02H,03H DATA      ENDS CODE      SEGMENT ASSUME   CS:CODE, DS:DATA START:    MOV     AX, CS                     MOV     DS, AX           MOV     AX, DATA           MOV     DS, AX MOV     DX, OFFSET MES MOV     AH, 09            ; dos调用,在显示器上显示以$为结                                       束符的字符串, INT     21H               ; 若显示字符串要求回车换行则在其                                       后加入0dh,0ah。         MOV     DX, P55CTL MOV     AL, 8BH           ;10001011B OUT     DX, AL            ;8255C输入,  A输出         MOV     BUF, 33H OUT1:      MOV     AL, BUF         MOV     DX, P55A OUT     DX, AL             ;从A口输出00110011         PUSH    DX MOV     AH, 06H MOV     DL, 0FFH            ;DOS调用,直接控制台读写,DL=0FF                                        输入,DL=字符  输出;           INT     21H               ;检查有无键按下         POP     DX JE      IN1                  ;ZF=1,则跳转 MOV     AH, 4CH              ;带返回码结束,AL=返回码           INT     21H IN1:     MOV       DX, P55C IN        AL,DX          ;读开关状态,则跳转至相应开关处         TEST      AL, 01H         JNZ       K0 TEST      AL, 02H         JNZ       K1 TEST      AL, 04H           JNZ       K2         TEST      AL, 08H         JNZ       K3 TEST      AL, 10H JNZ       K4 TEST      AL, 20H         JNZ       K5 TEST      AL, 40H           JNZ       K6 STOP:     MOV       DX, P55A         MOV       AL, 0FFH          JMP       OUT1 K0:      MOV      BL, 10H SAM:      TEST     AL, 80H       ;K7是否为1,是则步进电机正转,否则反转           JZ       ZX0           JMP      NX0 K1:       MOV      BL, 18H           JMP      SAM K2:       MOV      BL, 20H           JMP      SAM K3:       MOV      BL, 40H           JMP      SAM K4:       MOV      BL, 80H           JMP      SAM K5:       MOV      BL, 0C0H           JMP      SAM K6:       MOV      BL, 0FFH           JMP      SAM ZX0: MOV      BX,OFFSET TABLE           MOV      CX,0008H ZX1:      MOV      AL,[BX]         OUT      61H,AL         CALL     DELAY         INC      BX         LOOP     ZX1 JMP      OUT1 NX0: MOV      BX,OFFSET TABLE1         MOV      CX,0008H NX1:    MOV      AL,[BX]         OUT      61H,AL         CALL     DELAY         INC      BX         LOOP     NX1 JMP      OUT1 DELAY   PROC     NEAR                    ;延时子程序 DELAY1: MOV      CX, 05A4H DELAY2: LOOP     DELAY2         DEC      BL JNZ      DELAY1 RET DELAY    ENDP CODE     ENDS END      START              
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- 91gzw.com 版权所有 湘ICP备2023023988号-2
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务