周 鑫,張維佳
(武漢船用電力推進(jìn)裝置研究所,武漢 430064)
隨著嵌入式設(shè)備的快速發(fā)展,網(wǎng)絡(luò)技術(shù)的應(yīng)用廣泛。以太網(wǎng)接口以其傳輸速度快,效率高,實(shí)時(shí)性好等特點(diǎn)廣泛運(yùn)用于各嵌入式系統(tǒng)中,是信息傳遞的重要組成部分。在船用綜合保護(hù)裝置中,多采用以太網(wǎng)MODBUS/TCP 通信,經(jīng)常出現(xiàn)一對(duì)多進(jìn)行通訊,本文采取嵌入式多個(gè)網(wǎng)口,可以很好的解決這一問(wèn)題。通過(guò)以ARM 內(nèi)核的STM32F103zet6 單片機(jī)作為系統(tǒng)控制核心部分,dm9000c 作為網(wǎng)卡用于接收數(shù)據(jù)和發(fā)送數(shù)據(jù),通過(guò)軟件編程,實(shí)現(xiàn)下位機(jī)與上位機(jī)之間的TCP 協(xié)議網(wǎng)絡(luò)通信。
STM32F103 采是由STM 公司生產(chǎn)的32 位FLASH 存儲(chǔ)器單片機(jī),采用的是ARM Cortex-M3內(nèi)核的增強(qiáng)型芯片。其最高工作頻率為72MHZ,內(nèi)部數(shù)據(jù)路徑和寄存器都是32 位。具有高功能、低功耗、方便開(kāi)發(fā)。以太網(wǎng)接口是一個(gè)重要的外設(shè),通過(guò)雙絞線進(jìn)行數(shù)據(jù)傳輸,傳輸速度最快可達(dá)到100 MBPS 或1GBPS。
DM9000C,一個(gè)10/100M 自適應(yīng)的PHY 和4K DWORD 值的SRAM 。
DM9000C 是一款完全集成的、性價(jià)比高、引腳數(shù)少、帶有通用處理器接口的單芯片快速以太網(wǎng)控制器,并且DM9000C 屬于并口網(wǎng)卡。通過(guò)采用STM32 的FSMC 接口來(lái)驅(qū)動(dòng)DM9000C。該DM9000C 適用于提供支持8 位,16 位和32 位數(shù)據(jù)接口訪問(wèn)內(nèi)部存儲(chǔ)器,以支持不同的處理器。dm9000c 的特性可以自適應(yīng)10、100M 收發(fā)器,內(nèi)置16K 字節(jié)的SRAM,支持硬件幀校驗(yàn),并且dm9000c 存在多種型號(hào),有100 引腳,48 引腳。可以適用于不同型號(hào)的單片機(jī)芯片。
本項(xiàng)目采取通過(guò)STM32F103zet6 單片機(jī)同時(shí)控制2 個(gè)DM9000C 網(wǎng)卡芯片,連接兩個(gè)客戶端,實(shí)現(xiàn)同時(shí)進(jìn)行數(shù)據(jù)傳輸。
首先在main 函數(shù)中對(duì)DM9000C 進(jìn)行初始化,并設(shè)置好中斷優(yōu)先級(jí),再將發(fā)送的數(shù)據(jù)以TCP/IP幀格式進(jìn)行封包處理,然后將數(shù)據(jù)通過(guò)FSMC 寫(xiě)入SRAM 中,之后DM9000C 通過(guò)軟件編程實(shí)現(xiàn)的TCP 通信協(xié)議將數(shù)據(jù)從網(wǎng)口發(fā)送給上位機(jī)。兩個(gè)網(wǎng)口都是通過(guò)上述方法實(shí)現(xiàn)數(shù)據(jù)發(fā)送,且不會(huì)發(fā)生沖突。
STM32F103zet6 單片機(jī)通過(guò)接受中斷來(lái)接受發(fā)送過(guò)來(lái)的數(shù)據(jù)。DM9000C 先將遠(yuǎn)程數(shù)據(jù)接收后,放入緩存當(dāng)中,同時(shí)給單片機(jī)發(fā)送中斷信號(hào),單片機(jī)接到中斷信號(hào)后,就會(huì)開(kāi)始執(zhí)行程序代碼從FSMC 中將DM9000C 緩沖中的數(shù)據(jù)讀取出來(lái),進(jìn)行相應(yīng)的邏輯解析得到數(shù)據(jù)。這里要注意的是,兩個(gè)網(wǎng)口存放數(shù)據(jù)的地址是不一樣的,從DM9000C 中得到的數(shù)據(jù)要分別存放到不同緩存區(qū),并且如果是兩個(gè)DM9000C 傳輸,會(huì)產(chǎn)生兩個(gè)接收數(shù)據(jù)中斷信號(hào),這時(shí)要設(shè)置不同的中斷優(yōu)先級(jí),來(lái)區(qū)分?jǐn)?shù)據(jù)處理的先后順序,以免中斷被另一中斷打斷。
通過(guò)將DM9000C 的片選信號(hào)CS與單片機(jī)的NE2 相連,當(dāng)FSMC_NE2 發(fā)送低電平信號(hào)時(shí),此時(shí)運(yùn)行當(dāng)前DM9000C 芯片,注意的是另一個(gè)DM9000C 片選信號(hào)鏈接單片機(jī)的 NE1。DM9000C 的讀寫(xiě)信號(hào)RD 與WR 分別與單片機(jī)的NEW 和NOE 相連,另一個(gè)DM9000C 的鏈接方式一樣。
CMD 信號(hào)決定單片機(jī)是收發(fā)命令還是數(shù)據(jù),當(dāng)為1 時(shí),就是控制DM9000C 進(jìn)行寫(xiě)數(shù)據(jù)操作,當(dāng)為0 時(shí),就是控制DM9000C 進(jìn)行寫(xiě)命令操作。
首先在程序中將DM9000c 初始化:設(shè)置好接收中斷函數(shù),以及中斷優(yōu)先級(jí)。
并且分別定義 DM9000c 網(wǎng)卡芯片接在FSMC 的數(shù)據(jù)地址。
#define DM9000_DATE_BASE 0x60000002
這是其中一個(gè)數(shù)據(jù)地址;#define DM9000_DATE_BASE2 0x64000002
這是另一個(gè)數(shù)據(jù)地址,然后將接收到的數(shù)據(jù)存入到不同的緩存區(qū)。
這樣數(shù)據(jù)都已經(jīng)寫(xiě)入到了緩存當(dāng)中,同理另一個(gè)網(wǎng)口接收數(shù)據(jù)。之后將接收的數(shù)據(jù)按相應(yīng)的邏輯處理即可。
將已經(jīng)處理好的數(shù)據(jù),通過(guò)前面定義好的地址發(fā)送出去
由于定義的地址不同,所以兩個(gè)網(wǎng)口的數(shù)據(jù)并不會(huì)互相沖突。
圖2 DM9000c 讀時(shí)序
圖3 DM9000c 寫(xiě)時(shí)序
想要實(shí)現(xiàn)讀寫(xiě)寄存器,就必須先控制好CMD引腳。
先分別定義好兩個(gè)dm9000c 芯片的基地址,這里舉其中一個(gè)來(lái)說(shuō)明。
需要注意的是讀dm9000 里面的數(shù)據(jù)時(shí),需要判斷數(shù)據(jù)的長(zhǎng)度和dm9000 讀取數(shù)據(jù)時(shí)的狀態(tài)是否正常,這里可以根據(jù)需要做相應(yīng)邏輯上的異常處理。
在dm9000c 中,還有一些PHY 寄存器,PHY寄存器的地址空間為5 位。對(duì)這些寄存器的操作會(huì)影響網(wǎng)卡芯片的初始化和網(wǎng)絡(luò)連接。一般不對(duì)它進(jìn)行操作,一般PHY 寄存器采用分頁(yè)技術(shù),基本上所有的PHY 芯片擴(kuò)展都采用這種類似方案
至此,我們已經(jīng)寫(xiě)好了兩個(gè)最基本的函數(shù): int dm9000_tx()和structpbuf *dm9000_rx()。
dm9000c 將SRAM 作為緩存區(qū)用來(lái)接收和發(fā)送數(shù)據(jù),其中發(fā)送數(shù)據(jù)的緩存區(qū)大小為3KB。數(shù)據(jù)包以結(jié)構(gòu)體的形式發(fā)送到輸出數(shù)據(jù)緩存區(qū)內(nèi)。我們可以將這個(gè)結(jié)構(gòu)體理解成為一個(gè)鏈表,這樣傳輸數(shù)據(jù)的效率將會(huì)更高。
我們將playload 作為一個(gè)指針指向這個(gè)結(jié)構(gòu)體起始的位置。用len 表示數(shù)據(jù)的長(zhǎng)度。
Stm32 在發(fā)送數(shù)據(jù)之前通常會(huì)關(guān)閉dm9000網(wǎng)卡中斷,然后將數(shù)據(jù)寫(xiě)到SRAM 中,每次只寫(xiě)一個(gè)字的數(shù)據(jù),并判斷其長(zhǎng)度。隨后設(shè)置好發(fā)送寄存器,然后將SRAM 里的數(shù)據(jù)發(fā)送出去。這時(shí)如果緩存區(qū)里的數(shù)據(jù)沒(méi)有了,則表示已經(jīng)發(fā)送完成。之后再次將指針指向起始的位置。如果發(fā)送不成功則直接返回結(jié)束,并清除中斷標(biāo)記。詳細(xì)的流程圖如下:
由于是多個(gè)以太網(wǎng)口,需要注意的是發(fā)送數(shù)據(jù)的地址是不一樣的。
dm9000 接收數(shù)據(jù)的方式是通過(guò)中斷的形式接收的。接收數(shù)據(jù)之前會(huì)將中斷標(biāo)志清零并產(chǎn)生一個(gè)互斥變量鎖住dm9000c,避免這時(shí)處理其他信息導(dǎo)致處理信息紊亂。當(dāng)接收到的數(shù)據(jù)通過(guò)crc16 校驗(yàn)后,會(huì)產(chǎn)生一個(gè)中斷信號(hào),這個(gè)時(shí)候stm32 就可以在接收中斷發(fā)生時(shí),接收數(shù)據(jù)包并讀取數(shù)據(jù)包的長(zhǎng)度,隨后按照TCP 協(xié)議將其進(jìn)行解析,具體的流程圖如下:
圖4 數(shù)據(jù)包發(fā)送流程圖
圖5 數(shù)據(jù)包接收流程圖
要注意的是,接收數(shù)據(jù)時(shí)擴(kuò)開(kāi)內(nèi)存空間時(shí),要選用2 個(gè)不同的內(nèi)存空間,以免照成2 個(gè)網(wǎng)口接收數(shù)據(jù)紊亂,數(shù)據(jù)被互相覆蓋。并且判斷數(shù)據(jù)長(zhǎng)度時(shí)如果小于64 或者大于設(shè)定的數(shù)據(jù)最大長(zhǎng)度時(shí),要將數(shù)據(jù)丟除。
通過(guò)STM32 對(duì)數(shù)據(jù)包進(jìn)行封包和解析后。再通過(guò)dm9000c 進(jìn)行數(shù)據(jù)傳輸。采用tcp 通信進(jìn)行實(shí)驗(yàn)驗(yàn)證:
將STM32 作為服務(wù)器,將PC 端作為客戶端,將PC 端地址設(shè)為192.168.1.102,將服務(wù)器的2個(gè)網(wǎng)口芯片的IP 地址分別設(shè)為192.168.1.100;192.168.1.101。分別在PC 端ping 這兩個(gè)IP 地址,發(fā)現(xiàn)丟包率為0。實(shí)驗(yàn)結(jié)果表明,設(shè)計(jì)的以太網(wǎng)接口的可靠性高,傳輸速度快,丟包率低。為嵌入式設(shè)備通訊提供了有效的方案。
本文章介紹了,dm9000c 與stm32 單片機(jī)的硬件接口方案以及軟件接口方案和數(shù)據(jù)收發(fā)的原理以及軟件實(shí)現(xiàn)的流程。并通過(guò)TCP 網(wǎng)絡(luò)通信實(shí)驗(yàn)驗(yàn)證了該設(shè)計(jì)的可行性。