关于51控制 4线 5线 和6线和三线步进电机的问题

2020-02-02 09:37发布

本帖最后由 金砂紫钰 于 2012-10-27 14:20 编辑

#include "reg51.h"       //包含头文件

sbit S_A=P2^0;           //定义步进电机A相
sbit S_B=P2^1;           //定义步进电机B相
sbit S_C=P2^2;           //定义步进电机C相
sbit S_D=P2^3;           //定义步进电机D相

sbit P24=P2^4;           //定义步进3线电机A相
sbit P25=P2^5;           //定义步进3线电机B相

sbit S17=P3^7;           //正传
sbit S18=P3^6;           //定义S18控制IO,电机转速减小
sbit S19=P3^5;           //启动/暂停
sbit S20=P3^4;           //定义S20控制IO,电机转速加大
sbit S21=P3^3;           //反转

sbit LE1=P2^6;           //位选573锁存器使能
sbit LE2=P2^7;           //段选573锁存器使能

bit zf,stop;

#define uchar unsigned char
#define uint  unsigned int

uint  speed;             //电机转速

uchar keyValue;          //定义键盘扫描结果参数
uchar temp;
uchar code dis[16]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
                   //  0    1    2    3    4    5    6    7   
                     0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};//0~F的段码
                   //  8    9    A    B    C    D    E    F  

//**************************************************************************************************
//延时函数
//**************************************************************************************************
delay(uint time)         //int型数据为16位,所以最大值为65535            
{
  uint  i,j;             //定义变量i,j,用于循环语句
  for(i=0;i<time;i++)    //for循环,循环50*time次
     for(j=0;j<50;j++);  //for循环,循环50次
}

//**************************************************************************************************
//数码管显示函数
//**************************************************************************************************
smg_show(uchar n)
{
      //显示个位
     P1=0xbf;                 //0xbf=1011 1111,即选通个位
     LE1=1;                   //锁存位
     LE1=0;                   //断开锁存,位选573的Q7~Q0仍保持
     P1=dis[n/10];            //dis[n/10]为0~9的编码
     LE2=1;                   //锁存段码
     LE2=0;                   //断开锁存,段选573的Q7~Q0仍保持
     delay(10);              //延时保持一下,延时过大会闪动,延时过小会有重影   

     P1=0x00;LE2=1;LE2=0;     //清除P1口数据,以免造重影
     //显示十分位
     P1=0x7f;                 //0xbf=0111 1111,即选通十分位
     LE1=1;                   //锁存位
     LE1=0;                   //断开锁存,位选573的Q7~Q0仍保持
     P1=dis[n%10];            //0~9的编码
     LE2=1;                   //锁存段码
     LE2=0;                   //断开锁存,段选573的Q7~Q0仍保持
     delay(10);              //延时保持一下,延时过大会闪动,延时过小会有重影  

     P1=0x00;LE2=1;LE2=0;     //清除P1口数据,以免造重影   
         
}
//**************************************************************************************************
//1*5按键扫描函数
//**************************************************************************************************
keyScan()                             
{
   P3=P3|0xf8;                //P3高5位置1,设置为输入
   if((P3&0xf8)!=0xf8)        //判断是否有按键按下
    {
     delay(20);               //延时肖抖
     if((P3&0xf8)!=0xf8)      //再次判断是否有按键按下
       keyValue=(P3&0xf8);    //读取扫描结果
       while((P3&0xf8)!=0xf8);
    }
}
//**************************************************************************************************
//1*5按键扫描结果处理函数
//**************************************************************************************************
keyHandle()                     
{      
        switch(keyValue)         
          {
            case 0x78:               //如果S17按键按下  
                                {
                 zf=1;               //正反标志置1,正向
                 break;         
                }
            case 0xb8:               //如果S18按键按下
                                {
                 if(speed>15)speed--;//减速
                   else speed=30;   
                 break;
                }
            case 0xd8:               //如果S19按键按下
                                {
                 stop=~stop;         //启动/暂停  
                 break;
                }
            case 0xe8:               //如果S20按键按下
                                {                 
                 if(speed<45)speed++;//减速
                   else speed=30;  
                 break;
                }
            case 0xf0:               //如果S21按键按下
                                {
                 zf=0;               //正反标志置0,反向              
                 break;
                }
            default:
                                        break;
          }
}
//**************************************************************************************************
//步进电机控制 (测试好的程序4线和6线共用)
//**************************************************************************************************
/*stepmotor()
{     
     if(stop==0)           //停止标志位为0,执行以下程序,如果为1,不执行以下程序
       {
           if(zf)          //zf,即正反标志为1,正向转动
            {
            // P2=0x01;      //等效于S_D=0,S_C=0,S_B=0,S_A=1
                         P2=0xFE;      //           4
             delay(speed); //延时,修改此参数即可修改电机转速
            // P2=0x03;      //等效于S_D=0,S_C=0,S_B=1,S_A=1
                         P2=0XFC;      //   4
             delay(speed);
            // P2=0x02;      //i等效于S_D=0,S_C=0,S_B=1,S_A=0
             P2=0xFD;            //  4
                         delay(speed);
            // P2=0x06;      //等效于S_D=0,S_C=1,S_B=1,S_A=0
                         P2=0xF9;
             delay(speed);
             //P2=0x04;      //等效于S_D=0,S_C=1,S_B=0,S_A=0
                         P2=0xFB;
             delay(speed);
             //P2=0x0c;      //等效于S_D=1,S_C=1,S_B=0,S_A=0
                         P2=0xF3;
             delay(speed);
            // P2=0x08;      //等效于S_D=1,S_C=0,S_B=0,S_A=0
                         P2=0xF7;
             delay(speed);
            // P2=0x09;      //等效于S_D=1,S_C=0,S_B=0,S_A=1
                         P2=0xF6;
             delay(speed);
            }
           else            //zf,即正反标志为0,反向转动?   
            {
            // P2=0x09;      //等效于S_D=1,S_C=0,S_B=0,S_A=1
                         P2=0xF6;
             delay(speed); //延时,修改此参数即可修改电机转速
            // P2=0x08;      //等效于S_D=1,S_C=0,S_B=0,S_A=0
                         P2=0xF7;
             delay(speed);
            // P2=0x0c;      //等效于S_D=1,S_C=1,S_B=0,S_A=0
                         P2=0xF3;
             delay(speed);  
             //P2=0x04;      //等效于S_D=0,S_C=1,S_B=0,S_A=0
                         P2=0xFB;
             delay(speed);
             //P2=0x06;      //等效于S_D=0,S_C=1,S_B=1,S_A=0
                         P2=0xF9;
             delay(speed);        
             //P2=0x02;      //i等效于S_D=0,S_C=0,S_B=1,S_A=0
                         P2=0xFD;
             delay(speed);
             //P2=0x03;      //等效于S_D=0,S_C=0,S_B=1,S_A=1
                         P2=0xFC;
             delay(speed);      
             //P2=0x01;      //等效于S_D=0,S_C=0,S_B=0,S_A=1
                         P2=0xFE;
             delay(speed);
            }           
       }         
}   */         
//**************************************************************************************************
//三线步进电机控制
//**************************************************************************************************
void stepmotor()intertupt 1 using 1
{
        TMOD=0X01;
        THO=0X3C;
        TLO=0Xb0;
        P2=0x10;
        if(temp>=39)        //         定时2S
        {
                temp=0x00;
                P2=0x00;
           }
}                                   //这段程序老是报错,我这里是要输出一个,4S 一个周期的脉冲
////////////////////////////////////////////////////////////////////////////////////////////
//**************************************************************************************************
//三线步进检测程序
//**************************************************************************************************
/*stepmotor()
{     
     if(stop==0)           //停止标志位为0,执行以下程序,如果为1,不执行以下程序
       {
           if(zf)          //zf,即正反标志为1,正向转动
            {
             P2=0x01;      //等效于S_D=0,S_C=0,S_B=0,S_A=1
             delay(speed); //延时,修改此参数即可修改电机转速
             P2=0x02;      //等效于S_D=0,S_C=0,S_B=1,S_A=1
             delay(speed);
             //P2=0x00;      //i等效于S_D=0,S_C=0,S_B=1,S_A=0
             //delay(speed);
             // P2=0x05;
                         // P2=0x01;
                         // P2=0x00;  

            }
           else            //zf,即正反标志为0,反向转动?   
            {
               
             P2=0x05;      //i等效于S_D=0,S_C=0,S_B=1,S_A=0
            delay(speed);
           
             P2=0x06;      //等效于S_D=0,S_C=0,S_B=0,S_A=1
            delay(speed);
                        // P2=0x09;
                         //P2=0x01;
                        // P2=0x00;  
            }           
       }         
} */



//**************************************************************************************************
//主函数
//**************************************************************************************************
main()
{
                TMOD=0X11;                                 //开二个定时器
                TH0=0X3C;
                TH0=0Xb0;
                TH1=0X3C;
                TH1=0Xb0;
                EA=1;
                ET0=1;
                ET1=1;
                TR0=1;
                TR1=1;

  speed=30;                      //初始化转速
   while(1)                      //死循环,等待定时器中断
     {   keyValue=0;             //初始化键值为0
         keyScan();              //按键扫描
         keyHandle();            //处理扫描结果
         stepmotor();            //电机转动
         smg_show(speed);        //数码管最低两位显示转速,初始化为30,值越大,转速越小
     }
}




请教各位,
void stepmotor()intertupt 1 using 1    //interrupt
{
        TMOD=0X01;
        THO=0X3C;
        TLO=0Xb0;
        P2=0x10;
        if(temp>=39)        //         定时2S
        {
                temp=0x00;
                P2=0x00;
           }
}                                   //这段程序老是报错,我这里是要输出一个,4S 一个周期的脉冲
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。