专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

单片机控制步进电机程序+视频

作者:huqin   来源:本站原创   点击数:  更新时间:2014年04月08日   【字体:
完善二
 
 

源程序:
 


/*-----------------------------------------------------------------------------
 工作板源程序
-----------------------------------------------------------------------------*/  

#include <REG52.H> //各个特殊功能寄存器地址定义
#include <intrins.h>

 

/*-----------------------------------------------------------------------------
  用于串行输入SPI的数据接收口
-----------------------------------------------------------------------------*/  
volatile  unsigned int  data zd0; //功能1的时候调整蜂鸣器时间
volatile  unsigned char data SPI_DH,SPI_DL;//串行口高位和低位高位用于识别功能指令和地址指令,低位用于数据传输 
volatile  unsigned char data  SPI_ZL,SPI_DZ,SPI_SJ;
volatileunsigned   int data  m,z;
 /*-----------------------------------------------------------------------------
 三变量用于默认的速度,宽度,高度。
-----------------------------------------------------------------------------*/ 
volatile  unsigned char data b=100;    //单位是rpm/min
volatile unsigned char data  BBZ;
 volatile  unsigned char data c=1;          //       宽度单位是毫米
volatile unsigned char data  CBZ;
 volatile  unsigned char data d=4;              //         高度单位是毫米
volatile unsigned char data  DBZ;
 /*-----------------------------------------------------------------------------
 三变量用于速度,宽度,高度的翻译中间变量
-----------------------------------------------------------------------------*/ 
 unsigned char data  e;//  用于速度
 unsigned char data  f; //用于宽度
 unsigned  char data g;//用高度
 
 
 
/*-------------------------------------------------------------
P0引脚定义: P0口有5种定义,每种定义根据P2口给定功能不同而不同。
每种功能不能同时实现,否则会出现混乱。

-------------------------------------------------------------*/
  
sbitCLK1=P0^0;       //步进电机1脉冲
sbit CW1    =P0^1; //步进电机1方向
sbitEW1=P0^2; //步进电机1使能
sbitCLK2    =P0^3; //步进电机2脉冲
sbitCW2    =P0^4;      //步进电机2方向
sbitEW2    =P0^5;      //步进电机2使能
sbitEN1    =P0^6;      //角度电机使能
sbitIN1    =P0^7;    //角度电机脉冲

 /*-------------------------------------------------------------
P1引脚定义 :P1口为限位检测口。

-------------------------------------------------------------*/
sbit LED_SD    =P1^0;

sbit    LED_KD    =P1^2;
sbit    LED_GD=P1^3;
sbit    LED_YX=P1^4;
sbit    LED_FW=P1^5;
sbit    CLK        =P1^6;      //角度限位右  。当高电平表示有限位
sbitDATAS    =P1^7;      //角度电机输入2

 /*-------------------------------------------------------------
 P2引脚定义 :
-------------------------------------------------------------*/
sbit    VSW     = P2^0;
 sbit    FXXWZ   = P2^1;
sbitFXXWY=P2^2;  //  驱动控制,=0该为Q=D.=1时为高阻态。
sbitZXWX=P2^3;  //键盘控制,该位=0时为跟随变化Q=D,=1时为高阻态。
sbitZXWS=P2^4; //指示灯LED控制该位=0时为保持,=1时为数据Q=D
sbit    XXWZ=P2^5; //数码管个位控制该位=0时为保持,=1时为数据Q=D
    
sbit XXWY=P2^6; //数码管十位控制该位=0时为保持,=1时为数据Q=D 


sbitIN2    =P2^7;  //角度电机脉冲
 
 


 /*-------------------------------------------------------------
  P3引脚定义:P3口为主轴电机调速端口和
  主轴编码方向编码,还有键盘中断。
-------------------------------------------------------------*/

sbit    STB_IO  =P3^2 ;
sbit    JT      =P3^3 ;
sbitZZZD=P3^4;
sbitFXMC=P3^5;
sbitPOWSW=P3^7;

 

 
/*-----------------------------------------------------------------------------
函数功能 : MS 毫秒 延迟函数
-----------------------------------------------------------------------------*/
void Delay(unsigned int i)
{
unsigned int j;
for(i;i>0;i--)
{
for(j=0;j<125;j++)
{;}
}
}


 unsigned char code table[]=
{
  0x3f,0x06,0x5b,0x4f,0x66,
  0x6d,0x7d,0x07,0x7f,0x6f,
  0x77,0x7c,0x39,0x5e,0x79,
  0x71,0x00,0x40,0x00
};
 

 

/*-----------------------------------------------------------------------------
函数功能 : us 微秒 延迟函数
-----------------------------------------------------------------------------*/
void MyDelay(unsigned int time)
{
while(time--)
{
_nop_();
}
}

/*-----------------------------------------------------------------------------
函数功能 : us 微秒 精确US延迟 12MHZ延迟6us
-----------------------------------------------------------------------------*/
   void MyDelay2()
                 {
         _nop_();
                 }
 

 


  /*-----------------------------------------------------------------------------

函数功能 :X轴电机驱动脉冲

-----------------------------------------------------------------------------*/
  void XZDJQD()
   {
  CLK1=0;
  MyDelay2();
  CLK1=1;
       Delay(1);
  
}

   /*-----------------------------------------------------------------------------
函数功能 :Z轴电机驱动脉冲

-----------------------------------------------------------------------------*/
   void ZZDJQD()
   {
  CLK2=0;
  MyDelay2();
  CLK2=1;
  Delay(1);
  
}
  /*-----------------------------------------------------------------------------
函数功能 :机构复位程序 复位x轴z轴以及角度轴。
-----------------------------------------------------------------------------*/
  void jgfw ( )
  {
 
unsigned int g=0; //中点计数中间变量
EX0=0;//关闭键盘中断等待复位完成。
EW1=0; 
CW1=1; 
while(XXWZ==0)
     {   
      CW1=1;
      XZDJQD(); 
     }
CW1=0; 
while (XXWY==0)
      {
       CW1=0;
   XZDJQD();
    g=g+1;
      }
g=g/2;
CW1=1;
while (g>0)
      {
  CW1=1;
  XZDJQD();
      g=g-1;
      }
P2=0XF0;
EX0=1;
 }


  /*-----------------------------------------------------------------------------
函数功能 :运行状态中X轴和Z轴角度轴的控制。
-----------------------------------------------------------------------------*/
  void YXQD ( )
  { 
 f=c*20; 
 while(f>0)
      { 
     XZDJQD();
   f=f-1;
   if(XXWZ==1)CW1=0;
   if(XXWY==1)CW1=1;
   if(XXWZ==1||XXWY==1)
     {
  g=d*5;
  while(g>0)
       {
       ZZDJQD();
       g=g-1;
       }

      }


       }

 
 
 }

 

 
  
 
 
   /*-----------------------------------------------------------------------------
函数功能 :运行状态电机参数送出(串行方式)

-----------------------------------------------------------------------------*/

 void Control(unsigned char cmd)
{
unsigned char i;
STB_IO = 0;//拉低片选
Delay(20);
for(i=0;i<8;i++)

CLK = 0;
//这里大约是100us
if(cmd & 0x80)DATAS = 1;//把datas的参数与16进制数8000进行位与运算把结果给datas(如果有数则DAT=1
else DATAS = 0;//否则DAT=0
MyDelay(200) ;
CLK = 1;
MyDelay(200) ;//这里大约是100us
cmd <<= 1;
}
DATAS = 1;
STB_IO = 1;
CLK = 1;
}

 

 

 

 

/*-----------------------------------------------------------------------------
函数功能 : 主函数
-----------------------------------------------------------------------------*/
void main(void)
{  
      unsigned char YSJS=5 ;
   
      EX0=1;//开中断0
 EA=1; //开总中断
 IT0=1; //设定中断0方式为下降沿触发。
      while (1)
       {

        if   (SPI_ZL==0)   {POWSW=1;LED_SD=1;LED_KD=1;LED_GD=1;LED_YX=1;LED_FW=1;}       //  关闭电源状态
        while(SPI_ZL==0){;  }

        if   (SPI_ZL==1){VSW=0; POWSW=0;}                                                                  //启动电源的状态。  
        while(SPI_ZL==1)   {LED_SD=~LED_SD;LED_KD=~LED_KD;LED_GD=~LED_GD;LED_YX=~LED_YX;LED_FW=~LED_FW;Delay(300); }
 
        if   (SPI_ZL==2){  LED_SD=1;LED_KD=1;LED_GD=1;LED_YX=1;LED_FW=0;                      }   //复位状态
        while(SPI_ZL==2){;}                         
        if   (SPI_ZL==3){    LED_SD=0;LED_KD=1;LED_GD=1;LED_YX=0;LED_FW=1; VSW=1; POWSW=0;                             }       //运行状态
        while(SPI_ZL==3)
             {
             
    if(BBZ!=b)
                {
 LED_SD=1;
 LED_KD=1;
 LED_GD=1;
                 while(--YSJS){LED_SD=~LED_SD;Delay(100);}
 LED_SD=0 ;
                 BBZ=b;
YSJS=5 ;
                }
    if(CBZ!=c)
    {
 LED_SD=1;
 LED_KD=1;
 LED_GD=1;
  while(--YSJS){LED_KD=~LED_KD;Delay(100);}
 LED_KD=0;
     CBZ=c;
   YSJS=5 ;
    }
  if(DBZ!=d)
    {
   LED_SD=1;
 LED_KD=1;
 LED_GD=1;
while(--YSJS){LED_GD=~LED_GD;Delay(100);}
LED_GD=0;
     DBZ=d;
   YSJS=5 ;
    }
 
 
              }  
  if   (SPI_ZL==4)                                                                       //暂停状态
    { 
     LED_SD=0;LED_KD=1;LED_GD=1;LED_YX=0;LED_FW=1; POWSW=1;                     
}
        while (SPI_ZL==4)                                                                               //参数调整
              {
    if(BBZ!=b)
                {
 LED_SD=1;
 LED_KD=1;
 LED_GD=1;
                 while(--YSJS){LED_SD=~LED_SD;Delay(100);}
 LED_SD=0 ;
                 BBZ=b;
YSJS=5 ;
                }
    if(CBZ!=c)
    {
 LED_SD=1;
 LED_KD=1;
 LED_GD=1;
  while(--YSJS){LED_KD=~LED_KD;Delay(100);}
 LED_KD=0;
     CBZ=c;
   YSJS=5 ;
    }
  if(DBZ!=d)
    {
   LED_SD=1;
 LED_KD=1;
 LED_GD=1;
while(--YSJS){LED_GD=~LED_GD;Delay(100);}
LED_GD=0;
     DBZ=d;
   YSJS=5 ;
    }
 LED_YX=~LED_YX;
 Delay(100);   
                }  
       
        }     

 }
  /*-----------------------------------------------------------------------------
函数功能 : 串行中断接收

-----------------------------------------------------------------------------*/
 void SPI_IO(void) interrupt 0

{  

     IE0=0;
m=0; 
  if(STB_IO==0)
{   
 for(m=0;m<16;m++)
 { 
   while(CLK==1){;} 
   if(CLK==0)
     {
   _nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
       if(DATAS==1){ z|=1;}
else{ z|=0;}   
     }
zd0=z;
  z=z<<1;

 
   while(CLK==0){;}
  }
 
 SPI_DL=zd0;
zd0>>=8;
SPI_DH=zd0;
if(SPI_DH==0)
   { 
SPI_ZL  =   SPI_DL; 
}
 if(SPI_DH==0xf1)
  {
   c       =   SPI_DL;
   }
if(SPI_DH==0xf0)
 {
  b       =   SPI_DL;
  }
 
if(SPI_DH==0xf2)
  {
  d       =   SPI_DL;
  }
 
}
   IE0=0;
}

 

关闭窗口

相关文章