单片机/MCUwilliam hill官网
直播中

213945

13年用户 29经验值
擅长:可编程逻辑
私信 关注
[文章]

步进电机控制器的设计

单片机设计一个步进电机控制器。要求能对步进电机实现正、反转及速度控制,同时能对步进电机进行位置控制,即能控制步进电机从一个位置精确地运行到另一个位置。步进电机为四相反应式,软件生成脉冲序列,可设置参数和运行状态参数实时显示。技术要求  1. 转速:0—3000r/m,误差1‰;2. 角位移控制:2º—9999º;3. 方向:可逆;4. 可设置参数和运行状态参数实时显示。
下面是我写的一个简单的程序,但是我不知道该怎么修改才能满足题目的要求以及转速和角位移的显示程序,麻烦各位帮我看看,说说你们的想法,现在这谢了啊
#include        //51芯片管脚定义头文件
#include          //内部包含延时函数 _nop_();
#define uchar unsigned char
#define uint  unsigned int
uchar i,j,k;
uchar code zhengcode[8]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09};  //四相八拍正转编码
uchar code fancode[8]={0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01};  ////四相八拍反转编码
***it  K1   = P3^2;       //正转
***it  K2   = P3^3;       //反转
***it  K3   = P3^4;       //停止
void main()
{    TMOD=0X01;
     TH0=0xff;
         TL0=0xf6;        //定时0.01ms
         EA=1;
         ET0=1;
         TR0=1;
         i=0;
         j=0;
         k=100;                 
   if(K1==0)
   {  while(1)
        {           P1=zhengcode[i];
               if(K3==0)
                   {break;}
                           }
                                }
       
         else if(K2==0)
          {  while(1)
               
          {    P1=fancode[j];
             if(K3==0)
                   {break;}
                    }
                                }

   else P1=0xf0;
}
void  intt0() interrupt 1
{          k--;
     TH0=0xff;
         TL1=0xf6;
         if(k==0)
         {  k=100;
          i++;
          j++;}
        if(i==7)
        {i=0;}
        if(j==7)
        {j=0;}

}




            






                     


  • 这是我的这个设计的威廉希尔官方网站
原理图
已退回1积分

回帖(10)

lstcspring

2012-12-9 20:37:02
你现在能控制电机正反转动了吗?我也没有做过,一步一步的做吧,先让电机转起来,再来调速, 精度之类的功能
举报

寇艳斌

2012-12-10 12:31:18
举报

文敏

2013-3-19 13:34:45
不知道你显示部分威廉希尔官方网站 有了没有,是用液晶显示,还是用LED,请先说明一下,对应的外部威廉希尔官方网站 有,才好对应进行编程...
举报

h1654155808.8008

2013-3-20 12:12:14
你的程序还有很多没有完成。
单片机控制步进马达的方向,速度,位移的程序很简单。调速我还没有搞过。
用一个步进马达控制器就可以了。
举报

h1654155808.8008

2013-3-20 12:14:04
用单片机设计一个步进电机控制器。要求能对步进电机实现正、反转及速度控制,同时能对步进电机进行位置控制,这个很简单。

举报

h1654155808.8008

2013-3-20 12:15:27
举报

213945

2013-3-20 14:29:29
这个问题是要能够设定步进电机的转速啊,通过键盘设定。你会编写这个程序吗?
下面是我的完整程序,就是我调节的转速好没有与实际的转速一一对应。你能帮我改写吗?
#include
#include
void delayNOP()
{_nop_();_nop_();_nop_();_nop_();}
#define uchar unsigned char
#define uint  unsigned int
***it  LCD_RS = P2^0;            
***it  LCD_RW = P2^1;
***it  LCD_EN = P2^2;
uchar keycode,scan1,scan2;
uchar chuzhi;
uchar  shedingzhuansu[4]={0x00,0x01,0x00,0x00};        //存储转速
uchar shedingjiaodu[4]={0x03,0x00,0x00,0x00};   //存储角度

uint zhuanguojiaodu=0,number;//计算转过的角度和脉冲计数
uchar code FFW[8]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9};   //反转码
uchar code REV[8]={0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0xf1};   //正传码
uchar   m,v=0,q=0;                                                                                          
uint zhuansu,jiaodu;  //设置的转速和角度
bit zhengrunflag=0,fanrunflag=0,stopflag=0,zhuansushezhiflag=1,jiaodushezhiflag=0,shuzi; //区分控制键和数字键标志
bit  on_off=0;            //运行与停止标志
bit  direction;                   //正反标志
uint   data_temp,data_temP1,data_temp2,data_temp3,data_temp4;  

void delay(uint t)                        //延时函数
{                           
   uchar k;
   while(t--)
   {
     for(k=0; k<125; k++)
     { }
   }
}            



bit lcd_busy() //        检查LCD忙不忙
{                          
    bit result;
    LCD_RS = 0;
    LCD_RW = 1;
    LCD_EN = 1;
    delayNOP();
    result = (bit)(P0&0x80);
    LCD_EN = 0;
    return(result);
}
void lcd_wcmd(uchar cmd)  //        LCD写指令

{                          
   while(lcd_busy());
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_EN = 0;
    _nop_();
    _nop_();
    P0 = cmd;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0;  
}

void lcd_wdat(uchar dat)   //LCD写数据
{                          
   while(lcd_busy());
    LCD_RS = 1;
    LCD_RW = 0;
    LCD_EN = 0;
    P0 = dat;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0;
}                                          
void lcd_clr()                        // LCD清屏
{        lcd_wcmd(0x01);
     delay(5);

}


void lcd_init()                        //        LCD初始化
{
    delay(30);                  
    lcd_wcmd(0x38);      //16*2显示,5*7点阵,8位数据
    delay(5);
    lcd_wcmd(0x38);         
    delay(5);
    lcd_wcmd(0x38);         
    delay(5);

    lcd_wcmd(0x0c);      //显示开,关光标
    delay(5);
    lcd_wcmd(0x06);      //移动光标
    delay(5);
    lcd_wcmd(0x01);      //清除LCD的显示内容
    delay(5);
}

uchar keyscan()//矩阵键盘线反转法扫描程序
{
       
         
uchar i=0;

  P3=0xf0;
  scan1=P3;
  if(scan1!=0xf0)
  {  delay(8);          
    if(scan1!=0xf0)
        { P3=0x0f;
          scan2=P3;
          keycode=(scan1|scan2);
          switch(keycode)
   {  case 0xee:  zhengrunflag=1;shuzi=0;break;
      case 0xde:  fanrunflag=1;shuzi=0;break;
          case 0xbe:  stopflag=1;shuzi=0;break;
          
          
          case 0xed: zhuansushezhiflag=1;shuzi=0;break;
          case 0xdd: jiaodushezhiflag=1;shuzi=0;break;
                     
          case 0xbd: chuzhi=0;shuzi=1;break;
          case 0x7d: chuzhi=1;shuzi=1;break;

          case 0xeb: chuzhi=2; shuzi=1;break;
          case 0xdb: chuzhi=3;shuzi=1;break;
          case 0xbb: chuzhi=4;shuzi=1;break;                                 
          case 0x7b: chuzhi=5;shuzi=1;break;
          case 0xe7: chuzhi=6;shuzi=1;break;
          case 0xd7: chuzhi=7;shuzi=1;break;
          case 0xb7: chuzhi=8;shuzi=1;break;
          case 0x77: chuzhi=9;shuzi=1;break;
         }
         }
           else shuzi=0;

         }
          else shuzi=0;

          return shuzi;

           }

void zhuansutiaojie()         //         转速调节程序
{           uint i, j=0;
                for(i=0;i<4;i++)
            { while(!keyscan())
                    {;}
              shedingzhuansu[j]=chuzhi;
                    
                   lcd_wcmd(j|0x80);
           lcd_wdat(shedingzhuansu[j]+0x30);
                   j++;

                   delay(500);
                  
          }
          zhuansushezhiflag=0;
          zhuansu=shedingzhuansu[0]*1000;
          zhuansu=zhuansu+shedingzhuansu[1]*100;
          zhuansu=zhuansu+shedingzhuansu[2]*10;
          zhuansu=zhuansu+shedingzhuansu[3];//设定的转速



}
void jiaodutiaojie()         //          角度调节
{        uint i,j=0;
   for(i=0;i<4;i++)
  {          
      while(! keyscan());
          {;}
    shedingjiaodu[j]=chuzhi;

      lcd_wcmd((0x40+j)|0x80);
      lcd_wdat(shedingjiaodu[j]+0x30);
          j++;
             delay(500);
          
          }

   jiaodushezhiflag=0;
   jiaodu=shedingjiaodu[0]*1000;
   jiaodu=jiaodu+shedingjiaodu[1]*100;
   jiaodu=jiaodu+shedingjiaodu[2]*10;
   jiaodu=jiaodu+shedingjiaodu[3]; //设置的角度

}



void  data_conv()                   // 数据转化函数
{
     data_temP1=data_temp/1000;      
     data_temP1=data_temP1+0x30;

         data_temp2=data_temp%1000/100;      
     data_temp2=data_temp2+0x30;
         
         data_temp3=data_temp%1000%100/10;
         data_temp3=data_temp3+0x30;

         data_temp4=data_temp%10;
         data_temp4=data_temp4+0x30;

}
void  data_dis()                          //步进电机显示函数
{          data_temp = zhuanguojiaodu;        //显示转过角度
       data_conv();
       lcd_wcmd(0x48|0x80);
       lcd_wdat(data_temP1);
       lcd_wcmd(0x49|0x80);
       lcd_wdat(data_temp2);
       lcd_wcmd(0x4a|0x80);
       lcd_wdat(data_temp3);
           lcd_wcmd(0x4b|0x80);
       lcd_wdat(data_temp4);


}
void  motor_DR()
{
          if(direction==1)
          {lcd_wcmd(0x47|0x80);       
            lcd_wdat(0x2b);
          }
          else
          {        lcd_wcmd(0x47|0x80);       
            lcd_wdat(0x2d);

          }

}

void  motor_RUN()           // 步进电机运转子程序
{
          if(on_off==1)
            { TR0=1;
               
                  motor_DR();
               
                 }

          else  
    { TR0=0; P1 =0x0f; }

}



void main()                        //主程序
{
   delay(10);
   lcd_init();
   lcd_clr();

lcd_wcmd(0x00|0x80);
lcd_wdat(shedingzhuansu[0]+0x30);

lcd_wdat(shedingzhuansu[1]+0x30);

lcd_wdat(shedingzhuansu[2]+0x30);

lcd_wdat(shedingzhuansu[3]+0x30);

lcd_wcmd(0x40|0x80);
lcd_wdat(shedingjiaodu[0]+0x30);  
lcd_wdat(shedingjiaodu[1]+0x30);
lcd_wdat(shedingjiaodu[2]+0x30);
lcd_wdat(shedingjiaodu[3]+0x30);
   TMOD = 0x01;       //T0定时方式1
   TL0  = 0x9c;                  //定时时间为0.1ms
   TH0  = 0xff;
   EA   = 1;
   ET0  = 1;
   P1   = 0x0f;

while(1)
{        keyscan();
    if(zhuansushezhiflag==1)                 //         开始调节速度
          {    zhuansutiaojie();}
                                                     
   if(jiaodushezhiflag==1)                 //开始调节角度
         {
                jiaodutiaojie();}

        if(zhengrunflag==1)                        //正转键
        {   zhuanguojiaodu=0;
                   number=0;
           on_off=1;
           direction=1;      
         motor_RUN();
                zhengrunflag=0;
                 }

        if(fanrunflag==1)                        // 反转键
        {   zhuanguojiaodu=0;
                number=0;
           on_off=1;
           direction=0;      
         motor_RUN();
                fanrunflag=0;
                 }

      if(stopflag==1)    // 停止键
      {          
              on_off=0;
                 motor_RUN();
                 stopflag=0;
          }
                               
        if(zhuanguojiaodu==jiaodu) //判断是否达到了设置角度
         {           zhuanguojiaodu=0;
                   P1=0x0f;
                   on_off=0;
                   motor_RUN();

         }
    data_dis();           //显示函数

}

}

void  motor_onoff()  interrupt  1            //定时器0中断服务程序
{     
       TL0  = 0x9c;
       TH0  = 0xff;
       q++;
    if(q         { return; }
    else
       {  q=0;   
          number++;               //脉冲计数     
        zhuanguojiaodu=number*2;     //转过角度         
               
                     
       if(direction==1)            //方向标志
       { if(v<8)  
         {P1 = FFW[v];v++;
                 }       //取数据,正转
        if(v==8)
        { v=0; }
          }

      else
       { if(v<8)  
         {P1 = REV[v];v++;
                                     
                 
                 }       //取数据,反转
         if(v==8)
         { v=0; }
          }
              //电机转动角度


    }
}







举报

tuteng_2011

2013-3-26 16:51:55
举报

空靈靈

2014-4-12 17:43:59
这么好的东西
举报

夏里巴人

2018-1-13 20:47:51
谢谢
举报

更多回帖

发帖
×
20
完善资料,
赚取积分