No.102476 作者:w75815895 邮件:ggge4@126.com ID:65297 登陆:18次 文章数:31篇 最后登陆IP:121.35.207.36 最后登陆:2014/11/29 15:30:46 注册:2006/12/13 13:33:14 财富:247 发帖时间:2014/11/29 15:30:46 发贴者IP:121.35.207.36 标题:w75815895:51单片机控制6轴伺服电机程序,带直线插补圆弧插补 摘要:No.10247651单片机控制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[1 ......
>>返回讨论的主题
|