新聞詳情
單片機控制步進電機瀏覽數:3次
采用單片機stc89C2051和mpc006運動控制芯片模塊作為控制系統的核心,控制三路步進電機做運動實驗。單片機發送指令給mpc006微型運動控制模塊,模塊信號輸出給步進驅動器作高速度運動。可以定點運動,直線插補和圓弧插補。 1.引言 運動控制的應用在國內已有十幾年的歷史,技術也相當成熟。通常運動控制都需要用到運動控制卡, 運動控制器等產品,但這些產品價格高昂,使用復雜,也不適合由單片機構成的控制系統。而如果直接采 用單片機來做運動控制,由于運動控制對系統性能要求非常高,單片機速度資源有限,難以設計出性能優 良的運動控制模型。因此,本文采用單片機和專業的 mpc006 運動控制芯片模塊構成運動控制系統。 MPC006 運動控制芯片模塊采用新型 FPGA 設計,集成實用運動控制功能,可與普通單片機通過串口通訊 對步進電機和伺服電機控制。具有如下特點: ◆ 串口通訊,僅需使用幾條指令,簡單可靠。 ◆ 單模塊最高六軸輸出,多個模塊組網工作可達 120 軸。 ◆ 最大脈沖輸出頻率為 2MHz,脈沖輸出使用脈沖+方向方式。 ◆ 最高六軸獨立運動控制,任意兩軸直線插補,任意兩軸圓弧插補。 ◆ 每軸一路硬件回原點。 ◆ 模塊帶 1000 條指令緩存深度,指令先進先出,無需高速通訊。 ◆ 模塊體積小巧,僅 3.5*2.5*1.5cm,雙排直插 30 腳封裝。 硬件系統由四部分構成: (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 晶體管及電極開路輸出,分別接到電機驅動器脈沖和方向信號輸入端。 MPC006 運動控制芯片模塊與單片機串口通訊速率為 115200bps,數據位為 8 位,停止位 1 位,無校驗。單片機與 mpc006 運動控制模塊采用串口應答式通訊,單片機作主機,單片機每發送一條指令給 mpc006運動控制芯片模塊,mpc006 運動控制芯片模塊返回以 0x68 開始的固定長度為 10 個字節的數據串。單片即可以取出需要的數據。一般情況需接收到 mpc006 運動控制模塊返回的數據后單片機才能發送下一條指令。如果程序中不接收模塊返回的數據,需間隔 5MS 以上才能發送下一條指令。另外需注意,當發送指令時如果字節間時間間隔大于 1MS,模塊會認為整條指令發送結束,所以在發送一條指令給模塊時不要被程序里的中斷長時間打斷。當接收模塊的返回的數據時,由于波特率很高,如果有長時間中斷打斷接收過程,可能會導致接收字節丟失。所以,通訊時最好能暫時關閉其它太占時長中斷。mpc 運動控制模塊帶 1000條指令緩存空間,并自帶基本邏輯判斷能力,單片機不用等待一條執行完成后才發送下一條,完全可以一起發送給模塊,模塊會按順序自動逐條執行。 單片機發送和接收指令的數據格式如下: 起始碼:為一條指令的起始字節內容,固定為 0x68。 數據個數:為從數據個數開始到校驗和的數據長度。 模塊地址:為控制器的通訊地址。地址 0 對所有控制器都有效。 功能碼:表示指令的功能,每條指令的功能碼都是唯一的。 參數:表示指令的參數,每條指令的參數字節數并不都是相同的。 校驗和:為從數據個數開始到校驗和前一個字節的校驗和。 mpc006 運動控制芯片模塊默認地址為 0,可以接收帶任何地址的指令數據。如果單片機串口只連接了一個模塊,地址可以不用設置。 mpc006 運動控制芯片模塊無需任何初始化。上電后只發一條 pmove 單軸運行指令對應軸都會有脈沖輸出。使用函數前先設置好單片機的串口功能,并將需要用到的函數的原型拷貝到當前程序內。本文所使用的函數原型為基礎版本,已根據模塊使用說明書中通訊協議將各指令通訊過程描述出來。用戶可根據所使用的單片機的資源在保證通訊格式正確的情況下作出適當優化。 試驗程序如下: #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; ////////////////// sbit busy = P3^2; sbit s1=P3^7; void initial() { P3M1 = 0x00; P3M0 = 0x80; P1M1 = 0x00; P1M0 = 0xf9; } /*void init_uart() //串口 1 使用硬件波率發生器 { PCON &= 0x7f; //波特率不倍速 SCON = 0x50; //8 位數據,可變波特率 BRT = 0xFD; //設定獨立波特率發生器重裝值 波特率 115200bps AUXR |= 0x04; //獨立波特率發生器時鐘為 Fosc,即 1T AUXR |= 0x01; //串口 1 選擇獨立波特率發生器為波特率發生器 AUXR |= 0x10; //啟動獨立波特率發生器 } */ void init_uart() //串口 1 使用定時器 1 重裝值為波率 { AUXR = 0x54; //使能獨立波特率發生器,獨立波特 1 個計 1 次,T1 不分頻,串口 1 選擇定時器重裝值為波率 SCON = 0x50;//uart1 方式 1,允許接收 TMOD |= 0x20;//T1,方式 2 TL1 = 0xFD;//115200 波率 TH1 = 0xFD;//115200 波率 TR1 = 1; //T1 開啟 } /* 串口發送一個字節,需根據所使用的單片機作適當更改。 */ 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] = 0x8; 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 啟動頻率為:值*頻率倍率(Hz) speed 運行頻率為:值*頻率倍率(Hz) range 頻率倍率(1-100) 返回值: 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 range) { unsigned char OutByte[25]; unsigned char inbuf[12]; OutByte[0] = 0x68; OutByte[1] = 0xe; 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] = range; 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; } /* 函數名: set_soft_limit 功能:設置軸軟件限位 參數: cardno 卡號 axis 軸號(1-6) mode 0:解除軟件限位 1:啟用軟件限位 pulse1負方向限位脈沖值,范圍(-268435455~0) pulse2正方向限位脈沖值,范圍( 0~+268435455) 返回值: 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; } /* 函數名: set_hard_limit 功能:設置軸硬件限位 參數: cardno 卡號 axis 軸號(1-6) mode 0:解除硬件限位 1:啟用硬件限位 dir 0:反方向 1:正方向 number 端口號(0-9) X0-X9 value 狀態(0,1) 0: 輸入低電平 1: 輸入高電平 返回值: 0 失敗 1 成功 */ unsigned char set_hard_limit(unsigned char cardno ,unsigned char axis ,unsigned char mode, unsigned char dir, unsigned char number, unsigned char value) { unsigned char OutByte[25]; unsigned char inbuf[12]; OutByte[0] = 0x68; OutByte[1] = 0x9; OutByte[2] = cardno ; OutByte[3] = 0x10; OutByte[4] = axis; OutByte[5] = mode; OutByte[6] = dir; OutByte[7] = number; 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; } /* 函數名: pmove 功能:單軸運行 參數: cardno 卡號 axis 軸號(1-6) pulse輸出的脈沖數 >0:正方向移動 <0:負方向移動 范圍(-268435455~+268435455) mode 0:相對位移 1:絕對位移 2:連續位移 返回值: 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-8) 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; } /* 函數名: write_bit 功能:寫輸出口狀態或寄存器值 參數: cardno 卡號 number 端口號( 0-14) Y0-Y14 ; 寄存器號(100-115)D100-D115 value 狀態(0,1) 0 輸出低電平 1 輸出高電平;寄存器值(0-255) 返回值: 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; } /* 函數名: read_bit 功能:讀輸入口狀態或寄存器值 參數: cardno 卡號 number 端口號(0-6) X0-X6 ; 寄存器號(100-115)D100-D115 返回值: 狀態(0,1) 0 輸出低電平 1 輸出高電平;寄存器值(0-255) */ unsigned char read_bit(unsigned char cardno ,unsigned char number) { unsigned char OutByte[25]; unsigned char inbuf[12]; OutByte[0] = 0x68; OutByte[1] = 0x5; OutByte[2] = cardno; OutByte[3] = 4; OutByte[4] = number; OutByte[5] = OutByte[1] +OutByte[2] +OutByte[3] +OutByte[4]; USRAT_transmit(OutByte,6); receive(inbuf); return inbuf[5]; } /* 函數名: sudden_stop 功能: 軸停止 參數: cardno 卡號 axis 停止的軸號(1-8) 1-6:1-6 軸停 7:直線插補軸停 8:圓弧插補軸停 返回值: 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-9) X0-X9 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 需要等待停止的軸號 1-6:1-6 軸停 7:直線插補軸停 8:圓弧插補軸停 返回值: 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 long tmp=0; 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); tmp= (unsigned long)inbuf[4]<<24; tmp+= (unsigned long)inbuf[5]<<16; tmp+= (unsigned long)inbuf[6]<<8; tmp+= (unsigned long)inbuf[7]; return tmp; //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 軸狀態,第 7 位為直線插補狀態,第 8 位為圓弧插補狀態。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) */ long get_command_pos( unsigned char cardno, unsigned char axis) { long tmp=0; 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); tmp= (long)inbuf[5]<<24; tmp+= (long)inbuf[6]<<16; tmp+= (long)inbuf[7]<<8; tmp+= (long)inbuf[8]; return tmp; //return(((unsigned long)inbuf[5]<<24)+((unsigned long)inbuf[6]<<16)+((unsigned long)inbuf[7]<<8)+((unsigned //long)inbuf[8])); } /* 函數名: set_cardno 功能:設置卡號 參數: cardno 卡號(1-128)模塊地址 (250 ) 重啟 返回值: 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; } /* 函數名: read_fifo_count 功能:獲取緩沖空間未執行指令數量 參數: cardno 卡號 返回值:(0-1000) 緩沖空間未執行指令數量 */ unsigned int read_fifo_count ( unsigned char cardno) { unsigned char OutByte[25]; unsigned char inbuf[12]; OutByte[0] = 0x68 ; OutByte[1] = 0x4 ; OutByte[2] = cardno ; OutByte[3] = 0x0d; OutByte[4] =OutByte[1] +OutByte[2] +OutByte[3] ; USRAT_transmit(OutByte,5); receive(inbuf); return (((unsigned int)inbuf[4]<<8)+ inbuf[5]); } /* 函數名: wait_pulse 功能:等待軸脈沖數 參數: cardno 卡號 axis 軸號(1,2,3,5,7,8) 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; } /* 函數名: set_synchro 功能:設置軸同步 參數: cardno 卡號 no1 主軸號(1,2,3,5,7,8) no2 隨動軸號(1,2,3,5,7,8) mode 方式 0 :關閉 1: 打開 pulse1 主軸脈沖數 pulse2 隨動軸脈沖數 返回值: 0 失敗 1 成功 */ unsigned char set_synchro(unsigned char cardno ,unsigned char no1 ,unsigned char no2,unsigned char mode, int pulse1 ,int pulse2 ) { unsigned char OutByte[25]; unsigned char inbuf[12]; OutByte[0] = 0x68; OutByte[1] = 0xb; OutByte[2] = cardno; OutByte[3] = 0x22; OutByte[4] = no1; OutByte[5] = no2; OutByte[6] = mode; OutByte[7] = pulse1 >>8; OutByte[8] = pulse1 ; OutByte[9] = pulse2 >>8; OutByte[10] = pulse2 ; OutByte[11] =OutByte[1] +OutByte[2] +OutByte[3] +OutByte[4] +OutByte[5] +OutByte[6] +OutByte[7] +OutByte[8] +OutByte[9] +OutByte[10]; USRAT_transmit(OutByte,12); receive(inbuf); return 1; } /* 函數名: inp_move3 功能:三軸直線插補 參數: cardno 卡號 no1 X 軸軸號 no2 Y 軸軸號 no3 Z 軸軸號 pulse1,pulse2,pulse3 X-Y-Z 軸移動的距離,范圍( -8388608~+8388607) mode 0:相對坐標 1:絕對坐標 返回值: 0 失敗 1 成功 */ unsigned char inp_move3(unsigned char cardno,unsigned char no1 ,unsigned char no2,unsigned char no3, long pulse1 ,long pulse2,long pulse3 ,unsigned char mode ) { unsigned char OutByte[25]; unsigned char inbuf[12]; OutByte[0] = 0x68; OutByte[1] = 0x14; OutByte[2] = cardno; OutByte[3] = 0x21; OutByte[4] = no1; OutByte[5] = no2; OutByte[6] = no3; OutByte[7] = pulse1>>24; OutByte[8] = pulse1 >>16; OutByte[9] = pulse1>> 8; OutByte[10] = pulse1; OutByte[11] = pulse2 >>24; OutByte[12] = pulse2 >>16; OutByte[13] = pulse2 >>8; OutByte[14] = pulse2 ; OutByte[15] = pulse3 >>24; OutByte[16] = pulse3 >>16; OutByte[17] = pulse3 >>8; OutByte[18] = pulse3 ; OutByte[19] = mode; OutByte[20] =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[1]+OutByte[18] +OutByte[19] ; USRAT_transmit(OutByte,21); receive(inbuf); return 1; } void main(void) { char i; //initial(); init_uart(); //set_cardno(1); //設卡號為 1 set_hard_limit(1,1 ,1 , 0,0,0); // 設 1 軸向負方向運動時 X0 輸入口狀態為低時限位,用于回原點 set_hard_limit(1,2 ,1 , 0,1,0); // 設 2 軸向負方向運動時 X1 輸入口狀態為低時限位,用于回原點 set_hard_limit(1,3 ,1 , 0,2,0); // 設 3 軸向負方向運動時 X2 輸入口狀態為低時限位,用于回原點 while(1) { if(!s1)//按鍵按下 { set_speed(1 ,1,1000,1000,10,200,100); // 設 1 軸速度 set_speed(1 ,2,1000,1000,10,200,100); // 設 2 軸速度 set_speed(1 ,3,1000,1000,10,200,100); // 設 3 軸速度 /*1,2,3 軸同時回原點*/ pmove(1,1,-1000000,0); // 1 軸向負方向運動 pmove(1,2,-1000000,0); // 2 軸向負方向運動 pmove(1,3,-1000000,0); // 3 軸向負方向運動 wait_stop(1 ,1); //等待 1 軸停止 wait_stop(1 ,2); //等待 2 軸停止 wait_stop(1 ,3); //等待 3 軸停止 set_command_pos(1,1,0); // 設 1 軸此時坐標為 0 set_command_pos(1,2,0); // 設 2 軸此時坐標為 0 set_command_pos(1,3,0); // 設 3 軸此時坐標為 0 /*3 軸向正方向運動,單片機不斷查詢軸狀態,直到軸都停止了才執行后面的程序。*/ pmove(1,3,3200,0); // 3 軸運動 wait_stop(1 ,3) ; // 模塊自己等待 3 軸停止 write_bit(1, 101, 1) ; // 3 軸停止后自己將模塊寄存器 D101 寫為 1 while(read_bit(1,101)!=1); //模塊寄存器 D101 不為 1 一直等,即前面動作還沒執行完 //while(get_status(1)); // 軸沒停止一直等 /*1 軸向正方向運動,碰到感應開關 X5 后停止,然后 2 軸開始正方向運行 3200 個脈沖,運行 完成后,將 Y12 輸出口置 1,等待 5 秒,再將 Y12 輸出口置 0。*/ pmove(1,1,1000000,0); // 1 軸運動 wait_in(1,5,0); // 模塊內部自己等待,直到 X5 為低 sudden_stop(1,1); // 1 軸停止 pmove(1,2,3200,0); // 2 軸運動 wait_stop(1 ,2); //模塊內部自己等待 2 軸停止 write_bit(1,12 ,1); //將 Y12 輸出口置 1 wait_delay(1,5000); //模塊內部延時 5 秒 write_bit(1,12 ,0); //將 Y12 輸出口置 0 /*mpc004S 芯片軸同步指令配合等待軸脈沖指令完成繞線的過程示例。編碼器輸入口接主軸電機編 碼器,1 軸為排線電機。*/ for(i=0;i<10;i++) //繞 10 層 { set_synchro(1 ,7 ,1,1,8,1) ; /*編碼器 1 口為主軸,1 軸排線與其同步,編碼器 1 圈為 1600 個 脈沖,1 軸移一個線寬為 200 脈沖,比率為 8 比 1。*/ wait_pulse(1 ,7, 160000); // 等待編碼器脈沖為 160000,即轉了 100 圈。 set_synchro(1 ,7 ,1,1,8,-1) ; //將比率設為 8 比-1。即讓 1 軸反轉排線。 wait_pulse(1 ,7, 320000); // 等待編碼器脈沖為 320000,即又轉了 100 圈。 set_command_pos(1,7,0); //將編碼器脈沖清為 0。 write_bit(1, 100, i) ; //每繞一層將層號寫到模塊,單片機可隨時讀出已繞到哪層。 } while(!s1); } } } 采用單片機stc89C2051和mpc006運動控制芯片模塊作為控制系統的核心,控制三路步進電機做運動實驗。單片機發送指令給mpc006微型運動控制模塊,模塊信號輸出給步進驅動器作高速度運動。可以定點運動,直線插補和圓弧插補。 1.引言 運動控制的應用在國內已有十幾年的歷史,技術也相當成熟。通常運動控制都需要用到運動控制卡, 運動控制器等產品,但這些產品價格高昂,使用復雜,也不適合由單片機構成的控制系統。而如果直接采 用單片機來做運動控制,由于運動控制對系統性能要求非常高,單片機速度資源有限,難以設計出性能優 良的運動控制模型。因此,本文采用單片機和專業的 mpc006 運動控制芯片模塊構成運動控制系統。 MPC006 運動控制芯片模塊采用新型 FPGA 設計,集成實用運動控制功能,可與普通單片機通過串口通訊 對步進電機和伺服電機控制。具有如下特點: ◆ 串口通訊,僅需使用幾條指令,簡單可靠。 ◆ 單模塊最高六軸輸出,多個模塊組網工作可達 120 軸。 ◆ 最大脈沖輸出頻率為 2MHz,脈沖輸出使用脈沖+方向方式。 ◆ 最高六軸獨立運動控制,任意兩軸直線插補,任意兩軸圓弧插補。 ◆ 每軸一路硬件回原點。 ◆ 模塊帶 1000 條指令緩存深度,指令先進先出,無需高速通訊。 ◆ 模塊體積小巧,僅 3.5*2.5*1.5cm,雙排直插 30 腳封裝。 硬件系統由四部分構成: (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 晶體管及電極開路輸出,分別接到電機驅動器脈沖和方向信號輸入端。 MPC006 運動控制芯片模塊與單片機串口通訊速率為 115200bps,數據位為 8 位,停止位 1 位,無校驗。單片機與 mpc006 運動控制模塊采用串口應答式通訊,單片機作主機,單片機每發送一條指令給 mpc006運動控制芯片模塊,mpc006 運動控制芯片模塊返回以 0x68 開始的固定長度為 10 個字節的數據串。單片即可以取出需要的數據。一般情況需接收到 mpc006 運動控制模塊返回的數據后單片機才能發送下一條指令。如果程序中不接收模塊返回的數據,需間隔 5MS 以上才能發送下一條指令。另外需注意,當發送指令時如果字節間時間間隔大于 1MS,模塊會認為整條指令發送結束,所以在發送一條指令給模塊時不要被程序里的中斷長時間打斷。當接收模塊的返回的數據時,由于波特率很高,如果有長時間中斷打斷接收過程,可能會導致接收字節丟失。所以,通訊時最好能暫時關閉其它太占時長中斷。mpc 運動控制模塊帶 1000條指令緩存空間,并自帶基本邏輯判斷能力,單片機不用等待一條執行完成后才發送下一條,完全可以一起發送給模塊,模塊會按順序自動逐條執行。 單片機發送和接收指令的數據格式如下: 起始碼:為一條指令的起始字節內容,固定為 0x68。 數據個數:為從數據個數開始到校驗和的數據長度。 模塊地址:為控制器的通訊地址。地址 0 對所有控制器都有效。 功能碼:表示指令的功能,每條指令的功能碼都是唯一的。 參數:表示指令的參數,每條指令的參數字節數并不都是相同的。 校驗和:為從數據個數開始到校驗和前一個字節的校驗和。 mpc006 運動控制芯片模塊默認地址為 0,可以接收帶任何地址的指令數據。如果單片機串口只連接了一個模塊,地址可以不用設置。 mpc006 運動控制芯片模塊無需任何初始化。上電后只發一條 pmove 單軸運行指令對應軸都會有脈沖輸出。使用函數前先設置好單片機的串口功能,并將需要用到的函數的原型拷貝到當前程序內。本文所使用的函數原型為基礎版本,已根據模塊使用說明書中通訊協議將各指令通訊過程描述出來。用戶可根據所使用的單片機的資源在保證通訊格式正確的情況下作出適當優化。 試驗程序如下: #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; ////////////////// sbit busy = P3^2; sbit s1=P3^7; void initial() { P3M1 = 0x00; P3M0 = 0x80; P1M1 = 0x00; P1M0 = 0xf9; } /*void init_uart() //串口 1 使用硬件波率發生器 { PCON &= 0x7f; //波特率不倍速 SCON = 0x50; //8 位數據,可變波特率 BRT = 0xFD; //設定獨立波特率發生器重裝值 波特率 115200bps AUXR |= 0x04; //獨立波特率發生器時鐘為 Fosc,即 1T AUXR |= 0x01; //串口 1 選擇獨立波特率發生器為波特率發生器 AUXR |= 0x10; //啟動獨立波特率發生器 } */ void init_uart() //串口 1 使用定時器 1 重裝值為波率 { AUXR = 0x54; //使能獨立波特率發生器,獨立波特 1 個計 1 次,T1 不分頻,串口 1 選擇定時器重裝值為波率 SCON = 0x50;//uart1 方式 1,允許接收 TMOD |= 0x20;//T1,方式 2 TL1 = 0xFD;//115200 波率 TH1 = 0xFD;//115200 波率 TR1 = 1; //T1 開啟 } /* 串口發送一個字節,需根據所使用的單片機作適當更改。 */ 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] = 0x8; 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 啟動頻率為:值*頻率倍率(Hz) speed 運行頻率為:值*頻率倍率(Hz) range 頻率倍率(1-100) 返回值: 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 range) { unsigned char OutByte[25]; unsigned char inbuf[12]; OutByte[0] = 0x68; OutByte[1] = 0xe; 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] = range; 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; } /* 函數名: set_soft_limit 功能:設置軸軟件限位 參數: cardno 卡號 axis 軸號(1-6) mode 0:解除軟件限位 1:啟用軟件限位 pulse1負方向限位脈沖值,范圍(-268435455~0) pulse2正方向限位脈沖值,范圍( 0~+268435455) 返回值: 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; } /* 函數名: set_hard_limit 功能:設置軸硬件限位 參數: cardno 卡號 axis 軸號(1-6) mode 0:解除硬件限位 1:啟用硬件限位 dir 0:反方向 1:正方向 number 端口號(0-9) X0-X9 value 狀態(0,1) 0: 輸入低電平 1: 輸入高電平 返回值: 0 失敗 1 成功 */ unsigned char set_hard_limit(unsigned char cardno ,unsigned char axis ,unsigned char mode, unsigned char dir, unsigned char number, unsigned char value) { unsigned char OutByte[25]; unsigned char inbuf[12]; OutByte[0] = 0x68; OutByte[1] = 0x9; OutByte[2] = cardno ; OutByte[3] = 0x10; OutByte[4] = axis; OutByte[5] = mode; OutByte[6] = dir; OutByte[7] = number; 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; } /* 函數名: pmove 功能:單軸運行 參數: cardno 卡號 axis 軸號(1-6) pulse輸出的脈沖數 >0:正方向移動 <0:負方向移動 范圍(-268435455~+268435455) mode 0:相對位移 1:絕對位移 2:連續位移 返回值: 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-8) 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; } /* 函數名: write_bit 功能:寫輸出口狀態或寄存器值 參數: cardno 卡號 number 端口號( 0-14) Y0-Y14 ; 寄存器號(100-115)D100-D115 value 狀態(0,1) 0 輸出低電平 1 輸出高電平;寄存器值(0-255) 返回值: 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; } /* 函數名: read_bit 功能:讀輸入口狀態或寄存器值 參數: cardno 卡號 number 端口號(0-6) X0-X6 ; 寄存器號(100-115)D100-D115 返回值: 狀態(0,1) 0 輸出低電平 1 輸出高電平;寄存器值(0-255) */ unsigned char read_bit(unsigned char cardno ,unsigned char number) { unsigned char OutByte[25]; unsigned char inbuf[12]; OutByte[0] = 0x68; OutByte[1] = 0x5; OutByte[2] = cardno; OutByte[3] = 4; OutByte[4] = number; OutByte[5] = OutByte[1] +OutByte[2] +OutByte[3] +OutByte[4]; USRAT_transmit(OutByte,6); receive(inbuf); return inbuf[5]; } /* 函數名: sudden_stop 功能: 軸停止 參數: cardno 卡號 axis 停止的軸號(1-8) 1-6:1-6 軸停 7:直線插補軸停 8:圓弧插補軸停 返回值: 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-9) X0-X9 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 需要等待停止的軸號 1-6:1-6 軸停 7:直線插補軸停 8:圓弧插補軸停 返回值: 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 long tmp=0; 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); tmp= (unsigned long)inbuf[4]<<24; tmp+= (unsigned long)inbuf[5]<<16; tmp+= (unsigned long)inbuf[6]<<8; tmp+= (unsigned long)inbuf[7]; return tmp; //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 軸狀態,第 7 位為直線插補狀態,第 8 位為圓弧插補狀態。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) */ long get_command_pos( unsigned char cardno, unsigned char axis) { long tmp=0; 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); tmp= (long)inbuf[5]<<24; tmp+= (long)inbuf[6]<<16; tmp+= (long)inbuf[7]<<8; tmp+= (long)inbuf[8]; return tmp; //return(((unsigned long)inbuf[5]<<24)+((unsigned long)inbuf[6]<<16)+((unsigned long)inbuf[7]<<8)+((unsigned //long)inbuf[8])); } /* 函數名: set_cardno 功能:設置卡號 參數: cardno 卡號(1-128)模塊地址 (250 ) 重啟 返回值: 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; } /* 函數名: read_fifo_count 功能:獲取緩沖空間未執行指令數量 參數: cardno 卡號 返回值:(0-1000) 緩沖空間未執行指令數量 */ unsigned int read_fifo_count ( unsigned char cardno) { unsigned char OutByte[25]; unsigned char inbuf[12]; OutByte[0] = 0x68 ; OutByte[1] = 0x4 ; OutByte[2] = cardno ; OutByte[3] = 0x0d; OutByte[4] =OutByte[1] +OutByte[2] +OutByte[3] ; USRAT_transmit(OutByte,5); receive(inbuf); return (((unsigned int)inbuf[4]<<8)+ inbuf[5]); } /* 函數名: wait_pulse 功能:等待軸脈沖數 參數: cardno 卡號 axis 軸號(1,2,3,5,7,8) 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; } /* 函數名: set_synchro 功能:設置軸同步 參數: cardno 卡號 no1 主軸號(1,2,3,5,7,8) no2 隨動軸號(1,2,3,5,7,8) mode 方式 0 :關閉 1: 打開 pulse1 主軸脈沖數 pulse2 隨動軸脈沖數 返回值: 0 失敗 1 成功 */ unsigned char set_synchro(unsigned char cardno ,unsigned char no1 ,unsigned char no2,unsigned char mode, int pulse1 ,int pulse2 ) { unsigned char OutByte[25]; unsigned char inbuf[12]; OutByte[0] = 0x68; OutByte[1] = 0xb; OutByte[2] = cardno; OutByte[3] = 0x22; OutByte[4] = no1; OutByte[5] = no2; OutByte[6] = mode; OutByte[7] = pulse1 >>8; OutByte[8] = pulse1 ; OutByte[9] = pulse2 >>8; OutByte[10] = pulse2 ; OutByte[11] =OutByte[1] +OutByte[2] +OutByte[3] +OutByte[4] +OutByte[5] +OutByte[6] +OutByte[7] +OutByte[8] +OutByte[9] +OutByte[10]; USRAT_transmit(OutByte,12); receive(inbuf); return 1; } /* 函數名: inp_move3 功能:三軸直線插補 參數: cardno 卡號 no1 X 軸軸號 no2 Y 軸軸號 no3 Z 軸軸號 pulse1,pulse2,pulse3 X-Y-Z 軸移動的距離,范圍( -8388608~+8388607) mode 0:相對坐標 1:絕對坐標 返回值: 0 失敗 1 成功 */ unsigned char inp_move3(unsigned char cardno,unsigned char no1 ,unsigned char no2,unsigned char no3, long pulse1 ,long pulse2,long pulse3 ,unsigned char mode ) { unsigned char OutByte[25]; unsigned char inbuf[12]; OutByte[0] = 0x68; OutByte[1] = 0x14; OutByte[2] = cardno; OutByte[3] = 0x21; OutByte[4] = no1; OutByte[5] = no2; OutByte[6] = no3; OutByte[7] = pulse1>>24; OutByte[8] = pulse1 >>16; OutByte[9] = pulse1>> 8; OutByte[10] = pulse1; OutByte[11] = pulse2 >>24; OutByte[12] = pulse2 >>16; OutByte[13] = pulse2 >>8; OutByte[14] = pulse2 ; OutByte[15] = pulse3 >>24; OutByte[16] = pulse3 >>16; OutByte[17] = pulse3 >>8; OutByte[18] = pulse3 ; OutByte[19] = mode; OutByte[20] =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[1]+OutByte[18] +OutByte[19] ; USRAT_transmit(OutByte,21); receive(inbuf); return 1; } void main(void) { char i; //initial(); init_uart(); //set_cardno(1); //設卡號為 1 set_hard_limit(1,1 ,1 , 0,0,0); // 設 1 軸向負方向運動時 X0 輸入口狀態為低時限位,用于回原點 set_hard_limit(1,2 ,1 , 0,1,0); // 設 2 軸向負方向運動時 X1 輸入口狀態為低時限位,用于回原點 set_hard_limit(1,3 ,1 , 0,2,0); // 設 3 軸向負方向運動時 X2 輸入口狀態為低時限位,用于回原點 while(1) { if(!s1)//按鍵按下 { set_speed(1 ,1,1000,1000,10,200,100); // 設 1 軸速度 set_speed(1 ,2,1000,1000,10,200,100); // 設 2 軸速度 set_speed(1 ,3,1000,1000,10,200,100); // 設 3 軸速度 /*1,2,3 軸同時回原點*/ pmove(1,1,-1000000,0); // 1 軸向負方向運動 pmove(1,2,-1000000,0); // 2 軸向負方向運動 pmove(1,3,-1000000,0); // 3 軸向負方向運動 wait_stop(1 ,1); //等待 1 軸停止 wait_stop(1 ,2); //等待 2 軸停止 wait_stop(1 ,3); //等待 3 軸停止 set_command_pos(1,1,0); // 設 1 軸此時坐標為 0 set_command_pos(1,2,0); // 設 2 軸此時坐標為 0 set_command_pos(1,3,0); // 設 3 軸此時坐標為 0 /*3 軸向正方向運動,單片機不斷查詢軸狀態,直到軸都停止了才執行后面的程序。*/ pmove(1,3,3200,0); // 3 軸運動 wait_stop(1 ,3) ; // 模塊自己等待 3 軸停止 write_bit(1, 101, 1) ; // 3 軸停止后自己將模塊寄存器 D101 寫為 1 while(read_bit(1,101)!=1); //模塊寄存器 D101 不為 1 一直等,即前面動作還沒執行完 //while(get_status(1)); // 軸沒停止一直等 /*1 軸向正方向運動,碰到感應開關 X5 后停止,然后 2 軸開始正方向運行 3200 個脈沖,運行 完成后,將 Y12 輸出口置 1,等待 5 秒,再將 Y12 輸出口置 0。*/ pmove(1,1,1000000,0); // 1 軸運動 wait_in(1,5,0); // 模塊內部自己等待,直到 X5 為低 sudden_stop(1,1); // 1 軸停止 pmove(1,2,3200,0); // 2 軸運動 wait_stop(1 ,2); //模塊內部自己等待 2 軸停止 write_bit(1,12 ,1); //將 Y12 輸出口置 1 wait_delay(1,5000); //模塊內部延時 5 秒 write_bit(1,12 ,0); //將 Y12 輸出口置 0 /*mpc004S 芯片軸同步指令配合等待軸脈沖指令完成繞線的過程示例。編碼器輸入口接主軸電機編 碼器,1 軸為排線電機。*/ for(i=0;i<10;i++) //繞 10 層 { set_synchro(1 ,7 ,1,1,8,1) ; /*編碼器 1 口為主軸,1 軸排線與其同步,編碼器 1 圈為 1600 個 脈沖,1 軸移一個線寬為 200 脈沖,比率為 8 比 1。*/ wait_pulse(1 ,7, 160000); // 等待編碼器脈沖為 160000,即轉了 100 圈。 set_synchro(1 ,7 ,1,1,8,-1) ; //將比率設為 8 比-1。即讓 1 軸反轉排線。 wait_pulse(1 ,7, 320000); // 等待編碼器脈沖為 320000,即又轉了 100 圈。 set_command_pos(1,7,0); //將編碼器脈沖清為 0。 write_bit(1, 100, i) ; //每繞一層將層號寫到模塊,單片機可隨時讀出已繞到哪層。 } while(!s1); } } } |