导航: 老古网老古论坛XMOS公共讨论区XMOS开源项目区单片机程序设计嵌入式系统广告区域
→51单片机控制6轴伺服电机程序,带直线插补圆弧插补

* 102476: 51单片机控制6轴伺服电机程序,带直线插补圆弧插补

   w75815895 
w75815895发表的帖子 

 51单片机控制6轴伺服电机程序,带直线插补圆弧插补

单片机与mpc006运动控制模块组成的运动控制系统

摘要:采用单片机stc89C2051和mpc006微型运动控制模块作为控制系统的核心,控制三路步进电机做运动实验。单片机发送指令给mpc006微型运动控制模块,模块信号输出给步进驱动器作高速度运动。可以定点运动,直线插补和圆弧插补。


 1.引言
运动控制的应用在国内已有十几年的历史,技术也相当成熟。通常运动控制都需要用到运动控制卡,运动控制器等产品,但这些产品价格高昂,使用复杂,也不适合由单片机构成的控制系统。而如果直接采用单片机来做运动控制,由于运动控制对系统性能要求非常高,单片机速度资源有限,难以设计出性能优良的运动控制模型。因此,本文采用单片机和专业的mpc006微型运动控制模块构成运动控制系统。
MPC006微型运动控制模块采用新型FPGA设计,集成实用运动控制功能,可与普通单片机通过串口通讯对步进电机和伺服电机控制。具有如下特点:
◆   串口通讯,仅需使用几条指令,简单可靠。
◆   单模块最高六轴输出,多个模块组网工作可达120轴。 
◆   最大脉冲输出频率为2MHz,脉冲输出使用脉冲+方向方式。
◆   最高六轴独立运动控制,任意两轴直线插补,任意两轴圆弧插补。  
◆   每轴一路硬件回原点。
◆   模块带1000级指令缓存深度,指令先进先出。
◆  模块体积小巧,仅3.5*2.5*1.5cm,双排直插30脚封装。


2,系统硬件设计
硬件系统由四部分构成:
(1) 单片机部分
单片机与模块只需三根线连接,用作串口通讯的RXD和TXD,用作模块缓存满输出的BUSY信号。P3.7引出一按键作为测试使用。
 

(2) mpc006微型运动控制模块部分
mpc006微型运动控制模块采用5V电源供电,RXD,TXD,BUSY与单片机连接。X0,X1,X2可作为三路电机的原点信号,P1,D1为1轴的脉冲和方向信号。P2,D2为2轴的脉冲和方向信号。P3,D3为3轴的脉冲和方向信号。

 

(3)原点信号输入部分
原点采用光藕隔离输入,输入端可接NPN型光电开关来作为原点信号。


 

(4) 信号输出部分
输出采用NPN晶体管极电极开路输出,分别接到电机驱动器脉冲和方向信号输入端。
 

3,系统软件设计

MPC006微型运动控制模块与单片机串口通讯速率为115200bps,数据位为8位,停止位0位,无校验。使用函数前先设置好单片机的串口功能,并将需要用到的函数的原型拷贝到当前程序内。
试验程序如下:

#include   <reg52.h>  

//-----STC89C2051-------
sfr IPH  =0XB7;  
sfr CCON =0XD8;
sfr CMOD =0XD9;
sfr CL  =0XE9;
sfr CH  =0XF9;
sfr CCAP0L =0XEA;
sfr CCAP0H =0XFA;
sfr CCAPM0 =0XDA;
sfr CCAPM1 =0XDB;
sfr P3M1= 0XB1;
sfr P3M0= 0XB2;
sfr P1M1= 0X91;
sfr P1M0= 0X92;
sfr WAKE_CLKO= 0X8f;
sfr BRT     =0x9c;
sfr AUXR     =0x8E;
sfr AUXR1   = 0xA2;     
sfr WDT_CONTR = 0xc1;  
sfr T2MOD  = 0xC9;       
//////////////////


sbit busy = P3^2;
sbit s1 = P3^7; 

 void initial()
{
 P3M1 = 0x00;  
 P3M0 = 0x80; 
 P1M1 = 0x00;  
 P1M0 = 0xf9;      
}
 void init_uart()
{
  PCON &= 0x7f;  //波特率不倍速
   SCON = 0x50;  //8位数据,可变波特率
   BRT = 0xFD;      //设定独立波特率发生器重装值 波特率115200bps
   AUXR |= 0x04;  //独立波特率发生器时钟为Fosc,即1T
   AUXR |= 0x01;  //串口1选择独立波特率发生器为波特率发生器
   AUXR |= 0x10;  //启动独立波特率发生器
}


/*
串口发送一个字节,需根据所使用的单片机作适当更改。
*/
 void USART_Txbyte(unsigned char i)
{
    SBUF   =   i;
    while(TI ==0); //等待发送完成
    TI     =   0;  //清零串口发送完成中断请求标志
}

/*
串口接收模块返回的10个字节数据,需根据所使用的单片机作适当更改。
*/
 void receive(unsigned char *buf)
{
unsigned char i;
for(i=0;i  <10;i++)
   { 
   while(RI==0); 
    RI=0;
   buf[i]=SBUF;
   } 
}

/*
串口发送一串数据。
*/
void USRAT_transmit(unsigned char *fdata,unsigned char len)
{
   unsigned char i;           
    
   for(i=0;i  <len;i++)
   { 
      USART_Txbyte(fdata[i]);  
   }
   

/*
函数名:  inp_move
功能:二轴直线插补
参数:
cardno  卡号
no1   X轴轴号
no2   Y轴轴号
pulse1,pulse2    X-Y轴移动的距离,范围(-8388608~+8388607)
mode  0:相对坐标  1:绝对坐标
返回值:
0 失败  1  成功
*/
unsigned char inp_move(unsigned char cardno,unsigned char no1 ,unsigned char no2 , long pulse1  ,long pulse2 ,unsigned char mode ) 
{
unsigned char OutByte[25];
unsigned char inbuf[12];
OutByte[0] = 0x68;
OutByte[1] = 0x0F;
OutByte[2] = cardno;
OutByte[3] = 0x7;
OutByte[4] = no1;
OutByte[5] = no2;
OutByte[6] = pulse1>  >  24;
OutByte[7] = pulse1 >  >  16;
OutByte[8] = pulse1>  >   8;
OutByte[9] = pulse1;
OutByte[10] = pulse2 >  >  24;
OutByte[11] = pulse2 >  >  16;
OutByte[12] = pulse2 >  >  8;
OutByte[13] = pulse2 ;
OutByte[14] = mode;
OutByte[15] =OutByte[1] +OutByte[2] +OutByte[3] +OutByte[4]+OutByte[5] +OutByte[6] +OutByte[7] +OutByte[8] +OutByte[9] +OutByte[10] +OutByte[11] + OutByte[12] +OutByte[13] +OutByte[14];
USRAT_transmit(OutByte,16);
receive(inbuf);
return 1;
}

/*
函数名: inp_arc
功能:二轴圆弧插补
参数:
cardno 卡号
no1  参与插补X轴的轴号
no2  参与插补Y轴的轴号
x,y  圆弧插补的终点位置(相对于起点),范围(-8388608~+8388607)    
i,j  圆弧插补的圆心点位置(相对于起点),范围(-8388608~+8388607)
mode      0:顺时针插补   1:逆时针插补
返回值:
0 失败  1  成功
*/
unsigned char inp_arc(unsigned char cardno ,unsigned char no1,unsigned char no2, long X , long y, long i, long j,unsigned char mode ) 
{
unsigned char OutByte[25];
unsigned char inbuf[12];
OutByte[0] = 0x68;
OutByte[1] = 0x17;
OutByte[2] = cardno;
OutByte[3] = 0x7;
OutByte[4] = no1;
OutByte[5] = no2;
OutByte[6] = X >  >  24;
OutByte[7] = X >  >  16;
OutByte[8] = X >  >  8;
OutByte[9] = X ;
OutByte[10] = y >  >  24;
OutByte[11] = y >  >  16;
OutByte[12] = y >  >  8;
OutByte[13] = y ;
OutByte[14] = i >  >  24;
OutByte[15] = i >  >  16;
OutByte[16] = i >  >  8;
OutByte[17] = i ;
OutByte[18] = j >  >  24;
OutByte[19] = j >  >  16;
OutByte[20] = j >  >  8;
OutByte[21] = j ;
OutByte[22] = mode;
OutByte[23] =OutByte[1] +OutByte[2] +OutByte[3] +OutByte[4] +OutByte[5] +OutByte[6] +OutByte[7] +OutByte[8] +OutByte[9] +OutByte[10] +OutByte[11] + OutByte[12] +OutByte[13] +OutByte[14] +OutByte[15] +OutByte[16] +OutByte[17] +OutByte[18] +OutByte[19] +OutByte[20] +OutByte[21] +OutByte[22] ;
USRAT_transmit(OutByte,24);  
receive(inbuf);
return 1;
}

/*
函数名:  set_speed
功能:设置轴速度
参数:
cardno 卡号
axis 轴号(1-6)
acc     加速时间(ms)
dec     减速时间(ms)
startv     启动频率(*100Hz)
speed      运行频率(*100Hz)
返回值:
0 失败  1  成功
*/
unsigned char set_speed(unsigned char cardno ,unsigned char axis ,unsigned int acc  ,unsigned int dec  ,unsigned int startv ,unsigned int speed ) 
{
unsigned char OutByte[25];
unsigned char inbuf[12];
OutByte[0] = 0x68;
OutByte[1] = 0xD;
OutByte[2] = cardno;
OutByte[3] = 1;
OutByte[4] = axis;
OutByte[5] = acc >  >  8;
OutByte[6] = acc ;
OutByte[7] = dec >  >  8;
OutByte[8] = dec ;
OutByte[9] = startv >  >  8;
OutByte[10] = startv ;
OutByte[11] = speed >  >  8;
OutByte[12] = speed ;
OutByte[13] =OutByte[1] +OutByte[2] +OutByte[3] +OutByte[4] +OutByte[5] +OutByte[6] +OutByte[7] +OutByte[8] +OutByte[9] +OutByte[10] +OutByte[11] + 
OutByte[12] ;
USRAT_transmit(OutByte,14);
receive(inbuf);
return 1;
}

/*
函数名: set_soft_limit
功能:设置轴软件限位
参数:
cardno 卡号
axis  轴号(1-6)
pulse1  负方向限位脉冲值,范围(-8388608~0)    
pulse2  正方向限位脉冲值,范围(0~+8388607)
返回值:
0 失败  1  成功
*/
unsigned char set_soft_limit(unsigned char cardno ,unsigned char axis ,unsigned char mode, long pulse1 , long pulse2 ) 

unsigned char OutByte[25];
unsigned char inbuf[12];
OutByte[0] = 0x68;
OutByte[1] = 0xE;
OutByte[2] = cardno ;
OutByte[3] = 0x13;
OutByte[4] = axis;
OutByte[5] = mode;
OutByte[6] = pulse1 >  >  24;
OutByte[7] = pulse1 >  >  16;
OutByte[8] = pulse1 >  >  8;
OutByte[9] = pulse1 ;
OutByte[10] = pulse2 >  >  24;
OutByte[11] = pulse2 >  >  16;
OutByte[12] = pulse2 >  >  8;
OutByte[13] = pulse2 ;
OutByte[14] =OutByte[1] +OutByte[2] +OutByte[3] +OutByte[4] +OutByte[5] +OutByte[6] +OutByte[7] +OutByte[8] +OutByte[9] +OutByte[10] +OutByte[11] + 
OutByte[12] +OutByte[13] ;
USRAT_transmit(OutByte,15);
receive(inbuf);
return 1;
}

/*
函数名: pmove
功能:单轴运行
参数:
cardno 卡号
axis  轴号(1-6)
pulse  输出的脉冲数 >  0:正方向移动     <0:负方向移动 范围(-268435455~+268435455)
mode      0:相对位置   1:绝对位置
返回值:
0 失败  1  成功
*/
unsigned char pmove(unsigned char cardno ,unsigned char axis,long pulse , unsigned char mode) 
{
unsigned char OutByte[25];
unsigned char inbuf[12]; 
OutByte[0] = 0x68;
OutByte[1] = 0xA ;
OutByte[2] = cardno;
OutByte[3] = 2 ;
OutByte[4] = axis;
OutByte[5] = pulse >  >  24;
OutByte[6] = pulse >  >  16;
OutByte[7] = pulse >  >  8;
OutByte[8] = pulse ;
OutByte[9] = mode ;
OutByte[10] =OutByte[1] +OutByte[2] +OutByte[3] +OutByte[4] +OutByte[5] +OutByte[6] +OutByte[7] +OutByte[8] +OutByte[9] ;
USRAT_transmit(OutByte,11);
receive(inbuf);
return 1;
}

/*
函数名: wait_delay
功能:等待延时数
参数:
cardno 卡号
value   延时量(1-10000)MS
返回值:
0 失败  1  成功
*/
unsigned char wait_delay(unsigned char cardno ,unsigned int value) 
{
unsigned char OutByte[25];
unsigned char inbuf[12]; 
OutByte[0] = 0x68 ;
OutByte[1] = 0x6 ;
OutByte[2] = cardno ;
OutByte[3] = 0xE ;
OutByte[4] = value >  >  8;
OutByte[5] = value ;
OutByte[6] =OutByte[1] +OutByte[2] +OutByte[3] +OutByte[4] +OutByte[5];
USRAT_transmit(OutByte,7);
receive(inbuf);
return 1;
}

/*
函数名: set_command_pos
功能: 设置轴逻辑位置
参数:
cardno 卡号
axis 轴号(1-6)
pulse  位置脉冲数,范围(-268435455~+268435455)
返回值:
0 失败  1  成功
*/
unsigned char set_command_pos(unsigned char cardno ,unsigned char axis, long value ) 
{
unsigned char OutByte[25];
unsigned char inbuf[12]; 
OutByte[0] = 0x68 ;
OutByte[1] = 0x9 ;
OutByte[2] = cardno ;
OutByte[3] = 0x12 ;
OutByte[4] = axis ;
OutByte[5] = value >  >  24;
OutByte[6] = value >  >  16;
OutByte[7] = value >  >  8;
OutByte[8] = value ;
OutByte[9] =OutByte[1] +OutByte[2] +OutByte[3] +OutByte[4] +OutByte[5] +OutByte[6] +OutByte[7] +OutByte[8] ;
USRAT_transmit(OutByte,10);
receive(inbuf);
return 1;
}


 /*
函数名: wait_pulse
功能:等待轴脉冲数
参数:
cardno 卡号
axis 轴号(1-6)
pulse  位置脉冲数,范围(-268435455~+268435455)
返回值:
0 失败  1  成功
*/
unsigned char wait_pulse(unsigned char cardno ,unsigned char axis, long value ) 
{
unsigned char OutByte[25];
unsigned char inbuf[12];
OutByte[0] = 0x68;
OutByte[1] = 0x9 ;
OutByte[2] = cardno ;
OutByte[3] = 0x19;
OutByte[4] = axis ;
OutByte[5] = value >  >  24;
OutByte[6] = value >  >  16;
OutByte[7] = value >  >  8;
OutByte[8] = value ;
OutByte[9] =OutByte[1] +OutByte[2] +OutByte[3] +OutByte[4] +OutByte[5] +OutByte[6] +OutByte[7] +OutByte[8] ;
USRAT_transmit(OutByte,10);
receive(inbuf);
return 1;
}

/*
函数名: write_bit
功能:写输出口状态
参数:
cardno 卡号
number  端口号(0-8)  Y0-Y8
value   状态(0,1) 0 输出低电平   1 输出高电平
返回值:
0 失败  1  成功
*/
unsigned char write_bit(unsigned char cardno , unsigned char number, unsigned char value) 
{
unsigned char OutByte[25];
unsigned char inbuf[12]; 
OutByte[0] = 0x68 ;
OutByte[1] = 0x6  ;
OutByte[2] = cardno ;
OutByte[3] = 3 ;
OutByte[4] = number;
OutByte[5] = value;
OutByte[6] =OutByte[1] +OutByte[2] +OutByte[3] +OutByte[4] +OutByte[5] ;
USRAT_transmit(OutByte,7);
receive(inbuf);
return 1;
}


/*
函数名: sudden_stop
功能: 轴停止
参数:
cardno 卡号
axis 停止的轴号(1-6)
返回值:
0 失败  1  成功
*/
unsigned char sudden_stop(unsigned char cardno ,unsigned char axis) 
{
unsigned char OutByte[25];
unsigned char inbuf[12]; 
OutByte[0] = 0x68;
OutByte[1] = 0x5;
OutByte[2] = cardno ;
OutByte[3] = 0x17 ;
OutByte[4] = axis ;
OutByte[5] =OutByte[1] +OutByte[2] +OutByte[3] +OutByte[4] ;
USRAT_transmit(OutByte,6);
receive(inbuf);
return 1;
}


/*
函数名: wait_in
功能: 等待输入口状态
参数:
cardno 卡号
number  端口号(0-6)  X0-X6
value   状态(0,1) 0 输入低电平   1 输入高电平
返回值:
0 失败  1  成功
*/
unsigned char wait_in( unsigned char cardno, unsigned char number, unsigned char value) 
{
unsigned char OutByte[25];
unsigned char inbuf[12];
OutByte[0] = 0x68 ;
OutByte[1] = 0x6  ;
OutByte[2] = cardno;
OutByte[3] = 0xF  ;
OutByte[4] = number ;
OutByte[5] = value ;
OutByte[6] =OutByte[1] +OutByte[2] +OutByte[3] +OutByte[4] +OutByte[5];
USRAT_transmit(OutByte,7);
receive(inbuf);
return 1;
}


/*
函数名: wait_stop
功能:等待轴停止
参数:
cardno  卡号
axis  需要停止的轴号
返回值:
0 失败  1  成功
*/
unsigned char wait_stop(unsigned char cardno ,unsigned char axis) 
{
unsigned char OutByte[25];
unsigned char inbuf[12]; 
OutByte[0] = 0x68  ;
OutByte[1] = 0x5 ;
OutByte[2] = cardno ;
OutByte[3] = 9 ;
OutByte[4] = axis ;
OutByte[5] =OutByte[1] +OutByte[2] +OutByte[3] +OutByte[4];
USRAT_transmit(OutByte,6);
receive(inbuf);
return 1;
}

/*
函数名:  get_number
功能:获取唯一序列号
参数:
cardno 卡号
返回值: 32位序列号

*/
unsigned long get_number(unsigned char cardno ) 
{
unsigned char OutByte[25];
unsigned char inbuf[12]; 
OutByte[0] = 0x68 ;
OutByte[1] = 0x4 ;
OutByte[2] = cardno;
OutByte[3] = 0xC ;
OutByte[4] =OutByte[1] +OutByte[2] +OutByte[3] ;
USRAT_transmit(OutByte,5);
receive(inbuf);
return (unsigned long)inbuf[4]  <  <24+(unsigned long)inbuf[5]  <  <16+(unsigned long)inbuf[6]  <  <8+(unsigned long)inbuf[7];
}

/*
函数名: get_status
功能:获取各轴工作状态
参数:
cardno 卡号
返回值: 8位二进制,1-6位分别代表1-6轴状态,0表示停止中,1表示运行中。
*/
unsigned char get_status( unsigned char cardno) 
{
unsigned char OutByte[25];
unsigned char inbuf[12];
OutByte[0] = 0x68  ;
OutByte[1] = 0x4  ;
OutByte[2] = cardno ;
OutByte[3] = 5 ;
OutByte[4] =OutByte[1] +OutByte[2] +OutByte[3] ;
USRAT_transmit(OutByte,5);
receive(inbuf);
return inbuf[4];
}


/*
函数名: get_command_pos
功能: 获取轴逻辑位置
参数:
cardno 卡号
axis  轴号
返回值:  位置脉冲数,范围(-268435455~+268435455)
*/
unsigned long  get_command_pos( unsigned char cardno, unsigned char axis) 
{
unsigned char OutByte[25];
unsigned char inbuf[12]; 
OutByte[0] = 0x68  ;
OutByte[1] = 0x5  ;
OutByte[2] = cardno  ;
OutByte[3] = 6  ;
OutByte[4] = axis ;
OutByte[5] =OutByte[1] +OutByte[2] +OutByte[3] +OutByte[4] ;
USRAT_transmit(OutByte,6);
receive(inbuf);
return (unsigned long)inbuf[5]  <  <24+(unsigned long)inbuf[6]  <  <16+(unsigned long)inbuf[7]  <  <8+(unsigned long)inbuf[8];
}

/*
函数名: set_cardno
功能:设置卡号
参数:
cardno 卡号(1-255)
返回值:
0 失败  1  成功
*/
unsigned char set_cardno(unsigned char cardno) 

unsigned char OutByte[25];
unsigned char inbuf[12];
OutByte[0] = 0x68  ;
OutByte[1] = 5  ;
OutByte[2] = 0   ;
OutByte[3] = 0xFA ;
OutByte[4] = cardno ;
OutByte[5] =OutByte[1] +OutByte[2] +OutByte[3] +OutByte[4] ;
USRAT_transmit(OutByte,6);
receive(inbuf);
return 1;
}


void main(void)  
{
   initial();
   init_uart();

   set_cardno(1);    //设卡号为1
   while(1)
  { 
    
  if(!s1)//按键按下 
    {
     set_speed(1 ,1,1000,1000,10,200);   // 设1轴速度
        set_speed(1 ,2,1000,1000,10,200);   // 设2轴速度
        set_speed(1 ,3,1000,1000,10,200);   // 设3轴速度

         /*1轴回原点*/
         pmove(1,1,-1000000,0);    //  1轴运动
         wait_in(1,0,1);       //   等待X0为高
         sudden_stop(1,1);     //    1轴停止
        set_command_pos(1,1,0);  //    设1轴此时坐标为0
  pmove(1,2,3200,0);    //  2轴运动 
  pmove(1,3,-3200,0);    //  3轴运动    
      while(!s1);
    }
  
   
  }
 
}


4,结束语
单片机和mpc006运动控制模块构成的系统,使单片机彻底地从复杂的运动控制算法中解放出来,单片机只需简单地使用几条指令来控制模块便可完成运动控制,从而能将更多的资源用来参与其它方面的控制,对构建一个稳定的控制系统具有重大意义。 


本文来自泰安迪科技官网   转载请注明出处。




发表时间:2014年11月29日15:30:46

  
回复该帖

本主题共有 1 帖,分页:>>>>>该主题的所有内容[1]条

 *树形目录 只列出部分跟帖的标题以及简单的摘要信息 该主题的部分跟帖如下:

[上一篇帖子]:视频测试仪常见功能有哪些?目前视频测试仪常见功能有哪些? (1)能测试视频信号(PAL和NT
[下一篇帖子]:mpc006,mpc003运动控制芯片mpc003,mpc006运动控制芯片模块采用新型FPGA设计