單片機以太網控制芯片W7100A數據手冊(四)
例1:SOCKET 0 : 8KB, SOCKET 1 : 2KB
0xFE401E | 0xFE411E |
0x08 | 0x02 |
例2:SOCKET 2 : 1KB, SOCKET 3 : 1KB
0xFE421E | 0xFE431E |
0x01 | 0x01 |
例3: SOCKET 4 : 1KB, SOCKET 5 : 1KB
0xFE441E | 0xFE451E |
0x01 | 0x01 |
例4: SOCKET 6 : 1KB, SOCKET 7 : 1KB
0xFE461E | 0xFE471E |
0x01 | 0x01 |
從上面的例1~例4可以看出,8個SOCKET的RX存儲器之和為16K字節。
Sn_TXMEM_SIZE (SOCKET n發送存儲器大小寄存器)[R/W][0xFE401F + 0x100n][0x02]
它配置SOCKET的內部TX存儲器。每個SOCKET的TX存儲器可配置的大小為1、2、4、8、16K字節。復位后默認為2K字節。8個SOCKET的TX存儲器之和為16K字節。
例5:SOCKET 0 : 4KB, SOCKET 1 : 1KB
0xFE401F | 0xFE411F |
0x04 | 0x01 |
例6: SOCKET 2 : 2KB, SOCKET 3 : 1KB
0xFE421F | 0xFE431F |
0x02 | 0x01 |
例7:SOCKET 4 : 2KB, SOCKET 5 : 2KB
0xFE441F | 0xFE451F |
0x02 | 0x02 |
例8:SOCKET 6 : 2KB, SOCKET 7 : 2KB
0xFE461F | 0xFE471F |
0x02 | 0x02 |
從上面例5~例8所示,8個SOCKET的TX存儲器之和為16K字節。
Sn_TX_FSR (SOCKET n發送存儲器剩余空間大小寄存器)[R][(0xFE4020 + 0x100n) – (0xFE4021 + 100n)][0x0000]
它指示SOCKET n的內部TX存儲器可使用的空間大小(可寫入的傳輸數據的字節數)。主機不能寫入比Sn_TX_FSR更多的數據到TX存儲器。因此 , 在向TX存儲器寫入發送數據前檢查Sn_TX_FSR,如果要寫入的數據字節數小于或等于Sn_TX_FSR,才可以寫入數據到TX存儲器然后用SEND或SEND_MAC命令發送。
在TCP模式,如果對端接收到所發送的數據包(如果收到從對端來的DATA/ACK數據包),Sn_TX_FSR將自動增加,增加量就是已發送的字節數。在其它模式,只要Sn_IR(SENDOK)=1,Sn_TX_FSR就自動增加,增加量就是傳輸的數據長度。
例:S0_TX_FSR0的值為2048(0x0800),
0xFE4020 | 0xFE4021 |
0x08 | 0x00 |
Sn_TX_RD (SOCKET n發送存儲器讀指針寄存器)[R][(0xFE4022 + 0x100n) – (0xFE4023 + 0x100n)][0x0000]
該寄存器顯示TX存儲器最后結束傳輸的地址值。對SOCKET n的命令控制寄存器寫入SEND命令,它將從當前的Sn_TX_RD地址開始傳輸數據,直到Sn_WR_WR地址為止。在傳輸結束后該寄存器的值自動改變。因此在傳輸結束后,Sn_TX_RD和Sn_TX_WR的值是相等的。讀該寄存器時,先讀取它的高字節(0xFE4022,0xFE4122,0xFE4222,0xFE4322,0xFE4422, 0xFE4522,0xFE4622,0xFE4722),然后再讀它的低字節(0xFE4023,0xFE4123,0xFE4223, 0xFE4323,0xFE4423,0xFE4523,0xFE4623,0xFE4723),這樣讀取的數據才正確。
Sn_TX_WR (SOCKET n發送存儲器寫指針寄存器)[R/W][(0xFE4024 + 0x100n) – (0xFE4025 + 0x100n)][0x0000]
該寄存器提供定位信息,指示數據應該寫入到什么位置。讀取該寄存器時,先讀取高字節(0xFE4024,0xFE4124,0xFE4224,0xFE4324,0xFE4424,0xFE4524,0xFE4624,0xFE4724),然后再讀取低字節(0xFE4025,0xFE4125,0xFE4225,0xFE4325,0xFE4425,0xFE4525,0xFE4625, 0xFE4725),這樣讀取的數據才正確。
例:S0_TX_WR的值為2048(0x0800)。
0xFE4024 | 0xFE4025 |
0x08 | 0x00 |
但這個值本身不是可以直接訪問的物理地址。實際訪問的物理地址計算如下:(請參考W7100A驅動程序)
1.從Sn_TXMEM_SIZE(n)計算出端口n TX存儲器的基地址(SBIUFBASEADDRES(n))和掩碼地址(SMASK(n)),詳細內容參看所提供的源代碼。
2.將Sn_TX_WR0和SMASK(n)進行’位與’運算,其結果就是在端口n的TX存儲器范圍內的偏移地址(dst_mask)。
3.將dst_mask和SUBFBASEADDRESS(n)相加得到實際訪問的物理地址(dst_ptr)。現在可以將需要傳輸的數據寫到dst_ptr。(*有一種情況需要注意,寫入數據時可能會超過端口n的TX存儲器的上界。這時將數據寫入上邊界地址后,再從SBUFBASEADDRESS(n)開始寫入剩余的數據,如此循環寫入操作。)
操作完成后,Sn_TX_WR的值必須加上當前寫入數據的字節數。最后向Sn_CR(端口n的命令寄存器)發出SEND命令。詳細信息參考TCP服務器模式下發送數據的源代碼。
圖8.3 計算物理地址
Sn_RX_RSR (SOCKET n RX接收數據長度寄存器)[R][(0xFE4026 + 0x100n) – (0xFE4027 + 0x100n)][0x0000]
它指示SOCKET n內部RX存儲器中接收數據的字節數。由于該值是由Sn_Rx_RD和Sn_Rx_WR的在內部計算得出的,對SOCKET n的命令寄存器(Sn_CR)寫入RECV命令且接收到遠程的數據時,它將自動改變。當讀取該寄存器時,用戶應該首先讀取高字節(0xFE4026,0xFE4126,0xFE4226,0xFE4326,0xFE4426,0xFE4526,0xFE4626,0xFE4726),然后再讀低字節(0xFE4027,0xFE4127,0xFE4227,0xFE4327,0xFE4427,0xFE4527,0xFE4627, 0xFE4727),這樣才能夠得到正確的值。
例:S0_RX_RSR0的值為2048(0x0800)
0xFE4026 | 0xFE4027 |
0x08 | 0x00 |
這個值的總長度是由RX存儲器大小寄存器決定的。
Sn_RX_RD (SOCKET n RX接收存儲器讀指針寄存器)[R/W][(0xFE4028 + 0x100n) – (0xFE4029 + 0x100n)][0x0000]
該寄存器確定接收數據的讀取地址信息。當讀取該寄存器時先讀高字節 (0xFE4028,0xFE4128,0xFE4228,0xFE4328,0xFE4428,0xFE4528,0xFE4628,0xFE4728),然后再讀低字節(0xFE4029,0xFE4129,0xFE4229,0xFE4329,0xFE4429,0xFE4529,0xFE4629, 0xFE4729),這樣讀取的信息才正確。
例:S0_RX_RD02048的值為(0x0800)
0x0428 | 0x0429 |
0x08 | 0x00 |
但這個值不是實際要讀取的物理地址。實際的物理地址需要由下面的關系計算獲得:
1.由Sn_RXMEM_SIZE(n)獲得SOCKET n的RX存儲器的基地址(RBUFBASEADDRESS(n))和SOCKET n的RX掩碼地址(RMASK(n))。
2.將Sn_RX_RD0和RMASK(n)進行’位與’運算,得到SOCKET的RX存儲器地址范圍內的偏移地址(src_mask)。
3.將src_mask和RBUFBASEADDRESS(n)相加得到實際要訪問的物理地址。
現在可以從src_ptr地址讀取接收的數據(有一種特殊情況要注意,讀取的地址超過了SOCKET的RX存儲器的上邊界,這時讀完上邊界地址的數據后,返回到RBUFBASEADDRESS(n)地址讀取剩余的數據,如此循環訪問)。
完成操作后,Sn_RX_RD的值必須加上當前讀取的字節數(一定不能超過你讀取的字節數)。最后對Sn_CR命令寄存器寫入RECV命令,即完成操作。
更多詳細信息請參考TCP服務器模式下接收數據的源代碼。
Sn_RX_WR (SOCKET n RX接收存儲器寫指針寄存器)[R/W][(0xFE402A + 0x100n) – (0xFE402B + 0x100n)][0x0000]
它指示端口n內部RX存儲器中接收數據的字節數。由于該值是由Sn_Rx_RD和Sn_Rx_WR在內部計算得出的,對SOCKET n的命令寄存器(Sn_CR)寫入RECV命令且接收到遠程的數據時,它將自動改變。當讀取該寄存器時,用戶應該首先讀取高字節(0xFE4026,0xFE4126,0xFE4226,0xFE4326,0xFE4426,0xFE4526,0xFE4626,0xFE4726),然后再讀低字節(0xFE4027,0xFE4127,0xFE4227,0xFE4327,0xFE4427,0xFE4527,0xFE4627, 0xFE4727),這樣才能夠得到正確的值。
例:S0_RX_WR0的值為2048(0x0800)
0xFE402A | 0xFE402B |
0x08 | 0x00 |
Sn_FRAG(SOCKET n分段寄存器)[R/W][(0xFE402D + 0x100n) – (0xFE402E + 0x100n)][0x4000]
該它設置IP層的IP包頭中的分段字段。W7100不支持IP層的分段。即使配置了Sn_FRAG,IP數據包也不能夠分段。它需要在OPEN命令之前設置該寄存器。
例:Sn_FRAG0 = 0x4000(不分段)
0xFE402D | 0xFE402E |
0x40 | 0x00 |
9. 功能描述
因為W7100A內部嵌入一個8051兼容的CPU內核和硬件的TCP/IP內核,它可以不需要其它
器件而獨立工作。在這一節,將通過一些軟件源代碼,講解7100A的初始化和每一種協議(TCP、UDP、IP raw、MACRAW)的通信方法。
9.1 初始化
W7100A的初始化分三個步驟:設置8051單片機,網絡信息和內部TX/RX存儲器。
l
1.中斷設置
允許或禁止8051的中斷。詳細信息參考第3節”中斷”。
2.存儲器訪問時序設置
通過CKCON(0x8E)和WTST(0x92)寄存器來設置存儲器的訪問時序。CKCON(0x8E)控制數據存儲器的訪問時序,而WTSR(0x92)控制程序存儲器的訪問時序,設置值為0~7之間。但W7100A的CKCON可以設置的值為1~7,而WTST(0x92)的值只能是4~7,其它值都無效。如果用戶設置的值是一個無效值,W7100將不能夠正常工作。詳細信息請參考2.4節“SFR的定義”。
例:禁止中斷,訪問數據存儲器2個時鐘周期,訪問程序存儲器7個時鐘周期,設置如下:
3.串口通信波特率,寄存器和中斷的設置
1)設置W7100A串口通信的相關寄存器。
與串口相關的寄存器有:TMOD、PCON和SCON。
①
SM2:
REN:接收允許(‘1’允許接收)。
TB8: 在模式2和模式3,發送的第8位數據位。
RB8: 在模式2和模式3,接收的第8位數據位。
TI:
RI:
2)初始化串口通信時必須設置中斷狀態。
因為串口通信使用中斷,因此在初始化串口通信時用戶必須禁止其它相關的中斷。
3)設置用戶使用的波特率。請參考6.6節’波特率設置的實例’了解W7100用于產生波特率的定時器。定時器的波特率計算如下:
①
TH1 = 256 – ((K * 88.4736MHz) / (384 * 波特率))
K = ‘1’ at SMOD = ‘0’, K = ‘2’ at SMOD = ‘1’
②
(RCAP2H, RCAP2L) = 65536 – (88.4736MHz / (32 * 波特率))
例:使用Timer1的模式2,SMOD = 1,時鐘頻率 = 88.4736MHz,波特率 = 115200
- 步驟2:設置網絡信息
1.網絡通信的基本信息
必須設置的網絡基本信息有:
(1)SHAR(源硬件地址寄存器)
源硬件地址由SHAR設置,必須說明的是在以太網MAC層的物理地址(MAC地址)一定是唯一的。IEEE管理MAC地址的分配。網絡設備的制造商給產品分配MAC地址。物理地址分配到詳細信息請參考下面網址:
http://www.ieee.org/,http://standards.ieee.org/regauth/oui/index.shtml
(2)GAR(網關地址寄存器)
(3)SUBR(子網掩碼寄存器)
(4)SIPR(源IP地址寄存器)
2.數據包發送失敗時,設置重發時間和次數
為了設置重發時間,寄存器需要設置如下:
(1)RTR(重發時間寄存器),RTR的’1’代表’100us’。
(2)RCR(重發次數寄存器)
- 步驟3:分配SOCKET n的內部TX/RX存儲器
每一個可配置的TX/RX存儲器的最大長度為16K字節。在16K字節的范圍內,用戶可以將存儲器給8個SOCKET任意分配為1K、2K、4K、8K、16K字節。但是TX和RX存儲器的設置的總和不能超過16K字節。(TXMAX=16KB,RXMAX=16KB)
圖9.1 SOCKET n內部TX/RX存儲器的分配
完成W7100A的這三步初始化,W7100A就可以通過以太網進行數據傳輸。此時,W7100A可以響應來自于網絡的Ping請求。
9.2 數據通信
初始化過程完成以后,W7100A就可以以TCP、UDP、IPRAW或MACRAW的模式打開SOCKET,并發送和接收數據。W7100A支持8個端口以不同的方式同時進行工作。在這一節將介紹每一種方式的通信方法。
9.2.1
TCP是一種面向連接的協議。TCP使用本機IP地址/端口號和目的IP地址/端口號產生連接。發送和接收數據都是通過這個連接的端SOCKET。
建立到SOCKET連接的方法是TCP服務器和TCP客戶端。它們的區別是誰主動發出連接請求(SYN數據包)。
TCP服務器監聽來自TCP客戶端的連接請求,接收發送的連接請求(被動打開),并產生連接。
TCP客戶端發出連接請求到TCP服務器(主動打開),并產生連接。
圖9.2 TCP服務器和TCP客戶端
9.2.1.1
圖9.3 “TCP服務器”操作流程
- SOCKET初始化
TCP數據通信需要對SOCKET進行初始化設置。初始化過程首先選擇W7100A的一個SOCKET(從W7100A的8個SOCKET中),設置協議模式(Sn_MR(P3:P0))和設置源端口號Sn_PORT0(TCP服務器的監聽端口號)。然后運行OPEN指令。執行OPEN命令后如果端口的狀態Sn_SR改變為SOCK_INIT,那么端口的初始化就完成了。
TCP服務器和TCP客戶端的端口初始化是完全相同的端口初始化為TCP模式的操作如下:
- 建立連接
當SOCKET的狀態Sn_SR為SOCK_LISTEN時,如果它收到SYN數據包,Sn_SR的狀態將改變為SOCK_SYNRECV,并發送一個SYN/ACK數據包,然后SOCKET n建立連接。SOCKET n建立連接以后才允許進行數據通信。有兩種方法可以驗證SOCKET n是否建立連接。
第一種方法:當收到數據包時,Sn_IR(RECV)置為1,如果主機在接收下一個數據包之前沒有置上一個Sn_IR(RECV)為’1’,那么W7100將不能夠識別下一個數據包的Sn_I(RECV),這是由于上一個Sn_IR(RECV)和后面的Sn_IR(RECV)重疊所致。因此,如果主機不能完全處理每一個Sn_IR(RECV)的數據包,則不推薦使用這種方法。
評論