馮 深,王景存,黎佳亨
(武漢科技大學(xué)信息科學(xué)與工程學(xué)院,湖北武漢 430081)
由于傳統(tǒng)以太網(wǎng)采用CSMA/CD機(jī)制[1],應(yīng)用于工業(yè)自動(dòng)化控制系統(tǒng)時(shí)會(huì)產(chǎn)生實(shí)時(shí)性等問(wèn)題。因此,實(shí)時(shí)工業(yè)以太網(wǎng)技術(shù)是在傳統(tǒng)以太網(wǎng)的通信模型基礎(chǔ)之上加以修改來(lái)實(shí)現(xiàn)強(qiáng)實(shí)時(shí)性和穩(wěn)定性的工業(yè)以太網(wǎng),如EtherCAT、SERCOS等[2]。EtherCAT總線具有實(shí)時(shí)性好、速度快、同步性高、開(kāi)放性好、拓?fù)潇`活、成本低等優(yōu)點(diǎn),在測(cè)控領(lǐng)域、CNC加工控制以及工業(yè)機(jī)器人等領(lǐng)域有廣泛的應(yīng)用[3]。
現(xiàn)有的EtherCAT主站系統(tǒng)多為PLC或工控計(jì)算機(jī)來(lái)完成,不適合嵌入式系統(tǒng)中體積小、靈活性高的要求。因此在嵌入式系統(tǒng)中難以應(yīng)用EtherCAT總線。本文的主要思想是將EtherCAT總線的主站控制器應(yīng)用到嵌入式系統(tǒng)中。EC-01M是EtherCAT主站控制芯片,采用SPI通訊格式,依不同通訊周期頻率要求,SPI的串行時(shí)鐘信號(hào)最高至24 MHz,支持40個(gè)子站設(shè)備。系統(tǒng)采用基于嵌入式ARM MCU+FPGA的軟硬件協(xié)同設(shè)計(jì)方案[4-6],即解決了EtherCAT主站控制器所要求協(xié)議的強(qiáng)實(shí)時(shí)性和高穩(wěn)定性,又滿足了嵌入式系統(tǒng)體積小、靈活性高的要求。
本系統(tǒng)需要控制3臺(tái)伺服電機(jī),選用的伺服控制器為CDHD2型伺服控制器,該控制器支持EtherCAT總線接口,在系統(tǒng)中稱(chēng)為EtherCAT Slave設(shè)備[7]。主控MCU采用STM32F103,F(xiàn)PGA選用EP3C10E144C7芯片。系統(tǒng)框圖如圖1所示。
圖1 系統(tǒng)總體結(jié)構(gòu)圖
EC-01M可以控制40個(gè)EtherCAT子站,每個(gè)子站的數(shù)據(jù)幀為12 Byte。另有2個(gè)特殊的數(shù)據(jù)幀,一個(gè)為控制EC-01M芯片的數(shù)據(jù)幀,另一個(gè)為專(zhuān)門(mén)對(duì)應(yīng)單一子站進(jìn)行非周期性的參數(shù)讀寫(xiě)(SDO Read/Write)的數(shù)據(jù)幀。因此,每次給EC-01M芯片下達(dá)命令均會(huì)傳遞504 Byte的數(shù)據(jù)(本文稱(chēng)為一個(gè)數(shù)據(jù)包),會(huì)得到504 Byte的數(shù)據(jù)回應(yīng)。EC-01M芯片規(guī)定不論40個(gè)子站是否都連接了伺服控制器,都要傳輸504 Byte,沒(méi)有連接設(shè)備的子站12 Byte數(shù)據(jù)可均為0。504 Byte的數(shù)據(jù)包格式如圖2所示。由于篇幅有限,有關(guān)EC-01M芯片的硬件電路和命令集等可在其數(shù)據(jù)手冊(cè)中查閱,本文不再贅述。
圖2 EC-01M命令與響應(yīng)數(shù)據(jù)包格式
SPI傳輸以Byte為單位,每次由低地址開(kāi)始傳,依序傳至最高地址,即SPI傳輸從Byte0開(kāi)始,再依序傳Byte1、Byte2等,直至最后一個(gè)Byte為止。而SPI傳輸單一Byte時(shí),采取MSB模式,即高位先傳輸。
EC-01M的SPI模式為Slave模式,F(xiàn)PGA為Master模式[8],空閑時(shí)時(shí)鐘信號(hào)SPI_SCLK為低電位,數(shù)據(jù)在下降沿發(fā)送,并于上升沿接收。單字節(jié)傳輸時(shí)序如圖3所示,SPI_SS為選通信號(hào),當(dāng)?shù)碗娖綍r(shí)有效,SPI_CLK為時(shí)鐘信號(hào),SPI_MOSI為FPGA到EC-01M的輸出數(shù)據(jù),SPI_MISO為FPGA從EC-01M讀入的數(shù)據(jù)。
圖3 SPI單字節(jié)傳輸時(shí)序
在FPGA與EC-01M的SPI通訊過(guò)程中,要檢測(cè)EC-01M的忙(SPI_Busy)信號(hào),只有當(dāng)SPI_Busy信號(hào)為低時(shí)才能進(jìn)行數(shù)據(jù)包傳輸。當(dāng)進(jìn)入SPI通訊后,SPI_Busy信號(hào)立刻升為高電位,直至數(shù)據(jù)包通訊結(jié)束且EC-01M處理完命令后,SPI_Busy信號(hào)才會(huì)恢復(fù)為低電位。一個(gè)數(shù)據(jù)包(504 Byte)的時(shí)序圖如圖4所示。
圖4 SPI 數(shù)據(jù)包(504 Byte)傳輸時(shí)序
SPI控制邏輯的主頻率可高達(dá)24 MHz,且FPGA控制端偵測(cè)到SPI_Busy為低電位時(shí),必須立即進(jìn)行下一筆數(shù)據(jù)的交換。
在FPGA的邏輯設(shè)計(jì)中,主要包含兩大邏輯模塊,一是和MCU通訊的FSMC接口模塊[9-10],二是控制EC-01M的SPI控制邏輯模塊[11-12]。FSMC接口模塊包括:寄存器定義模塊、寄存器讀寫(xiě)模塊和中斷控制模塊等,由于FSMC接口模塊其他文獻(xiàn)介紹較多,在此不再贅述。
SPI控制邏輯模塊對(duì)下提供SPI接口,與主站芯片EC-01M相連,實(shí)現(xiàn)SPI通信協(xié)議;對(duì)上與FSMC相連,完成與MCU的數(shù)據(jù)交換。具有以下功能:
(1)支持8位、504 Byte長(zhǎng)數(shù)據(jù)傳輸;
(2)支持帶有SPI_SS的傳輸模式;
(3)支持帶有SPI_BUSY的傳輸控制模式;
(4)支持?jǐn)?shù)據(jù)包發(fā)送接收完成后產(chǎn)生中斷請(qǐng)求信號(hào)。
圖5為FPGA中SPI控制邏輯的設(shè)計(jì)框圖??刂七壿嬛蠸PI_MOSI、SPI_MISO、SPI_CS、SPI_CLK為標(biāo)準(zhǔn)SPI協(xié)議引腳,SPI_BUSY連接主站芯片。
圖5 FPGA SPI設(shè)計(jì)框圖
SPI控制邏輯分為3部分實(shí)現(xiàn),即數(shù)據(jù)發(fā)送寄存器、數(shù)據(jù)接收寄存器和SPI控制邏輯(包括中斷與時(shí)鐘發(fā)生器及狀態(tài)機(jī)控制器邏輯)。在本系統(tǒng)中只有3個(gè)伺服電機(jī),因此只有60 Byte的輸出寄存器和60 Byte的輸入寄存器(主站12 Byte,伺服3×12=36 Byte,SDO控制器12 Byte)。
SPI控制邏輯在輸出數(shù)據(jù)SPI_MOSI的同時(shí)會(huì)讀取SPI_MISO引腳接收的數(shù)據(jù)。并將其移位輸入到spi_rx_db接收數(shù)據(jù)寄存器中,由狀態(tài)機(jī)控制器再把接收寄存器的值輸出到60個(gè)接收數(shù)據(jù)寄存器中的一個(gè)寄存器中。
SPI控制邏輯工作在有限狀態(tài)機(jī),整個(gè)504 Byte的發(fā)送與接收由狀態(tài)機(jī)來(lái)控制,其狀態(tài)可分為空閑狀態(tài)(IDLE)、預(yù)發(fā)送狀態(tài)(SEND_PRE)、發(fā)送狀態(tài)(SEND)、發(fā)送結(jié)束狀態(tài)(SEND_OV)、忙線檢查狀態(tài)(CHECK_BUSY)、延時(shí)狀態(tài)(DELAY)和延時(shí)結(jié)束狀態(tài)(DELAY_OV),圖6為狀態(tài)機(jī)控制器設(shè)計(jì)框圖。
圖6 狀態(tài)機(jī)轉(zhuǎn)移圖
狀態(tài)機(jī)的控制信號(hào)主要有Start_Rise、cnt504、spi_busy、delay_cnt等。其中:
Start_Rise為MCU發(fā)出的SPI啟動(dòng)信號(hào),當(dāng)MCU通過(guò)FSMC將上一次的數(shù)據(jù)讀出且將本次要發(fā)出的數(shù)據(jù)已寫(xiě)入寄存器后,發(fā)出此信號(hào)。SPI控制邏輯中通過(guò)高頻時(shí)鐘檢查此信號(hào)的上升沿,將此信號(hào)置1。
cnt504為內(nèi)部計(jì)數(shù)器,每發(fā)送接收1 Byte后,此計(jì)數(shù)器加1。因此當(dāng)它等于504時(shí),即完成了1包數(shù)據(jù)的傳輸。此計(jì)數(shù)器也指出了當(dāng)前正在發(fā)送和接收的是哪個(gè)數(shù)據(jù)。(系統(tǒng)中只有3個(gè)伺服電機(jī),在504 Byte中大部分字節(jié)的數(shù)據(jù)為0)。
spi_busy為主站芯片輸出的忙信號(hào),當(dāng)主站可以進(jìn)行SPI傳輸時(shí),此信號(hào)為0。否則為1。
delay_cnt為延時(shí)計(jì)數(shù)器,它決定了兩包數(shù)據(jù)之間的延時(shí)時(shí)間。在進(jìn)入DELAY狀態(tài)的同時(shí),觸發(fā)中斷控制模塊,向MCU產(chǎn)生INT中斷請(qǐng)求。
最后,狀態(tài)機(jī)回到空閑狀態(tài),等待MCU啟動(dòng)下一輪的數(shù)據(jù)傳輸。
除了上述狀態(tài)機(jī)以外,還有幾個(gè)重要的控制模塊,如SPI字節(jié)傳輸控制、SPI_CLK產(chǎn)生模塊、SPI數(shù)據(jù)的輸入和輸出模塊、輸入寄存器的保存、輸出寄存器的更新、中斷信號(hào)產(chǎn)生等模塊,下面詳細(xì)介紹各模塊的設(shè)計(jì)思路。
2.2.1 SPI字節(jié)傳輸控制
字節(jié)傳輸控制模塊由一個(gè)計(jì)數(shù)器cnt20來(lái)實(shí)現(xiàn),此計(jì)數(shù)器的計(jì)數(shù)范圍為0~19,在SEND狀態(tài)下由主時(shí)鐘控制加1操作。主要程序如下:
always @(posedge clk or negedge rst_n)
if(!rst_n)
Cnt20 <= 8′d0;
else if(cur_st == IDLE)
Cnt20 <= 8′d0;
else if(cur_st == SEND)
begin
if(cnt20 < 8′d19)
Cnt20 <= cnt20+1'b1;
else
Cnt20 <= 8′d0;
end
else
cnt8 <=8′d0;
cur_st為狀態(tài)機(jī)的當(dāng)前狀態(tài)??梢钥闯龃擞?jì)數(shù)器為0~19的一個(gè)循環(huán)計(jì)數(shù)器。
2.2.2 SPI_CLK產(chǎn)生模塊
根據(jù)Cnt20的值結(jié)合狀態(tài)機(jī)的狀態(tài)可以完成很多功能,包括SPI_CLK信號(hào)的產(chǎn)生。主要程序如下:
always @(posedge clk or negedge rst_n)
if(!rst_n)
spi_clk <= 1′b0;
else if(cur_st == IDLE||cur_st == SEND_OV)
spi_clk <= 1′b0;
else if(cnt20 > 8′d2 && cnt20 < 8′d19)
spi_clk <=~spi_clk;
可以看出,在cnt20為3~18時(shí),每個(gè)主時(shí)鐘都使得spi_clk翻轉(zhuǎn)1次,因此可以得到傳輸1 Byte所需要的8個(gè)spi_clk脈沖信號(hào)。
2.2.3 SPI數(shù)據(jù)的輸入和輸出
同樣,在SEND狀態(tài)下,可以根據(jù)cnt20的值將8位輸出寄存器spi_tx_db的值輸出到SPI_MOSI信號(hào)線上。主要程序如下:
if(cur_st == SEND)
begin
case(cnt8[4:1])
4′d1:spi_mosi <= spi_tx_db[7];
4′d2:spi_mosi <= spi_tx_db[6];
4′d3:spi_mosi <= spi_tx_db[5];
4′d4:spi_mosi <= spi_tx_db[4];
4′d5:spi_mosi <= spi_tx_db[3];
4′d6:spi_mosi <= spi_tx_db[2];
4′d7:spi_mosi <= spi_tx_db[1];
4′d8:spi_mosi <= spi_tx_db[0];
default:spi_mosir <= 1′b1;
endcase
end
同理,也可以將SPI_MISO線上的值讀入到8位的spi_rx_db寄存器中(篇幅有限,以后只給出程序的主要部分)。
case(cnt8)
8′d3:spi_rx_db[7]<= spi_miso;
8′d5:spi_rx_db[6]<= spi_miso;
8′d7:spi_rx_db[5]<= spi_miso;
8′d9:spi_rx_db[4]<= spi_miso;
8′d11:spi_rx_db[3]<= spi_miso;
8′d13:spi_rx_db[2]<= spi_miso;
8′d15:spi_rx_db[1]<= spi_miso;
8′d17:spi_rx_db[0]<= spi_miso;
default:;
endcase;
2.2.4 輸入輸出寄存器更新
上面所述的只是單字節(jié)的SPI輸入和輸出,由于1包數(shù)據(jù)由504 Byte組成,因此,每當(dāng)上述1 Byte完成后,都要把接收的數(shù)據(jù)(在輸入寄存器spi_rx_db中)保存并更新輸出寄存器spi_tx_db,以便下一次輸入和輸出,并且保存和更新的數(shù)據(jù)位置應(yīng)該是在504 Byte中的相應(yīng)位置,通過(guò)cnt504寄存器可以完成以上功能。主要程序如下:
if(cnt8 == 8′d2)
begin
case(cnt504)
10′d1:RX_SV00_DAT00<=spi_rx_db;
10′d2:RX_SV00_DAT01<= spi_rx_db;
……
10′d504:RX_SV00_DAT59<=spi_rx_db;
default:;
endcase
end
可以看出,每當(dāng)cnt8 == 8′d2時(shí),1 Byte的輸入已經(jīng)完成,因此,可以根據(jù)cnt504計(jì)數(shù)器的值將來(lái)更新和保存上述的spi_rx_db和spi_tx_db寄存器。
case(cnt504)
10′d0:spi_tx_db<= TX_SV00_DAT00;
10′d1:spi_tx_db<= TX_SV00_DAT01;
……
10′d503:spi_tx_db<=TX_SV00_DAT59;
default:spi_tx_db <= 8′d0;
endcase
每當(dāng)1 Byte(spi_tx_db中)輸出完成后,都要更新spi_tx_db寄存器,以便下一次輸出。
2.2.5 中斷信號(hào)的產(chǎn)生
SPI控制模塊完成1包數(shù)據(jù)(504 Byte)的輸入和輸出后向MCU發(fā)出的中斷信號(hào)。當(dāng)MCU接收到中斷信號(hào)后可以通過(guò)FMSC總線將504 Byte讀出并寫(xiě)入1組新的數(shù)據(jù)。
中斷信號(hào)INT在DELAY狀態(tài)下發(fā)出,因?yàn)樵诖藸顟B(tài)下所有輸入輸出都已完成。由于INT是脈沖信號(hào),因此用一個(gè)中斷計(jì)數(shù)器來(lái)規(guī)范INT信號(hào)的脈寬。主要程序如下:
中斷計(jì)數(shù)器的實(shí)現(xiàn):
if(cur_st == DELAY_OV)
begin
if(int_width int_width <= int_width +1′b1; end; else int_width <= 10′d0; 中斷信號(hào)的產(chǎn)生: always @(posedge clk or negedge rst_n) if(!rst_n) spi_int <= 1′d0; else if(int_width == 10′d1) spi_int <= 1′d1; else if(int_width >= INT_WIDTH) spi_int <= 1′d0;else; 改變參數(shù)INT_WIDTH的值,可以改變INT信號(hào)脈沖的寬度。 本系統(tǒng)的測(cè)試是在實(shí)時(shí)運(yùn)行環(huán)境下用邏輯分析儀進(jìn)行采樣獲得。 圖7為多個(gè)數(shù)據(jù)包的總體預(yù)覽圖。從圖7可以看出,SPI數(shù)據(jù)包間隔15 ms定時(shí)發(fā)送,這是在伺服電機(jī)靜止的條件下,不用發(fā)同步周期命令(CSP),只用GET STATUS命令獲取子站狀態(tài),每15 ms 1個(gè)數(shù)據(jù)包即可滿足要求。在伺服電機(jī)運(yùn)動(dòng)期間,本系統(tǒng)主站的同步周期時(shí)間設(shè)為1 ms,因此,每個(gè)數(shù)據(jù)包的間隔也為1 ms。 圖7 SPI數(shù)據(jù)總體采樣圖 圖8為1個(gè)數(shù)據(jù)包(504 Byte)的采集時(shí)序圖。從圖8可以看出,每個(gè)數(shù)據(jù)包是在SPI_BUSY為低電平的情況下開(kāi)始傳送的,F(xiàn)PGA首先發(fā)出SPI_SS(置為低電平),此時(shí),SPI_BUSY變高電平,在SPI_CLK的驅(qū)動(dòng)下開(kāi)始數(shù)據(jù)發(fā)送和接收,504 Byte傳輸完成后,SPI_SS變高電平,此時(shí)等待SPI_BUSY變?yōu)榈碗娖剑?包數(shù)據(jù)傳輸結(jié)束。產(chǎn)生SPI_INT中斷,MCU接收此中斷后通過(guò)FSMC總線和FPGA中的寄存器交換數(shù)據(jù),準(zhǔn)備下一次傳輸。 圖8 1個(gè)數(shù)據(jù)包的采集時(shí)序圖 圖9為1 Byte SPI數(shù)據(jù)傳輸采集圖。SPI_CLK的周期為100 ns,頻率為10 MHz。從圖9可以看到MOSI的輸出數(shù)據(jù)和FPGA要發(fā)送的數(shù)據(jù)是完全一致的。 圖9 SPI數(shù)據(jù)采集圖 本系統(tǒng)實(shí)現(xiàn)了基于FPGA和EC-01M芯片的Ethercat主站控制系統(tǒng)設(shè)計(jì)。在FPGA上設(shè)計(jì)了SPI EtherCAT主站控制邏輯,使用STM32 MCU通過(guò)FSMC總線接口訪問(wèn)FPGA內(nèi)的SPI控制器,實(shí)現(xiàn)了MCU與EtherCAT主站通信的需求。經(jīng)過(guò)仿真測(cè)試與實(shí)際硬件測(cè)試,證明了該系統(tǒng)工作正常、可靠。為EtherCAT主站控制系統(tǒng)在嵌入式系統(tǒng)的應(yīng)用提供了一種切實(shí)可行的設(shè)計(jì)方法。3 系統(tǒng)仿真與測(cè)試
4 結(jié)束語(yǔ)