Xc1004四軸SPI運動控制芯片?
?
參
考
手
冊
?
? ?概述
?? SPI通訊,僅需使用10條指令便可完成復雜工作。
單芯片四軸輸出,多個芯片通過不同片選腳可控制達120軸。
獨立軸e版本支持最大脈沖輸出頻率1.2MHz獨立輸出。
插補軸f版本支持四軸,三軸,二軸,一軸直線插補,二軸圓弧插補,螺旋插補,支持連續插補,支持速度前瞻。
脈沖輸出使用脈沖+方向方式。
各版本擁有128條運動指令緩存空間。
LQFP48封裝,引腳輸入輸出3.3V,可兼容5V。
?
性能參數
?
溫度范圍 |
-40 ~ +105℃ |
封裝 |
LQFP48 |
IO輸入 |
3.3v ,兼容5v |
IO輸出 |
3.3v ? TTL輸出 |
控制軸數 |
? 4軸 |
脈沖頻率 |
??e版:1.2MHZ?? ??f版:400kHZ?? |
運動性能 |
e版:單軸運行,指令緩存 f版:1-4軸直線插補 ,圓弧插補,螺旋插補,支持指令緩存,支持連續插補 |
通信速度 |
SPI:10Mbps |
?
?
?
引腳排列
?
引腳號 |
引腳名稱 |
引腳功能說明 |
1 |
VDD |
電源正極+3.3V |
2 |
Y4 |
4號輸出口 |
3 |
Y5 |
5號輸出口 |
4 |
Y6 |
6號輸出口 |
5 |
A |
空引腳 |
6 |
B |
空引腳 |
7 |
RST |
復位引腳,低電平有效 |
8 |
VSS |
電源負極 |
9 |
VDD |
電源正極+3.3V |
10 |
LMT1- |
1軸負限位或原點,低電平有效 |
11 |
LMT2- |
2軸負限位或原點,低電平有效 |
12 |
LMT3- |
3軸負限位或原點,低電平有效 |
13 |
LMT4- |
4軸負限位或原點,低電平有效 |
14 |
LMT1+ |
1軸正限位,低電平有效 |
15 |
LMT2+ |
2軸正限位,低電平有效 |
16 |
LMT3+ |
3軸正限位,低電平有效 |
17 |
LMT4+ |
4軸正限位,低電平有效 |
18 |
STOP |
急停引腳,低電平有效 |
19 |
NC |
空引腳 |
20 |
VSS |
電源負極 |
21 |
Y0 |
0號輸出口 |
22 |
Y1 |
1號輸出口 |
23 |
VSS |
電源負極 |
24 |
VDD |
電源正極+3.3V |
25 |
CS |
SPI通信使能腳,低電平有效 |
26 |
SCK |
SPI通信時鐘腳 |
27 |
SO |
SPI通信數據輸出腳,接單片機數據輸入腳 |
28 |
SI |
SPI通信數據輸入腳,接單片機數據輸出腳 |
29 |
P1 |
第1軸脈沖信號 |
30 |
TXD |
串口數據發送 |
31 |
RXD |
串口數據接收 |
32 |
D1 |
第1軸方向信號 |
33 |
Y2 |
2號輸出口 |
34 |
Y3 |
3號輸出口 |
35 |
VSS |
電源負極 |
36 |
VDD |
電源正極+3.3V |
37 |
SIGN |
工作狀態指示,閑時慢速交替變化,軸運行時快速交替變化 |
38 |
P2 |
第2軸脈沖信號 |
39 |
D2 |
第2軸方向信號 |
40 |
P3 |
第3軸脈沖信號 |
41 |
D3 |
第3軸方向信號 |
42 |
NC |
空引腳 |
43 |
NC |
空引腳 |
44 |
VSS |
電源負極 |
45 |
P4 |
第4軸脈沖信號 |
46 |
D4 |
第4軸方向信號 |
47 |
VSS |
電源負極 |
48 |
VDD |
電源正極+3.3V |
?
SPI通訊協議
?
芯片與單片機使用SPI通訊,單片機作為主機,芯片為從機。CPHA=0,CPOL=0,高位在前,SPI數據寬度為8位。空閑狀態下單片機SCK引腳必須為低電平。每一條指令開始發送前將CS引腳置低,整條指令發送完成后必須將CS置高。
每條指令間隔1MS以上。
?
SPI時序圖如下:
?
SPI通訊指令
?
◆設置軸速度(e版本f版本共用指令)
?
發送:
功能碼 |
補充0 |
軸號 |
加速度 |
運行速度 |
0x01 |
0x00 |
1字節 |
4字節 |
4字節 |
?
部分參數解釋:
軸號(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版本共用指令)
?
發送:
?
功能碼 |
補充0 |
軸號 |
位置 |
0x12 |
0x00 |
1字節 |
4字節 |
?
部分參數解釋:
軸號(1,2,3,4)?? 1-4:1-4軸
位置????? 軸邏輯位置,范圍(-268435455~+268435455)
?
?
◆軸停止(e版本f版本共用指令)
發送:
?
功能碼 |
軸號 |
模式 |
0x17 |
1字節 |
1字節 |
??? ??
部分參數解釋:
?
軸號(1,2,3,4)?? ??? 1-4: 1-4軸?
模式(0,1,2) ???????0:急停并清空后面緩存的指令? ?1:減速停不清空后面緩存的指令 ???2:急停不清空后面緩存的指令
要點:f版本由于共用一個插補核心,軸號設為任意值都會讓所用軸停止。
?
◆獲取各軸邏輯位置和狀態(e版本f版本共用指令)
發送:
?
功能碼 |
數據0 |
0x04 |
最多19個字節 |
????????
返回:
起始碼 |
各軸運行狀態 |
緩存數量 |
1軸坐標 |
2軸坐標 |
3軸坐標 |
4軸坐標 |
0x00 |
1字節 |
2字節 |
4字節 |
4字節 |
4字節 |
4字節 |
?
部分參數解釋:
?
?
各軸運行狀態(轉為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版本專用指令)
?
發送:
?
功能碼 |
補充0 |
功能 |
0xfa |
0x00 |
1字節 |
?
?
?
部分參數解釋:
?
當功能寫入0xfc,緩存內運動指令暫停。
當功能寫入0xfd,取消緩存內運動指令暫停。
以下指令會自動進入緩存區并排隊執行:
?
◆ 回原點(e版本f版本共用指令)
發送:
?
功能碼 |
補充0 |
軸號 |
進入原點速度 |
離開原點速度 |
0x1a |
0x00 |
1字節 |
4字節 |
4字節 |
?
?
?
?
?
部分參數解釋:
?
軸號(1,2,3,4)
?
進入原點速度? 運行頻率為:值(1-400000)(Hz)
?
離開原點速度? 運行頻率為:值(1-400000)(Hz)
?
要點:回原點指令會自動生成一段負脈沖和一段正脈沖。以進入原點速度輸出負脈沖時,左限位原點開關生效時自動減速停;隨后以離開原點速度輸出正脈沖,離開原點限位開關時自動急速停止,急停后可作為原點。回原點指令不宜和其它運動指令混合在一起放入緩存里,回原點過程應單獨存在。
?
?
◆ 四軸直線插補(f版本專用指令)
發送:
?
?
功能碼 |
X軸號 |
Y軸號 |
Z軸號 |
E軸號 |
X脈沖數 |
Y脈沖數 |
Z脈沖數 |
E脈沖數 |
補充0 |
運動方式 |
0x0a |
1字節 |
1字節 |
1字節 |
1字節 |
4字節 |
4字節 |
4字節 |
4字節 |
0x00 |
1字節 |
?
?
部分參數解釋:
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軸號 |
Y軸號 |
終點坐標X |
終點坐標Y |
圓心坐標X |
圓心坐標Y |
運動方式1 |
運動方式2 |
0x0c |
1字節 |
1字節 |
4字節 |
4字節 |
4字節 |
4字節 |
1字節 |
1字節 |
?
?
?
?
部分參數解釋:
X軸號(1,2,3)
Y軸號(1,2,3)
終點坐標? ???????圓弧插補的終點位置,范圍(-268435455~+268435455)
圓心坐標 ????????圓弧插補的圓心點位置,范圍(-268435455~+268435455)
運動方式1 ???????0:逆時針插補?? 1:順時針插補?? 2:三點定圓弧
運動方式2?? ?????0:絕對位移? 1:相對位移?
?
要點:圓弧各坐標必須能構成正常的圓弧。圓弧插補指令會根據圓弧參數動態占用緩存空間。當運動方式1設為2時,為三點定圓弧模式,圓心坐標參數設為圓弧的中間點坐標。
?
?
◆ 三軸螺旋插補(f版本專用指令)
發送:
?
功能碼 |
X軸號 |
Y軸號 |
Z軸號 |
終點坐標X |
終點坐標Y |
脈沖數 |
圓心坐標X |
圓心坐標Y |
運動方式1 |
運動方式2 |
0x0d |
1字節 |
1字節 |
1字節 |
4字節 |
4字節 |
字節 |
4字節 |
4字節 |
1字節 |
1字節 |
?
?
部分參數解釋:
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版本共用指令)
?
發送:
?
功能碼 |
延時量 |
0x0e |
2字節 |
?
?
部分參數解釋:
?
延時量(1-10000)MS
?
要點:等待延時是指等待所設延時量后才執行后面的指令。
?
?
◆寫輸出口狀態(e版本f版本共用指令)
發送:
?
功能碼 |
輸出端口號 |
輸出狀態 |
0x03 |
1字節 |
1字節 |
?
?
部分參數解釋:
?
輸出端口號?? (0-6)??? Y0-Y6
輸出狀態???? (0,1)?? ?0:輸出低電平?? 1:輸出高電平
?
?
◆ 單軸運行(e版本專用指令)
?
發送:
功能碼 |
軸號 |
運動方式 |
脈沖數量 |
0x02 |
1字節 |
1字節 |
4字節 |
?
?
部分參數解釋:
?
軸號(1,2,3,4)??? 獨立軸運動的軸號
脈沖數量 (-268435455~+268435455)輸出的脈沖數 >0:正方向移動? ?<0:負方向移動
運動方式(0,1)?? 0:絕對位移? 1:相對位移??
?
?
◆等待軸停止(e版本專用指令)
發送:
?
功能碼 |
軸號 |
0x0f |
1字節 |
?
?
部分參數解釋:
?
軸號(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波特率
?
sbit b2??? =?? P1^1;
sbit b1??? =?? P5^5;
sbit led?? =?? P3^5;
?
sbit cs3?? ?= P3^3;
sbit cs2?? ?= P3^2;
sbit cs1?? ?= P1^2;
sbit sck = P1^5;
sbit in??? ?= P1^4;
sbit 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;
?
?void initial()
{
?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;
??
}
?
?
?
/*
串口發送一個字節。
*/
?void USART_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[i]);?????
?? }
??
}??
?
?
?
?void delay_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 char outdata)
{
?
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 char outdata)
{
?
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 char cardno,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 char inbuf[])
{??
unsigned char OutByte[25];
?
char i; ??
enabled_cs(cardno);
inbuf[0]=SPI_SendData(0x04);
for(i=1;i
{??
inbuf[i]=SPI_SendData(0);
?
}
disabled_cs(cardno);
delay_nms(1);
???
?
}
?
?
/*
函數名:??? ?go_home
功能:回原點,回到原點開關會自動減速停止,隨后離開原點開關自動急停
參數:
cardno ??? 卡號
no?? 軸號
speed1????? 進入原點速度,運行頻率為:值(Hz)
speed2????? 離開原點速度,運行頻率為:值(Hz)
*/
?
void go_home(unsigned char cardno,unsigned char 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,unsigned char no1 ,unsigned char no2 ,unsigned char no3 ,unsigned char no4, long pulse1? ,long pulse2 ,long pulse3 ,long pulse4 ,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 ,unsigned char no1,unsigned char no2, long x , long y, long i, long j,unsigned char mode1,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,unsigned char 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 ,unsigned char 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點亮
?
?
?
??? ?}? ??
???
}