完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本帖最后由 w75815895 于 2020-8-26 14:16 编辑
Xc1004四轴SPI运动控制芯片 参 考 手 册 泰 概述 SPI通讯,仅需使用10条指令便可完成复杂工作。 单芯片四轴输出,多个芯片通过不同片选脚可控制达120轴。 独立轴e版本支持最大脉冲输出频率1.2MHz独立输出。 插补轴f版本支持四轴,三轴,二轴,一轴直线插补,二轴圆弧插补,螺旋插补,支持连续插补,支持速度前瞻。 脉冲输出使用脉冲+方向方式。 各版本拥有128条运动指令缓存空间。 LQFP48封装,引脚输入输出3.3V,可兼容5V。 模块性能参数
引脚排列
SPI通讯协议 芯片与单片机使用SPI通讯,单片机作为主机,芯片为从机。CPHA=0,CPOL=0,高位在前,SPI数据宽度为8位。空闲状态下单片机SCK引脚必须为低电平。每一条指令开始发送前将CS引脚置低,整条指令发送完成后必须将CS置高。 每条指令间隔1MS以上。 SPI时序图如下: SPI通讯指令 ◆设置轴速度(e版本f版本共用指令) 发送:
部分参数解释: 轴号(1,2,3,4) 加减速 加减速为: e版(1-480000)(Hz/s2) f版(1-1600000)(Hz/s2) 运行速度 运行频率为:e版(1-1200000)(Hz) f版(1-400000)(Hz) 要点:e版本轴号有效,速度为对应轴的速度。f版本由于共用一个插补核心,轴号设为任意值都为所有轴速度,如需改变当前运动指令里的速度需在当前指令前重设速度。加速度最大可设为运行速度4倍。 ◆设置轴逻辑位置(e版本f版本共用指令) 发送:
部分参数解释: 轴号(1,2,3,4) 1-4:1-4轴 位置 轴逻辑位置,范围(-268435455~+268435455) ◆轴停止(e版本f版本共用指令) 发送:
部分参数解释: 轴号(1,2,3,4) 1-4: 1-4轴 模式(0,1,2) 0:急停并清空后面缓存的指令 1:减速停不清空后面缓存的指令 2:急停不清空后面缓存的指令 要点:f版本由于共用一个插补核心,轴号设为任意值都会让所用轴停止。 ◆获取各轴逻辑位置和状态(e版本f版本共用指令) 发送:
返回:
部分参数解释: 各轴运行状态(转为8位二进制数) 第0位为e版1轴状态 0:停止中 1:运行中 第1位为e版2轴状态 0:停止中 1:运行中 第2位为e版3轴状态 0:停止中 1:运行中 第3位为e版4轴状态 0:停止中 1:运行中 第5位为f版插补核各轴状态 0:停止中 1:运行中 缓存数量(0-128) 还未运行的缓存指令数 各轴坐标 范围(-268435455~+268435455) 要点:返回字节按功能顺序排列,由于SPI工作模式是一边发送一边接收,如只需取前面字节的数据,为节省通讯时间,可只发送对应字节的数据0。例如只需获取各轴运行状态,发送2个字节0便可。轴运行状态只是轴的瞬时状态,不能用来指示圆弧指令是否完成。可通过读取缓存数量来判断缓存区指令是否完成。一条圆弧指令会动态占用最多120条缓存空间。 ◆ 设置特殊功能(f版本专用指令) 发送:
部分参数解释: 当功能写入0xfc,缓存内运动指令暂停。 当功能写入0xfd,取消缓存内运动指令暂停。 以下指令会自动进入缓存区并排队执行: ◆ 回原点(e版本f版本共用指令) 发送:
部分参数解释: 轴号(1,2,3,4) 进入原点速度 运行频率为:值(1-400000)(Hz) 离开原点速度 运行频率为:值(1-400000)(Hz) 要点:回原点指令会自动生成一段负脉冲和一段正脉冲。以进入原点速度输出负脉冲时,左限位原点开关生效时自动减速停;随后以离开原点速度输出正脉冲,离开原点限位开关时自动急速停止,急停后可作为原点。回原点指令不宜和其它运动指令混合在一起放入缓存里,回原点过程应单独存在。 ◆ 四轴直线插补(f版本专用指令) 发送:
部分参数解释: X轴号(1,2,3,4) Y轴号(1,2,3,4) Z轴号(1,2,3,4) E轴号(1,2,3,4) X脉冲(-268435455~+268435455) Y脉冲(-268435455~+268435455) Z脉冲(-268435455~+268435455) E脉冲(-268435455~+268435455) 运动方式(0,1) 0:绝对位移 1:相对位移 要点:当只需要少于四轴做插补时,不用的轴号和脉冲数写0。 ◆ 二轴圆弧插补(f版本专用指令) 发送:
部分参数解释: X轴号(1,2,3) Y轴号(1,2,3) 终点坐标 圆弧插补的终点位置,范围(-268435455~+268435455) 圆心坐标 圆弧插补的圆心点位置,范围(-268435455~+268435455) 运动方式1 0:逆时针插补 1:顺时针插补 2:三点定圆弧 运动方式2 0:绝对位移 1:相对位移 要点:圆弧各坐标必须能构成正常的圆弧。圆弧插补指令会根据圆弧参数动态占用缓存空间。当运动方式1设为2时,为三点定圆弧模式,圆心坐标参数设为圆弧的中间点坐标。 ◆ 三轴螺旋插补(f版本专用指令) 发送:
部分参数解释: X轴号 (1,2,3) 圆弧X轴 Y轴号 (1,2,3) 圆弧Y轴 Z轴号 (1,2,3) 螺旋轴 终点坐标 圆弧插补的终点位置,范围(-268435455~+268435455) 圆心坐标 圆弧插补的圆心点位置,范围(-268435455~+268435455) 运动方式1 0:逆时针插补 1:顺时针插补 运动方式2 0:绝对位移 1:相对位移 ◆ 等待延时(e版本f版本共用指令) 发送:
部分参数解释: 延时量(1-10000)MS 要点:等待延时是指等待所设延时量后才执行后面的指令。 ◆写输出口状态(e版本f版本共用指令) 发送:
部分参数解释: 输出端口号 (0-6) Y0-Y6 输出状态 (0,1) 0:输出低电平 1:输出高电平 ◆ 单轴运行(e版本专用指令) 发送:
部分参数解释: 轴号(1,2,3,4) 独立轴运动的轴号 脉冲数量(-268435455~+268435455)输出的脉冲数 >0:正方向移动 <0:负方向移动 运动方式(0,1) 0:绝对位移 1:相对位移 ◆等待轴停止(e版本专用指令) 发送:
部分参数解释: 轴号(1,2,3,4) 1,2,3,4:独立轴1-4轴 要点:等待轴停止是指在对应轴停止之前一直等待,直到轴停止后才执行后面的指令。独立轴不会自动等待轴运行完成后才执行下一条指令。插补轴会自动等待轴运行完成后才执行下一条指令。 电路连接 芯片引脚输出最大电流15Ma,输入灌电流最大25Ma。如多芯片组网,各芯片的SCK,SO,SI引脚并联,CS脚独立受单片机控制。单片机SPI数据输入脚接芯片SO脚,需内部或外部上拉。单片机SPI数据输出脚接芯片SI脚。芯片,单片机,差分输出连接参考图: 运动控制编程参考 通过51单片机控制运动控制芯片的SPI通信程序示例。 (来自产品官网:http://www.lf-control.com) #include #include //MCU: stc8f2k08s2 sfr P0M1 = 0x93; sfr P0M0 = 0x94; sfr P1M1 = 0x91; sfr P1M0 = 0x92; sfr P2M1 = 0x95; sfr P2M0 = 0x96; sfr P3M1 = 0xb1; sfr P3M0 = 0xb2; sfr P4M1 = 0xb3; sfr P4M0 = 0xb4; sfr P5M1 = 0xC9; sfr P5M0 = 0xCA; sfr P6M1 = 0xCB; sfr P6M0 = 0xCC; sfr P7M1 = 0xE1; sfr P7M0 = 0xE2; sfr P5 = 0xC8; sfr SPSTAT = 0xcd; sfr SPCTL = 0xce; sfr SPDAT = 0xcf; sfr IE2 = 0xaf; sfr AUXR = 0x8e; sfr T2H = 0xd6; sfr T2L = 0xd7; sfr P_SW2 = 0xba; #define CKSEL (*(unsigned char volatile xdata *)0xfe00) #define CKDIV (*(unsigned char volatile xdata*)0xfe01) #define IRC24MCR (*(unsigned char volatile xdata*)0xfe02) #define XOSCCR (*(unsigned char volatile xdata*)0xfe03) #define IRC32KCR (*(unsigned char volatile xdata*)0xfe04) //#define FOSC 16000000UL //使用外部16M晶振 #define FOSC 24000000UL //使用内部24M晶振 #define BRT (65536 - FOSC / 115200 / 4) //定义115200波特率 ***it b2 = P1^1; ***it b1 = P5^5; ***it led = P3^5; ***it cs3 = P3^3; ***it cs2 = P3^2; ***it cs1 = P1^2; ***it sck = P1^5; ***it in = P1^4; ***it out = P1^3; #define SPI3_CSHIGH cs3=1 // CS3 #define SPI3_CSLOW cs3=0 #define SPI2_CSHIGH cs2=1 // CS2 #define SPI2_CSLOW cs2=0 #define SPI1_CSHIGH cs1=1 // CS1 #define SPI1_CSLOW cs1=0 #define SPI_SCKHIGH sck=1 //SCK #define SPI_SCKLOW sck=0 #define SPI_OUTHIGH out=1 #define SPI_OUTLOW out=0//MOSI #define SPI_IN in//MISO unsigned char inbuf[50]; unsigned char b1_state=0; voidinitial() { P1M1= 0; P1M0= 0x2c; // 引脚模拟通信时,MOSI,SCK, CS 设为推挽输出 SPI1_CSHIGH; //CS不使用时设为高 SPI2_CSHIGH; SPI3_CSHIGH; SPI_SCKLOW;//SCK空闲状态一定要为低电平。 //SPCTL = 0xd0; //使能SPI主机模式 //SPSTAT = 0xc0; //清中断标志 } void init_uart() { SCON = 0x50; T2L = BRT; T2H = BRT >> 8; AUXR = 0x15; } /* 串口发送一个字节。 */ voidUSART_Txbyte(unsigned char i) { SBUF = i; while(TI ==0); TI = 0; } /* 串口发送一串数据。 */ void USRAT_transmit(unsigned char*fdata,unsigned char len) { unsigned char i; for(i=0;i
{ USART_Txbyte(fdata); } } voiddelay_nus(unsigned long n) { unsigned long j; while(n--) { j=1; while(j--); } } //延时n ms void delay_nms(unsigned long n) { while(n--) delay_nus(1000); } /* 函数名: SPI_SendData 功能:软件模拟SPI通讯发送并接收一个8位字节数据。 如需使用硬件SPI,单片机作为主机,运动控制芯片为从机。CPHA=0,CPOL=0,高位在前,SPI数据宽度为8位。 空闲状态下单片机SCK引脚必须为低电平。每一条指令开始发送前将CS引脚置低,整条指令发送完成后必须将CS置高。 每条指令间需有时间间隔,推荐延时1MS以上。 */ unsigned char SPI_SendData(unsigned charoutdata) { unsigned char RecevieData=0,i; SPI_SCKLOW; // _nop_();_nop_(); _nop_();_nop_(); _nop_();_nop_();_nop_(); _nop_(); _nop_(); _nop_();_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); for(i=0;i<8;i++) { SPI_SCKLOW; _nop_(); _nop_(); _nop_();_nop_(); _nop_();_nop_(); _nop_(); _nop_(); _nop_();_nop_();_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); if(outdata&0x80) { SPI_OUTHIGH; } else { SPI_OUTLOW; } outdata<<=1; _nop_(); _nop_(); _nop_();_nop_(); _nop_();_nop_(); _nop_(); _nop_(); _nop_();_nop_();_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); SPI_SCKHIGH; // RecevieData <<= 1; if(SPI_IN) { RecevieData |= 1; } _nop_(); _nop_(); _nop_();_nop_(); _nop_();_nop_(); _nop_(); _nop_(); _nop_();_nop_();_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); SPI_SCKLOW; } return RecevieData; } /* unsigned char SPI_SendData(unsigned charoutdata) { unsigned char RecevieData=0,i; SPDAT = outdata; //发送数据 while (!(SPSTAT & 0x80)); //查询完成标志 SPSTAT = 0xc0; //清中断标志 return SPDAT; } */ /* 函数名: enabled_cs 功能:SPI运动控制模块使能对应芯片模块的CS脚 参数: cardno 卡号 用单片机不同引脚去控制不同芯片的CS脚,以便多个芯片模块关联使用。 */ void enabled_cs(unsigned char cardno) { if(cardno==1) { SPI1_CSLOW; } if(cardno==2) { SPI2_CSLOW; } if(cardno==3) { SPI3_CSLOW; } } /* 函数名: disabled_cs 功能:SPI运动控制模块禁止对应芯片模块的CS脚 参数: cardno 卡号 用单片机不同引脚去控制不同芯片的CS脚,以便多个芯片关联使用。 */ void disabled_cs(unsigned char cardno) { if(cardno==1) { SPI1_CSHIGH; } if(cardno==2) { SPI2_CSHIGH; } if(cardno==3) { SPI3_CSHIGH; } } /* 函数名: set_speed 功能:设置轴速度 参数: cardno 卡号 axis 轴号(1,2,3,4) acc 加减速: 值(Hz/s2) speed 运行频率为:值(Hz) */ void set_speed(unsigned char cardno,unsigned char axis ,unsigned long acc ,unsigned long speed ) { unsigned char OutByte[25]; OutByte[0] = 1; OutByte[1] = 0; OutByte[2] = axis; OutByte[3] = acc >>24; OutByte[4] = acc >>16; OutByte[5] = acc >>8; OutByte[6] = acc ; OutByte[7] = speed >>24; OutByte[8] = speed >>16; OutByte[9] = speed >>8; OutByte[10] = speed ; enabled_cs(cardno); SPI_SendData(OutByte[0]); SPI_SendData(OutByte[1]); SPI_SendData(OutByte[2]); SPI_SendData(OutByte[3]); SPI_SendData(OutByte[4]); SPI_SendData(OutByte[5]); SPI_SendData(OutByte[6]); SPI_SendData(OutByte[7]); SPI_SendData(OutByte[8]); SPI_SendData(OutByte[9]); SPI_SendData(OutByte[10]); disabled_cs(cardno); delay_nms(1); } /* 函数名: set_command_pos 功能: 设置轴逻辑位置 参数: cardno 卡号 axis 轴号(1,2,3,4) pulse 位置脉冲数,范围(-268435455~+268435455) */ void set_command_pos(unsigned char cardno,unsigned char axis, long value ) { unsigned char OutByte[25]; OutByte[0] = 0x12 ; OutByte[1] = 0 ; OutByte[2] = axis ; OutByte[3] = value >>24; OutByte[4] = value >>16; OutByte[5] = value >>8; OutByte[6] = value ; enabled_cs(cardno); SPI_SendData(OutByte[0]); SPI_SendData(OutByte[1]); SPI_SendData(OutByte[2]); SPI_SendData(OutByte[3]); SPI_SendData(OutByte[4]); SPI_SendData(OutByte[5]); SPI_SendData(OutByte[6]); disabled_cs(cardno); delay_nms(1); } /* 函数名: sudden_stop 功能: 轴立即停止 参数: cardno 卡号 axis 停止的轴号(1,2,3,4) mode 0:急停并清空后面缓存的指令 2:急停不清后面缓存的指令 */ void sudden_stop(unsigned char cardno,unsigned char axis ,unsigned char mode) { unsigned char OutByte[25]; OutByte[0] = 0x17 ; OutByte[1] = axis ; OutByte[2] = mode; enabled_cs(cardno); SPI_SendData(OutByte[0]); SPI_SendData(OutByte[1]); SPI_SendData(OutByte[2]); disabled_cs(cardno); delay_nms(1); } /* 函数名: set_special 功能:设置特别功能 参数: cardno 卡号 value 0xfc 缓存插补运动暂停 0xfd 取消缓存插补暂停 */ void set_special(unsigned charcardno,unsigned char value) { unsigned char OutByte[25]; OutByte[0] = 0xFA ; OutByte[1] = 0; OutByte[2] = value; enabled_cs(cardno); SPI_SendData(OutByte[0]); SPI_SendData(OutByte[1]); SPI_SendData(OutByte[2]); disabled_cs(cardno); delay_nms(1); } /* 函数名: get_inp_state 功能: 获取轴状态,缓存剩余量,各轴逻辑位置。 参数: cardno 卡号 amount 获取字节数量。 设为20将取全部数据。 inbuf[] 读取的数据存放的数组 */ void get_inp_state( unsigned char cardno, unsigned char amount,unsigned charinbuf[]) { unsigned char OutByte[25]; char i; enabled_cs(cardno); inbuf[0]=SPI_SendData(0x04); for(i=1;i
{ inbuf=SPI_SendData(0); } disabled_cs(cardno); delay_nms(1); } /* 函数名: go_home 功能:回原点,回到原点开关会自动减速停止,随后离开原点开关自动急停 参数: cardno 卡号 no 轴号 speed1 进入原点速度,运行频率为:值(Hz) speed2 离开原点速度,运行频率为:值(Hz) */ void go_home(unsigned char cardno,unsignedchar no , long speed1 ,long speed2 ) { unsigned char OutByte[25]; OutByte[0] = 0x1a; OutByte[1] = 0; OutByte[2] = no; OutByte[3] = speed1>>24; OutByte[4] = speed1 >>16; OutByte[5] = speed1>> 8; OutByte[6] = speed1; OutByte[7] = speed2 >>24; OutByte[8] = speed2 >>16; OutByte[9] = speed2 >>8; OutByte[10] = speed2 ; enabled_cs(cardno); SPI_SendData(OutByte[0]); SPI_SendData(OutByte[1]); SPI_SendData(OutByte[2]); SPI_SendData(OutByte[3]); SPI_SendData(OutByte[4]); SPI_SendData(OutByte[5]); SPI_SendData(OutByte[6]); SPI_SendData(OutByte[7]); SPI_SendData(OutByte[8]); SPI_SendData(OutByte[9]); SPI_SendData(OutByte[10]); disabled_cs(cardno); delay_nms(1); } /* 函数名: inp_move4 功能:四轴直线插补 参数: cardno 卡号 no1 X轴轴号 no2 Y轴轴号 no3 Z轴轴号 no4 E轴轴号 pulse1,pulse2,pulse3,pulse4 X-Y-Z-E轴移动的距离,范围(-8388608~+8388607) mode 0:绝对位移 1:相对位移 */ void inp_move4(unsigned char cardno,unsignedchar no1 ,unsigned char no2 ,unsigned char no3 ,unsigned char no4, longpulse1 ,long pulse2 ,long pulse3 ,longpulse4 ,unsigned char mode ) { unsigned char OutByte[25]; OutByte[0] = 0xa; OutByte[1] = no1; OutByte[2] = no2; OutByte[3] = no3; OutByte[4] = no4; OutByte[5] = pulse1>>24; OutByte[6] = pulse1 >>16; OutByte[7] = pulse1>> 8; OutByte[8] = pulse1; OutByte[9] = pulse2 >>24; OutByte[10] = pulse2 >>16; OutByte[11] = pulse2 >>8; OutByte[12] = pulse2 ; OutByte[13] = pulse3 >>24; OutByte[14] = pulse3 >>16; OutByte[15] = pulse3 >>8; OutByte[16] = pulse3 ; OutByte[17] = pulse4 >>24; OutByte[18] = pulse4 >>16; OutByte[19] = pulse4 >>8; OutByte[20] = pulse4 ; OutByte[21] = 0 ; OutByte[22] = mode; enabled_cs(cardno); SPI_SendData(OutByte[0]); SPI_SendData(OutByte[1]); SPI_SendData(OutByte[2]); SPI_SendData(OutByte[3]); SPI_SendData(OutByte[4]); SPI_SendData(OutByte[5]); SPI_SendData(OutByte[6]); SPI_SendData(OutByte[7]); SPI_SendData(OutByte[8]); SPI_SendData(OutByte[9]); SPI_SendData(OutByte[10]); SPI_SendData(OutByte[11]); SPI_SendData(OutByte[12]); SPI_SendData(OutByte[13]); SPI_SendData(OutByte[14]); SPI_SendData(OutByte[15]); SPI_SendData(OutByte[16]); SPI_SendData(OutByte[17]); SPI_SendData(OutByte[18]); SPI_SendData(OutByte[19]); SPI_SendData(OutByte[20]); SPI_SendData(OutByte[21]); SPI_SendData(OutByte[22]); disabled_cs(cardno); delay_nms(1); } /* 函数名: inp_arc 功能:二轴圆弧插补 参数: cardno 卡号 no1 参与插补X轴的轴号 no2 参与插补Y轴的轴号 x,y 圆弧插补的终点位置(相对于起点),范围(-8388608~+8388607) i,j 圆弧插补的圆心点位置(相对于起点),范围(-8388608~+8388607) mode1 0:逆时针插补 1:顺时针插补 mode2 0:绝对位移 1:相对位移 */ void inp_arc(unsigned char cardno ,unsignedchar no1,unsigned char no2, long x , long y, long i, long j,unsigned charmode1,unsigned char mode2 ) { unsigned char OutByte[25]; OutByte[0] = 0xc; OutByte[1] = no1; OutByte[2] = no2; OutByte[3] = x >>24; OutByte[4] = x >>16; OutByte[5] = x >>8; OutByte[6] = x ; OutByte[7] = y >>24; OutByte[8] = y >>16; OutByte[9] = y >>8; OutByte[10] = y ; OutByte[11] = i >>24; OutByte[12] = i >>16; OutByte[13] = i >>8; OutByte[14] = i ; OutByte[15] = j >>24; OutByte[16] = j >>16; OutByte[17] = j >>8; OutByte[18] = j ; OutByte[19] = mode1; OutByte[20] = mode2; enabled_cs(cardno); SPI_SendData(OutByte[0]); SPI_SendData(OutByte[1]); SPI_SendData(OutByte[2]); SPI_SendData(OutByte[3]); SPI_SendData(OutByte[4]); SPI_SendData(OutByte[5]); SPI_SendData(OutByte[6]); SPI_SendData(OutByte[7]); SPI_SendData(OutByte[8]); SPI_SendData(OutByte[9]); SPI_SendData(OutByte[10]); SPI_SendData(OutByte[11]); SPI_SendData(OutByte[12]); SPI_SendData(OutByte[13]); SPI_SendData(OutByte[14]); SPI_SendData(OutByte[15]); SPI_SendData(OutByte[16]); SPI_SendData(OutByte[17]); SPI_SendData(OutByte[18]); SPI_SendData(OutByte[19]); SPI_SendData(OutByte[20]); disabled_cs(cardno); delay_nms(100); } /* 函数名: inp_helical 功能:圆弧螺旋插补 参数: cardno 卡号 no1 参与插补X轴的轴号 no2 参与插补Y轴的轴号 no3 参与插补螺旋轴的轴号 x,y 圆弧插补的终点位置(相对于起点),范围(-8388608~+8388607) z 参与插补螺旋轴的位置(相对于起点) i,j 圆弧插补的圆心点位置(相对于起点),范围(-8388608~+8388607) mode1 0:逆时针插补 1:顺时针插补 mode2 0:绝对位移 1:相对位移 */ void inp_helical(unsigned char cardno,unsigned char no1,unsigned char no2,unsigned char no3,long x , long y,long z,long i, long j,unsigned char mode1,unsigned char mode2 ) { unsigned char OutByte[30]; OutByte[0] = 0xd; OutByte[1] = no1; OutByte[2] = no2; OutByte[3] = no3; OutByte[4] = x >>24; OutByte[5] = x >>16; OutByte[6] = x >>8; OutByte[7] = x ; OutByte[8] = y >>24; OutByte[9] = y >>16; OutByte[10] = y >>8; OutByte[11] = y ; OutByte[12] = z >>24; OutByte[13] = z >>16; OutByte[14] = z >>8; OutByte[15] = z ; OutByte[16] = i >>24; OutByte[17] = i >>16; OutByte[18] = i >>8; OutByte[19] = i ; OutByte[20] = j >>24; OutByte[21] = j >>16; OutByte[22] = j >>8; OutByte[23] = j ; OutByte[24] = mode1; OutByte[25] = mode2; enabled_cs(cardno); SPI_SendData(OutByte[0]); SPI_SendData(OutByte[1]); SPI_SendData(OutByte[2]); SPI_SendData(OutByte[3]); SPI_SendData(OutByte[4]); SPI_SendData(OutByte[5]); SPI_SendData(OutByte[6]); SPI_SendData(OutByte[7]); SPI_SendData(OutByte[8]); SPI_SendData(OutByte[9]); SPI_SendData(OutByte[10]); SPI_SendData(OutByte[11]); SPI_SendData(OutByte[12]); SPI_SendData(OutByte[13]); SPI_SendData(OutByte[14]); SPI_SendData(OutByte[15]); SPI_SendData(OutByte[16]); SPI_SendData(OutByte[17]); SPI_SendData(OutByte[18]); SPI_SendData(OutByte[19]); SPI_SendData(OutByte[20]); SPI_SendData(OutByte[21]); SPI_SendData(OutByte[22]); SPI_SendData(OutByte[23]); SPI_SendData(OutByte[24]); SPI_SendData(OutByte[25]); disabled_cs(cardno); delay_nms(1); } /* 函数名: write_bit 功能:写输出口状态 参数: cardno 卡号 number 端口号(0-6) Y0-Y6 value 状态(0,1) 0 输出低电平 1 输出高电平 */ void write_bit(unsigned char cardno ,unsigned char number, unsigned char value) { unsigned char OutByte[25]; OutByte[0] = 0x03 ; OutByte[1] = number; OutByte[2] = value; enabled_cs(cardno); SPI_SendData(OutByte[0]); SPI_SendData(OutByte[1]); SPI_SendData(OutByte[2]); disabled_cs(cardno); delay_nms(1); } /* 函数名: wait_delay 功能:等待延时数 参数: cardno 卡号 value 延时量(1-10000)MS */ void wait_delay(unsigned char cardno,unsigned int value) { unsigned char OutByte[25]; OutByte[0] = 0x0e ; OutByte[1] = value>>8; OutByte[2] = value; enabled_cs(cardno); SPI_SendData(OutByte[0]); SPI_SendData(OutByte[1]); SPI_SendData(OutByte[2]); disabled_cs(cardno); delay_nms(1); } /* 函数名: pmove 功能: e版本单轴运行 参数: cardno 卡号 axis 轴号 mode 0:绝对位移 1:相对位移 pulse1 X轴移动的距离,范围(-8388608~+8388607) */ void pmove(unsigned char cardno,unsignedchar axis,unsigned char mode, long pulse1 ) { unsigned char OutByte[25]; OutByte[0] = 0x2; OutByte[1] = axis ; OutByte[2] = mode; OutByte[3] = pulse1>>24; OutByte[4] = pulse1 >>16; OutByte[5] = pulse1>>8; OutByte[6] = pulse1; enabled_cs(cardno); SPI_SendData(OutByte[0]); SPI_SendData(OutByte[1]); SPI_SendData(OutByte[2]); SPI_SendData(OutByte[3]); SPI_SendData(OutByte[4]); SPI_SendData(OutByte[5]); SPI_SendData(OutByte[6]); disabled_cs(cardno); delay_nms(1); } /* 函数名: wait_stop 功能: e版本等待轴停止 参数: cardno 卡号 axis 停止的轴号(1,2,3,4) mode 0:急停并清空后面缓存的指令 2:急停不清后面缓存的指令 */ void wait_stop(unsigned char cardno ,unsignedchar axis) { unsigned char OutByte[25]; OutByte[0] = 0xf ; OutByte[1] = axis ; enabled_cs(cardno); SPI_SendData(OutByte[0]); SPI_SendData(OutByte[1]); disabled_cs(cardno); delay_nms(1); } void main(void) { initial(); init_uart(); //ES = 1; //EA = 1; //P_SW2 = 0x80; //XOSCCR = 0xc0; //启动外部晶振 //while (!(XOSCCR & 1)); //等待时钟稳定 //CKDIV = 0x00; //时钟不分频 //CKSEL = 0x01; //选择外部晶振 //P_SW2 = 0x00; led=0; delay_nms(100) ; /*下面的指令为1,2轴回原点 go_home(1,1,30000,5000 ) ; // 1轴回原点 go_home(1,2,30000,5000 ) ; // 2轴回原点 do { get_inp_state( 1, 4,inbuf); //只需读出4个字节来判断轴状态 } while(inbuf[3]); // 等待缓存数量为0 ,如果多条运动指令在缓存里 ,可以读取缓存数量来判断指令有没执行完成。 //while(inbuf[1]); // 等待轴停止,如果只有一条除圆弧外的运动指令,可以读取轴状态来判断有没执行完。 set_command_pos(1,1,0); //设1轴坐标 set_command_pos(1,2,0); //设2轴坐标 */ while(1) { if(!b1) //按下按键 { delay_nms(10); if(!b1) { /*e型测试指令*/ // set_speed(1 ,1,200000,50000); //设置1轴运行速度50K,加速度200k // set_speed(1 ,2,200000,50000); //设置1轴运行速度50K,加速度200k // set_speed(1 ,3,40000,10000); //设置1轴运行速度10K,加速度40k //write_bit(1 , 6, 0); // Y6输出低 // pmove(1,1,1, 1000); //1轴相对运行速1000个脉冲 // pmove(1,2,1, 1000); // 2轴相对运行速1000个脉冲 //wait_stop(1 ,1); //等待1轴停止 //wait_stop(1 ,2); //等待2轴停止 // wait_delay(1 ,500); // 延时500MS // pmove(1,3,1, 1000); //3轴相对运行速1000个脉冲 //write_bit(1 , 6, 1); // Y6输出高 /*f型测试指令*/ // write_bit(1 , 6, 0); // set_speed(1 ,1,200000,50000); //设置运行速度50K,加速度200h // wait_delay(1 ,500); // 延时500MS // write_bit(1, 2, 0); // inp_move4(1,1,0,0,0,80000 ,0,0 ,0 ,1); // 1,2轴插补 // set_speed(1,1 ,800000,25000); //设置运行速度25K,加速度800K //inp_move4(1,1,2,0,0,20000 ,10000,0 ,0,1); // 1,2轴插补 // inp_arc(1 ,1,2, -20000, 20000, -20000, 0,0,1); // 1,2轴圆弧插补 //set_speed(1,1,800000,25000); //设置运行速度250K,加速度800K // inp_arc(1 ,1,2, -20000, 20000, -20000,0,0,1) ; // wait_delay(1 ,500); // write_bit(1, 6, 1); // wait_delay(1 ,500); // write_bit(1 , 6, 0); /*下面的指令会直接发到缓存区自动排队运行*/ // write_bit(1 , 6, 0); // Y6输出低 // set_speed(1,1,40000,25000); //inp_move4(1,1,2,3,4,320000 ,32000,32000 ,32000 ,1); // 4轴直线插补 //wait_delay(1 ,2000); //模块内部指令间延时3S //inp_move4(1,1,2,0,0,32000 ,32000,0 ,0,1); // 1,2轴直线插补 // wait_delay(1 ,2000); // inp_move4(1,2,0,0,0,32000 ,0,0 ,0 ,1); // 2轴单独运行 //inp_arc(1 ,1,2, -20000, 20000, -20000, 0,0,1) ; // 2轴圆弧插补,终点相对起点坐标(-20000,20000),圆心相对起点坐标(-20000,0),逆时针方向,画出1/4圆弧。 // write_bit(1, 6, 1); // Y6输出高 ,判断指令段有没执行完成也可以在指令段后面加一条端口输出指令,然后用单片机来读引脚来判断。 while(!b1); } } if(!b2) //按下按键 { delay_nms(10) ; if(!b2) { sudden_stop(1,1,0); // f型立即停止所有插补轴,并清缓存 。 e型立即停止1轴 ,并清缓存 。 while(!b2); } } get_inp_state( 1, 20,inbuf); //读出20个字节数据放入数组 //USRAT_transmit(inbuf,20); // 串口将数组数据发送出去查看 ////USART_Txbyte(inbuf[3]); if(inbuf[3]==0) //inbuf[1]数据为0表示所有轴都停 led=1; else led=0; // 指示LED点亮 } }
|
||||||||||
相关推荐
|
||||||||||
好东西,值得分享
|
|
|
|
|
|
学习了
|
|
|
|
|
|
两轴SPI通讯TSSOP20封装运动控制芯片mpc02t的程序
#include //-----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; ////////////////// ***it s1 = P1^6; ***it s2 = P1^7; ***it b1 = P3^7; ***it cs2 = P1^4; ***it cs = P1^3; ***it sck = P1^2; ***it out = P1^0; ***it in = P1^1; #define SPI2_CSHIGH cs2=1 // CS2 #define SPI2_CSLOW cs2=0 #define SPI_CSHIGH cs=1 // CS #define SPI_CSLOW cs=0 #define SPI_SCKHIGH sck=1 //SCLK #define SPI_SCKLOW sck=0 #define SPI_OUTHIGH out=1 #define SPI_OUTLOW out=0//MOSI #define SPI_IN in//MISO unsigned char inbuf[12]; void initial() { SPI_CSHIGH; SPI2_CSHIGH; } void delay_nus(unsigned long n) { unsigned long j; while(n--) { j=8; while(j--); } } //延时n ms void delay_nms(unsigned long n) { while(n--) delay_nus(1100); } /* 函数名: SPI_SendData 功能:软件模拟SPI通讯发送并接收一个8位字节数据。 */ unsigned char SPI_SendData(unsigned char outdata) { unsigned char RecevieData=0,i; for(i=0;i<8;i++) { SPI_SCKLOW; if(outdata&0x80) { SPI_OUTHIGH; } else { SPI_OUTLOW; } outdata<<=1; __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); SPI_SCKHIGH; RecevieData <<= 1; if(SPI_IN) { RecevieData |= 1; } __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); SPI_SCKLOW; } return RecevieData; } /* 函数名: enabled_cs 功能:使能对应芯片的CS脚 参数: cardno 卡号 用单片机不同引脚去控制不同芯片的CS脚,以便多个芯片关联使用。 */ void enabled_cs(unsigned char cardno) { if(cardno==1) { SPI_CSLOW; } else if(cardno==2) { SPI2_CSLOW; } } /* 函数名: disabled_cs 功能:禁止对应芯片的CS脚 参数: cardno 卡号 用单片机不同引脚去控制不同芯片的CS脚,以便多个芯片关联使用。 */ void disabled_cs(unsigned char cardno) { if(cardno==1) { SPI_CSHIGH; } else if(cardno==2) { SPI2_CSHIGH; } } /* 函数名: set_speed 功能:设置轴速度 参数: cardno 卡号 axis 轴号(1-6) acc 加速时间(ms) dec 减速时间(ms) startv 启动频率为:值*频率倍率(Hz) speed 运行频率为:值*频率倍率(Hz) range 频率倍率(1-100) */ unsigned char set_speed(unsigned char cardno ,unsigned char axis ,unsigned int acc ,unsigned int dec ,unsigned int startv ,unsigned int speed ,unsigned char range) { unsigned char OutByte[25]; OutByte[0] = 1; OutByte[1] = axis; OutByte[2] = acc >>8; OutByte[3] = acc ; OutByte[4] = dec >>8; OutByte[5] = dec ; OutByte[6] = startv >>8; OutByte[7] = startv ; OutByte[8] = speed >>8; OutByte[9] = speed ; OutByte[10] = range; enabled_cs(cardno); SPI_SendData(OutByte[0]); SPI_SendData(OutByte[1]); SPI_SendData(OutByte[2]); SPI_SendData(OutByte[3]); SPI_SendData(OutByte[4]); SPI_SendData(OutByte[5]); SPI_SendData(OutByte[6]); SPI_SendData(OutByte[7]); SPI_SendData(OutByte[8]); SPI_SendData(OutByte[9]); SPI_SendData(OutByte[10]); disabled_cs(cardno); } /* 函数名: pmove 功能:单轴运行 参数: cardno 卡号 axis 轴号(1-2) pulse 输出的脉冲数 >0:正方向移动 <0:负方向移动 范围(-268435455~+268435455) mode 0:相对位移 1:绝对位移 2:连续位移 */ unsigned char pmove(unsigned char cardno ,unsigned char axis,long pulse , unsigned char mode) { unsigned char OutByte[25]; OutByte[0] = 2 ; OutByte[1] = axis; OutByte[2] = pulse >>24; OutByte[3] = pulse >>16; OutByte[4] = pulse >>8; OutByte[5] = pulse ; OutByte[6] = mode ; enabled_cs(cardno); SPI_SendData(OutByte[0]); SPI_SendData(OutByte[1]); SPI_SendData(OutByte[2]); SPI_SendData(OutByte[3]); SPI_SendData(OutByte[4]); SPI_SendData(OutByte[5]); SPI_SendData(OutByte[6]); SPI_SendData(0); disabled_cs(cardno); } /* 函数名: set_command_pos 功能: 设置轴逻辑位置 参数: cardno 卡号 axis 轴号(1-2) pulse 位置脉冲数,范围(-268435455~+268435455) */ unsigned char set_command_pos(unsigned char cardno ,unsigned char axis, long value ) { unsigned char OutByte[25]; OutByte[0] = 0x12 ; OutByte[1] = axis ; OutByte[2] = value >>24; OutByte[3] = value >>16; OutByte[4] = value >>8; OutByte[5] = value ; enabled_cs(cardno); SPI_SendData(OutByte[0]); SPI_SendData(OutByte[1]); SPI_SendData(OutByte[2]); SPI_SendData(OutByte[3]); SPI_SendData(OutByte[4]); SPI_SendData(OutByte[5]); disabled_cs(cardno); } /* 函数名: sudden_stop 功能: 轴停止 参数: cardno 卡号 axis 停止的轴号(1-2) 1-2:1-2轴停 */ unsigned char sudden_stop(unsigned char cardno ,unsigned char axis) { unsigned char OutByte[25]; OutByte[0] = 0x17 ; OutByte[1] = axis ; enabled_cs(cardno); SPI_SendData(OutByte[0]); SPI_SendData(OutByte[1]); disabled_cs(cardno); } /* 函数名: get_command_pos 功能: 获取轴逻辑位置或状态。 本函数先发一条指令过去让芯片准备相应的数据,等待1MS后,再从芯片读取4个字节的相应数据。 参数: cardno 卡号 axis 轴号 1,1轴 2,2轴 100,会返回两个轴的状态。0位为第一轴状态。1位为第二轴状态。0表示停止中,1表示运行中。 返回值: 位置脉冲数,范围(-268435455~+268435455)或者两个轴的状态 */ long get_command_pos( unsigned char cardno, unsigned char axis) { unsigned char OutByte[25]; unsigned char inbuf[12]; long tmp=0; OutByte[0] = 0x06; OutByte[1] = axis ; enabled_cs(cardno); SPI_SendData(OutByte[0]); SPI_SendData(OutByte[1]); disabled_cs(cardno); delay_nms(1); enabled_cs(cardno); inbuf[0]=SPI_SendData(0); inbuf[1]=SPI_SendData(0); inbuf[2]=SPI_SendData(0); inbuf[3]=SPI_SendData(0); disabled_cs(cardno); delay_nms(1); tmp= (long)inbuf[0]<<24; tmp+= (long)inbuf[1]<<16; tmp+= (long)inbuf[2]<<8; tmp+= (long)inbuf[3]; return tmp; //return(((long)inbuf[0]<<24)+((long)inbuf[1]<<16)+((long)inbuf[2]<<8)+((long)inbuf[3])); } /* 函数名: set_special 功能:设置特别功能 参数: cardno 卡号(1-128)芯片地址 value 0xf1 停止时缓慢 0xf2 停止时急速 0xfa 重新启动 0xfb 急停 */ unsigned char set_special(unsigned char cardno,unsigned char value) { unsigned char OutByte[25]; OutByte[0] = 0xFA ; OutByte[1] = value; enabled_cs(cardno); SPI_SendData(OutByte[0]); SPI_SendData(OutByte[1]); disabled_cs(cardno); } void main(void) { initial(); set_speed(1 ,1,1000,1000,10,200,100); // 设1轴速度 set_speed(1 ,2,1000,1000,10,200,100); // 设2轴速度 /*1轴2轴回原点*/ pmove(1,1,-1000000,0); // 1轴多脉冲负方向运动 pmove(1,2,-1000000,0); // 2轴多脉冲负方向运动 while(s1); //检测1轴状态引脚电平,如变低表示已停,且在原点 while(s2); //检测2轴状态引脚电平,如变低表示已停,且在原点 //while(get_command_pos(1, 100)) ; //通过指令也能获取各轴状态 ,与S1,S2两个状态指示输入口功能相同。 set_command_pos(1,1,0); // 设1轴此时坐标为0 set_command_pos(1,2,0); // 设2轴此时坐标为0 while(1) { if((!b1)&&(!s1))//按键按下 ,并且1轴停止状态 { pmove(1,1,32000,0); // 1轴正向运动 32000个脉冲 while(!b1); } if((!b1)&&(inbuf[0]>0))//按键按下, 并且1轴在运动中 { sudden_stop(1,1); // 1轴停止 while(!b1); } } } |
|
|
|
|
|
楼主的东西很好,我要收藏下,谢谢
|
|
|
|
|
|
谢谢楼主分享,学习学习了
|
|
|
|
|
|
2491 浏览 1 评论
1523 浏览 0 评论
3255 浏览 1 评论
【⌈嵌入式机电一体化系统设计与实现⌋阅读体验】+磁力输送机系统设计的创新与挑战
1721 浏览 0 评论
4185 浏览 2 评论
浏览过的版块 |
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-14 00:10 , Processed in 0.926314 second(s), Total 77, Slave 66 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号