,,,
(西安工程大學 電子信息學院,西安 710048)
傳統的點對點通信方式,不論從經濟成本還是從今后的系統維護上來說,都給工作者帶來一定的困難。然而,隨著網絡通信時代的發展,利用單片機擴展以太網通信,實現網絡數據傳輸的功能已經成為一種普遍的現象。例如,新余鋼鐵有限責任公司利用以太網資源的優勢,提出利用以太網通信的方式完成數據傳輸的功能[9]。單片機以太網接入方案一般按TCP/IP協議棧的不同分為兩大類:第一類是傳統的軟件TCP/IP協議棧方案,即由MCU+MAC+PHY再加入網絡接口實現以太網的物理連接,通過在主控芯片中植入TCP/IP協議代碼實現通信及上層應用;第二類是硬件TCP/IP協議棧方案,即由MCU+硬件協議棧芯片(內含MAC和PHY)直接加網絡接口,所有處理TCP/IP協議的工作都是通過MCU的硬件協議棧芯片來完成[1-3]。
從中斷請求次數方面來說,硬件協議棧的加入協助單片機處理了幾乎所有的TCP/IP協議工作,不僅極大地減少了單片機的中斷次數,讓單片機騰出更多資源去完成其它工作,而且硬件化的電路處理協議會更加快速、穩定;從安全性方面來說,硬件化的邏輯門電路來處理TCP/IP協議是不可攻擊的,充分彌補了網絡協議安全性不足的短板。所以在這里選擇了硬件TCP/IP協議棧方案,就是一種基于STM32F407的應用系統通過SPI串口直接進行外部擴展以太網的形式,快速方便地實現網絡數據傳輸。
近年來開發STM32比較流行的一個工具STM32CubeMX,它是意法半導體的主動原創工具,可以縮短開發的工作時間,降低費用,它也是一個圖形化的工具,配置和完成開發初期關于芯片相關的一些初始化代碼[8]。同時也集成了一個全面的軟件平臺,支持STM32每一個系列的MCU開發。快速完成初始化代碼的配置,提高了代碼編寫速度。W5500是WIZnet公司推出的一款內部集成硬件協議棧的高性能以太網接口芯片,它擁有早期芯片的所有主要優勢。全硬件協議棧技術采用硬件邏輯門電路實現復雜的TCP/IP協議簇,與傳統協議棧相比,它卸載了用于處理協議棧的MCU部分的線程,節約了MCU內部ROM等硬件資源,具有應用快速簡單、安全性好、可靠性高等優勢;內部集成了MAC和PHY工藝,使得接入以太網方案的硬件設計更為簡捷和高效。W5500提供了SPI(外設串行接口),從而能夠更加容易與外設MCU整合,方便開發者使用。
本文搭建了基于LabVIEW和STM32F4的軟硬件平臺系統進行測試。首先采用ST開發的STM32CubeMX來進行STM32F407的相應初始化配置,結合改進前后的W5500庫函數快速完成從機端發送數據的程序配置,使用PC端的LabVIEW完成主機端的定時接收數據程序配置,通過統計通信數據讀取的起止時間實現以太網通信數據傳輸速率的測試。對比W5500庫函數改進前后,其通信速率相對改進前提高近2倍。
基于STM32CubeMX的W5500以太網模塊通信速率測試系統主要包括STM32F407應用系統、W5500以太網控制器、PC端的LabVIEW。首先,W5500以太網控制芯片與STM32F407單片機通過SPI直連方式連接,W5500以太網控制芯片與PC機端通過以太網口連接,STM32F407單片機可直接通過命令調用以太網控制芯片W5500官方庫函數,且采用以太網控制芯片內置的TCP/IP協議棧,將其單片機作為服務器端,利用上位機LabVIEW作為客戶端來進行數據通信。為了驗證設計方案的有效性及測試通信速率,搭建了基于LabVIEW和STM32F4的軟硬件平臺系統進行測試。在保證硬件連接正確和通信成功的前提下,統計通信數據讀取的起止時間并實時觀察以太網通信數據傳輸速率。基于STM32CubeMX的W5500以太網通信的系統總體方案如圖1所示。

圖1 測試系統方案框圖

圖2 測試系統硬件連接圖
基于STM32CubeMX的W5500快速以太網通信硬件設計主要是W5500以太網模塊通過SPI總線與STM32F407單片機直接連接。測試系統硬件連接如圖2所示。W5500提供了新的SPI高速外設串行接口作為主機接口,同時SPI在芯片的引腳占用4根線,節省了芯片的引腳,也在PCB的布局上節省了空間,W5500以太網模塊SPI的4根線SDI(數據輸入)、SDO(數據輸出)、SCLK(時鐘)、CS(片選)連接單片機STM32F4上SPI接口的4個引腳。在SPI進行數據傳輸的過程中,W5500提供兩種數據傳輸長度可選的數據傳輸方式,數據固定長度和數據長度可選的數據傳輸模式。W5500以太網模塊自帶的RJ45網口與路由器連接,從而有一定的IP、端口號,方便與上位機完成通信功能。可變數據長度模式W5500與STM32F407硬件接口框圖如圖3所示。

圖3 可變數據長度模式W5500與STM32F407硬件接口框圖
基于STM32CubeMX的W5500快速以太網通信的軟件程序設計主要包括基于STM32F407服務器端的軟件程序設計和基于LabVIEW客戶端的軟件程序設計。其中,服務器端的軟件程序包括STM32CubeMX初始化、W5500初始化以及移植程序。
3.1.1 STM32CubeMX的初始化配置
該方案是以STM32F407處理器為基礎來外擴W5500以太網控制器,為了提升開發速率,這里選擇利用STM32CubeMX快速完成STM32F407初始化配置程序的設計。采用STM32CubeMX軟件進行程序配置的步驟如下:
① 打開STM32CubeMX軟件,點擊New Project,新建工程。
② 根據MCU型號對板子進行選擇,本方案所選用的是STM32F407ZET6。首先,在Series中選擇STM32F4,Lin中選擇STM32F407/417,然后就出現STM32F407ZETx這個選項,雙擊它,進入引腳配置界面,直接對引腳右鍵勾選所需的配置,十分方便。
③ 首先進行SPI(外設串行接口)配置,這里選擇使用STM32F407ZETx的SPI1接口與W5500網絡適配板進行連接,并選擇Full-Duplex Master模式,接著在Clock Configuration選項配置SPI1的工作時鐘頻率,為了提升通信速率,將SPI1時鐘由21 MHz提升為42 MHz;再進行RCC時鐘配置,勾選Crystal/Ceramic Resonator選項;最后進行串口配置,這里選擇USART1,勾選Asynchronous模式。
利用STM32CubeMX方便快速地完成STM32F407初始化配置,點擊生成工程文件按鈕,生成工程文件。之后用編譯器打開,方便編寫所需代碼。
3.1.2 W5500以太網初始化配置及移植程序設計
對于W5500以太網模塊的程序設計,首先需要去WIZnet官網下載W5500驅動源碼,再將其驅動源碼移植到工程文件目錄,主要是添加socket.c、w5500.c、wizchip_conf.c三個文件。其中,socket.c主要介紹W5500的Socket相關配置函數,比如Socket的打開、關閉、接收數據、發送數據等;w5500.c主要介紹W5500的寄存器讀寫過程;wizchip_conf.c主要配置W5500的MAC、IP地址,以及基本的數據讀寫過程、復位設置函數等。在移植W5500官方庫函數時,為避免w5500.c中引用#include"stm32f4xx_hal.h"與#include"stm32f4xx_hal_spi.h"時,與stm32f407xx.h文件中聲明的IMR與RCR產生沖突,并且在系統板子不改變的情況下,對其W5500原始庫函數進行了相應的改進,即將w5500.h中定義和涉及的IMR與RCR替換成了W5500_IMR與W5500_RCR。為了防止當更大量數據存在時,可能有數據丟失情況,在這里選擇通過提高通信速率來避免。所以在w5500.c文件中,重新修改了以下4個函數:WIZCHIP_READ()、WIZCHIP_WRITE()、WIZCHIP_READ_BUF()、WIZCHIP_WRITE_BUF()。在這里就其中一個函數做說明,例如在WIZCHIP_WRITE()函數只定義了WIZCHIP_CRITICAL_ENTER()和WIZCHIP.CS._select()函數,修改成在這兩個函數前面添加8位整型的發送數組和接收數組,即send_array[4]和receive_array[4],修改的主要作用是將SPI的逐一查詢傳輸方式改為按幀查詢傳輸方式,提高一定數據傳輸通信速率。具體的修改如下所示,首先展示出修改前的WIZCHIP_WRITE()函數程序代碼:
void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb){
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
#if((_WIZCHIP_IO_MODE_&_WIZCHIP_IO_MODE_SPI_))
#if(_WIZCHIP_IO_MODE_==_WIZCHIP_IO_MODE_SPI_VDM_)
AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_);
#elif( _WIZCHIP_IO_MODE_==_WIZCHIP_IO_MODE_SPI_FDM_)
AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_FDM_OP_LEN1_);
#else
#error "Unsupported _WIZCHIP_IO_SPI_ inW5500 !!!"
#endif
WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000)>>16);
WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00)>>8);
WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF)>>0);
WIZCHIP.IF.SPI._write_byte(wb);
#elif ((_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_))
#if(_WIZCHIP_IO_MODE_==_WIZCHIP_IO_MODE_BUS_DIR_)
#elif(_WIZCHIP_IO_MODE_==_WIZCHIP_IO_MODE_BUS_INDIR_)
#else
#error "Unsupported _WIZCHIP_IO_MODE_BUS_ inW5500 !!!"
#endif
#else
#error "Unknown _WIZCHIP_IO_MODE_ in W5500. !!!"
#endif
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
}
接著展示出修改后的WIZCHIP_WRITE()函數程序代碼:
void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb){
unsigned char send_array[4],receive_array[4];
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
#if((_SPI_DMA_ & 0x01))
#if((_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
#if(_WIZCHIP_IO_MODE_==_WIZCHIP_IO_MODE_SPI_VDM_)
AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_);
#elif(_WIZCHIP_IO_MODE_==_WIZCHIP_IO_MODE_SPI_FDM_)
AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_FDM_OP_LEN1_);
#else
#error "Unsupported _WIZCHIP_IO_SPI_ in W5500 !!!"
#endif
send_array[0]=(AddrSel & 0x00FF0000)>>16;
send_array[1]=(AddrSel & 0x0000FF00)>>8;
send_array[2]=(AddrSel & 0x000000FF)>>0;
send_array[3]=wb;
HAL_SPI_TransmitReceive(&hspi1,send_array,receive_array,4,100);
#elif ((_WIZCHIP_IO_MODE_&_WIZCHIP_IO_MODE_BUS_))
#if(_WIZCHIP_IO_MODE_==_WIZCHIP_IO_MODE_BUS_DIR_)
#elif(_WIZCHIP_IO_MODE_==_WIZCHIP_IO_MODE_BUS_INDIR_)
#else
#error "Unsupported _WIZCHIP_IO_MODE_BUS_ in W5500 !!!"
#endif
#else
#error "Unknown _WIZCHIP_IO_MODE_ in W5500 !!!"
#endif
#else
#if((_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_))
#if(_WIZCHIP_IO_MODE_==_WIZCHIP_IO_MODE_SPI_VDM_)
AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_);
#elif(_WIZCHIP_IO_MODE_==_WIZCHIP_IO_MODE_SPI_FDM_)
AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_FDM_OP_LEN1_);
#else
#error "Unsupported _WIZCHIP_IO_SPI_ in W5500 !!!"
#endif
WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000)>>16);
WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00)>>8);
WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF)>>0);
WIZCHIP.IF.SPI._write_byte(wb);
#elif ((_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) )
#if(_WIZCHIP_IO_MODE_==_WIZCHIP_IO_MODE_BUS_DIR_)
#elif(_WIZCHIP_IO_MODE_==_WIZCHIP_IO_MODE_BUS_INDIR_)
#else
#error "Unsupported _WIZCHIP_IO_MODE_BUS_ in W5500 !!!"
#endif
#else
#error "Unknown _WIZCHIP_IO_MODE_ in W5500. !!!"
#endif
#endif
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
}
其他三個函數修改思路類似于WIZCHIP_WRITE()函數。具體的代碼在這里就不展出了。
其中,W5500的初始化過程為:首先主處理器配置與W5500相連接的I/O端口,配置I/O端口的輸入輸出方式;主處理器與W5500之間采用SPI串行接口方式,因此需要編寫與SPI通信相關的API函數,即在通信過程中用到的讀寫數據函數;通過SPI接口配置W5500的各寄存器值,具體包括W5500網關地址寄存器、子網掩碼寄存器、模塊物理地址寄存器和IP地址寄存器;最后需要配置W5500為TCP服務器端模式,同時還需要設置發送緩存區和接收緩存區的大小,進行好所有初始化配置后即可對網關服務器進行Socket設置,當Socket處于初始化完成SOCK_INIT狀態,此時,作為TCP服務器就要執行listen()函數來偵聽端口。
3.1.3 W5500以太網通信模塊的主程序設計
對于STM32F407擴展W5500以太網模塊的主程序設計,包括STM32CubeMX程序設計和Keil MDK5程序設計。程序開始后,首先STM32F407單片機進行初始化,具體包括:HAL_Init()函數完成配置Flash預取功能;SystemClock_Config()函數實現外部時鐘晶振時鐘配置;MX_GPIO_Init()函數初始化所有I/O外設;MX_SPI1_Init()函數初始化SPI1外設串行接口;MX_USART1_UART_Init()函數進行串口的初始化。再對W5500進行初始化,包括設置其物理地址、網關IP、IP地址、子網掩碼、初始化內置TCP/IP協議棧,并初始化Socket為TCP服務器模式。在TCP服務器模式下,檢查PHY連接是否成功,如連接成功,進行網絡通信參數配置,接著打開Socket,進而判斷TCP連接是否成功,如連接成功,則認為Socket通信成功,W5500芯片產生中斷,那么清除中斷標志位,客戶端和服務器可以正常通信,進行收發數據的操作,反之,不能進行收發數據。W5500以太網通信模塊的主程序設計流程圖如圖4所示。

圖4 STM32CubeMX的W5500以太網通信主程序流程圖
LabVIEW的客戶端程序主要是基于LabVIEW的GUI軟件設計,通過自帶的TCP/IP協議完成與STM32F407單片機和W5500以太網模塊作為服務器的通信程序測試。

圖6 LabVIEW客戶端后面板
LabVIEW客戶端的軟件程序設計主要包括前面板程序設計和后面板程序設計。其中,前面板程序設計主要包括:開始、結束以及接收1000包TCP數據的時間、TCP 1000次讀取次數、通信傳輸速率以及數據傳輸波形顯示功能。圖5為客戶端接收服務器端發送的數據的前面板展示。

圖5 LabVIEW客戶端前面板
基于LabVIEW客戶端的后面板程序設計包括IP地址設置、端口設置、客戶端數據讀取數等。首先通過打開TCP函數指定IP地址192.168.1.128和端口號5 000。當與服務器端通信完成后,開始建立連接數據傳輸,通過讀取TCP數據函數一次性讀取2 048個字節,記錄開始接收數據的時間,當連續循環讀取1000次,接收完成后,再去獲取結束時間,計算出數據循環1000次所需時間,進而完成通信速率的測試。通信速率為通過數據傳輸大小/(結束時間-開始時間),得到傳輸速率大小并顯示在前面板上。圖6為客戶端接收服務器端發送數據的后面板展示。
在本系統設計方案中,搭建的基于LabVIEW和STM32F4的軟硬件平臺測試系統主要包括STM32F4系列的STM32F407應用系統、W5500以太網控制器、PC端的LabVIEW。其中,STM32F407應用系統通過SPI(外設串行接口)外擴W5500以太網控制器作為服務端,完成給客戶端發送數據;PC端的LabVIEW作為客戶端,完成接收服務器端發送的數據。 W5500再與路由器通過RJ45端口用雙絞線連接,聯合TCP/IP協議,進行調試并完成通信速率的測試。
在進行測試時,首先調試客戶端與服務器端的通信問題,在這里,同樣選擇由上位機LabVIEW來完成通信程序設計,聯合TCP/IP協議,當結果顯示表明通信測試成功。則接著對其進行通信速率測試,首先直接移植W5500官方提供的原始庫函數,進行單收單發數據傳輸,做10次實驗,最終平均傳輸速率可穩定在220 KB/s;對其W5500官方提供的原始庫函數進行一定修改,再次進行單收單發數據傳輸,同樣完成10次實驗,平均傳輸速率可穩定在414 KB/s。其中,直接移植W5500官方提供的原始庫函數,通信速率結果圖展示如圖7所示。進行修改后的W5500庫函數,通信速率結果圖展示如圖8所示。對官方提供的W5500庫函數進行修改前后,進行10次實驗對比,結果如表1所列。

表1 對官方提供的W5500庫函數進行修改前后的通信速率結果

圖7 直接移植W5500庫函數的通信速率結果圖

圖8 對W5500庫函數進行修改后的通信速率結果圖
在搭建的軟硬件平臺測試系統中,一方面選用ST開發的STM32CubeMX工具來配置開發初期關于STM32F407芯片相關的一些初始化代碼,方便快速;另一方面,直接移植W5500官方提供的原始庫函數,快速方便。兩者的結合,不僅節省了工作時間,還降低了開發成本。對于通過直接移植W5500官方提供的庫函數,發現數據傳輸速率過低,進而對其庫函數進行相應修改,最終提高了一定的通信速率,相比改進之前,數據傳輸通信速率提高了2倍左右。
