一、首先配置W5300
1、初始化GPIO
包括FSMC(靈活的靜態存儲控制器)的地址總線、數據總線、讀使能腳、寫使能腳,片選腳。
W5300與主機的接口有直接地址模式和間接地址模式兩種,總線又分為16位和8位兩種。另外,W5300可以根據TEST_MODE[3:0]的不同配置選擇內部PHY和外部PHY。本項目中,使用的是直接地址模式下的16位數據總線。
在16位數據總線模式下 ,只使用ADDR[9:1],而ADDR0接地或者懸空。因為“BIT16EN”有內部上拉,所以可以懸空。
硬件連接方式:
數據總線 |
數據總線 |
地址總線 |
片選 |
PD14 <-> FSMC_D0 |
PE13 <-> FSMC_D10 |
PF0 <-> FSMC_A0 |
PG10<->FSMC_NE3 |
PD15 <-> FSMC_D1 |
PE14 <-> FSMC_D11 |
PF1 <-> FSMC_A1 |
讀使能 |
PD 0 <-> FSMC_D2 |
PE15 <-> FSMC_D12 |
PF2 <-> FSMC_A2 |
PD4<->FSMC_NOE |
PD1 <-> FSMC_D3 |
PD8 <-> FSMC_D13 |
PF3 <-> FSMC_A3 |
寫使能 |
PE7 <-> FSMC_D4 |
PD9 <-> FSMC_D14 |
PF4 <-> FSMC_A4 |
PD5<->FSMC_NWE |
PE8 <-> FSMC_D5 |
PD10<-> FSMC_D15 |
PF5 <-> FSMC_A5 |
|
PE9 <-> FSMC_D6 |
|
PF12<->FSMC_A6 |
|
PE10 <-> FSMC_D7 |
|
PF13<->FSMC_A7 |
|
PE11 <-> FSMC_D8 |
|
PF14<->FSMC_A8 |
|
PE12 <-> FSMC_D9 |
|
PF15<->FSMC_A9 |
2、復位W5300
PLL鎖相環:將25MHZ的時鍾源經過6倍頻,建立150MHZ的時鍾用於內部單元的運行,如TCP/IP內核、主機接口管理和寄存器管理。鎖相環在復位后鎖定並提供穩定的時鍾信號。且W5300不支持上電復位,因此必須由外部系統給出復位信號。每個SOCKET在復位后分配8K字節。
3、配置W5300的MAC地址和IP地址
MAC地址:
IP地址:
二、freemodbus tcp
主機為客戶端那么modbus tcp支持多個主機,在一個局域網中可存在多個主機和多個從機。
2.1 modbus TCP和modbus RTU區別
【1】從機地址變得不再重要,多數情況下忽略。從某種意義上說從機地址被IP地址取代;
【2】CRC校驗變得不再重要,甚至可以忽略。由於TCP數據包中已經存在校驗,為了不重復造輪子,modbus TCP干脆取消了CRC校驗。
modbus TCP和modbus RTU的區別可使用下圖概括:
modbus TCP數據包和modbus RTU數據包比較
在modbus TCP中包含一個MBAP頭,該頭包含以下幾個部分
區域 |
長度 |
描述 |
客戶端 |
服務器 |
傳輸標志 |
2字節 |
MODBUS 請求和響應傳輸過程中序列號 |
客戶端生成 |
應答時復制該值 |
協議標志 |
2字節 |
Modbus協議默認為0 |
客戶端生成 |
應答時復制該值 |
長度 |
2字節 |
剩余部分的長度 |
客戶端生成 |
應答時由服務器端生成 |
單元標志 |
1字節 |
從機標志(從機地址) |
客戶端生成 |
應答時復制該值 |
注意
【1】傳輸標志可理解為序列號,防止MODBUS TCP通信錯位,例如后發生的響應先到了主機,而早發生的響應后到主機
【2】單元標志可理解為從機地址,此時已經不再重要
2.2 modbus Tcp 和 TCP IP的關系
modbus TCP可以理解為發生在TCP上的應用層協議,既然是TCP協議那么一個完整的MODBUS TCP報文必然包括TCP首部,IP首部和Ethernet首部。
2.3 MODBUS TCP和RTU代碼實現
首先下載最新的modbus源碼,在https://www.embedded-experts.at/en/freemodbus-downloads/下載最新的版本freemodbus-v1.5,下載最新的協議不僅可以防止被人改動導致自己做無用功,保持原生態也可以很好的與制定者進行交流。解壓freemodbus-v1.5,目錄結構很清晰,主要有四個文件件,分別是demo、modbus、tools、doc。其中tools為上位機測試modbus程序,doc為一些說明文件先不討論。有用的是demo以及modbus。打開demo,沒有看到stm32的工程文件,有一個叫BARE的文件夾,是一些不包括任何處理器的部分源代碼,我們就用這個建立工程文件。
W5300工程中加入BARE的文件夾下的port以及modbus文件夾,將BARE的文件夾demo中的函數拷貝到W5300工程中。
2.3.1 定義本地端口
2.3.2 循環檢測W5300狀態寄存器Sn_SSR
①調用getSn_SR(SOCK_UDPS)函數檢測Sn_SSR寄存器的狀態,如果檢測socket關閉,則出現連接UDP;②如果socket處於UDP模式,調用getSn_RX_RSR(SOCK_UDPS),獲取Sn_RX_RSR(接收數據的字節長度寄存器,它指示SOCKET內部RX存儲器接收數據的字節長度)的狀態。③如果接收的字節長度大於0,調用recvfrom接收函數。④調用xMBPortEventPost( EV_FRAME_RECEIVED )函數,發送已接收到數據到modbus tcp狀態機。
eMBErrorCode eMBTCPInit( USHORT ucTCPPort )
eMBEnable()函數流程
eMBEventType枚舉類型變量定義了event事件的類型。
Modbus的主查詢函數eMBPoll()的流程
(1)當事件為EV_FRAME_RECEIVED(接收到完整數據幀)時,調用peMBFrameReceiveCur函數,即modbus RTU或者TCP接收處理函數。
xMBTCPPortGetRequest()函數中** ppucMBTCPFrame為一個指向數據的指針,而*ppucMBTCPFrame可以指向一個數組,在這里可把ucTCPRequestFrame復制給該變量,配合usTCPLength,那么從uIP接收到的內容就”轉移“到freemodbus中。
(2)當事件為EV_EXECUTE(接收功能函數)時,按照eMBPoll()的EV_EXECUTE事件流程。peMBFrameSendCur()函數→eMBTCPSend()函數→xMBTCPPortSendResponse()函數。