?? 網卡初始化.htm
字號:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0032)http://www.laogu.com/MY/tcp8.htm -->
<!-- saved from url=(0051)http://www.p8s.com.cn/magazine/files20002/lm/Lm.htm --><HTML><HEAD><TITLE>單片機與TCP/IP網絡</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<STYLE>.normal {
FONT-SIZE: 16pt; COLOR: #ff6666; LINE-HEIGHT: normal
}
.ourfont {
FONT-SIZE: 9pt; COLOR: #808080; LINE-HEIGHT: 13pt
}
A:link {
COLOR: #004080; FONT-FAMILY: "新細明體"; TEXT-DECORATION: underline
}
A:hover {
COLOR: #ff0000; TEXT-DECORATION: underline
}
</STYLE>
<META content="MSHTML 6.00.2900.3429" name=GENERATOR></HEAD>
<BODY bgColor=#d5eaea leftMargin=0 topMargin=0>
<P> </P>
<DIV align=center>
<CENTER>
<TABLE borderColor=#008080 height=1277 cellSpacing=4 cellPadding=4 width=600
border=6>
<TBODY>
<TR>
<TD width=600>
<P align=center><SPAN style="FONT-SIZE: 9pt"><FONT face=隸書 color=#800080
size=4> </FONT><FONT face=宋體> </FONT></SPAN><FONT face=隸書
color=#800080 size=4><STRONG>單片機與TCP/IP網絡<BR></STRONG></FONT><FONT
color=#800080><STRONG>--版主 老古</STRONG></FONT><FONT face=隸書
color=#800080><STRONG> <A href="http://www.laogu.com/"
target=_blank>http://www.laogu.com/</A></STRONG></FONT></P>
<P align=center><FONT color=#ff0033>(八)網卡初始化</FONT></P><B>
<HR color=#800080>
</B>
<P align=left>---- 完成復位之后,你要對網卡的工作參數進行設置.以使網卡開始工作.<BR>先介紹一個子函數<BR>#define
reg00 XBYTE[0xc000] //對應于地址240H 為命令寄存器CR地址</P>
<P align=left>void page(uchar pagenumber)<BR>{ uchar data temp;
<BR>temp=reg00;//command register <BR>temp=temp&<FONT
color=#ff0000>0x3f</FONT>;<BR>pagenumber=pagenumber <<6;
<BR>temp=temp | pagenumber;<BR>reg00=temp;<BR>}<BR><BR><FONT
color=#ff3333>錯誤修正:(2001年11月10日)
:以上程序有問題,在中斷驅動或發送數據包不作等待時,因為發送數據包的命令是讓TXP置位,如果在發送數據包的過程中,使用該函數,就會不斷地向外發送數據包.原因是TXP置位之后,只能是發完數據包的時候,由網卡內部將TXP位清0,命令不能使TXP清0,對該位寫入0沒有作用.讀取時要屏蔽該位,上面的程序修正如下,請用戶使用下面的程序:<BR>void
page(uchar pagenumber)<BR>{uchar data
temp;<BR>temp=reg00;<BR>temp=temp&<FONT color=#3333cc>0x3B</FONT>;
//注意不是0x3F
,TXP位在平時一定要置為0.<BR>pagenumber=pagenumber<<6<BR>temp=temp|pagenumber;<BR>reg00=temp;<BR>}<BR>從實驗當中也發現,只要再置位TXP位就可以重發該數據包(重發數據包時,不需要設置TPSTART,TBCR0,TBCR1).
</FONT></P>
<P align=left>作用是選擇指定的頁,網卡共有4頁寄存器,Ne2000兼容的有3頁。第四頁可以不用。 </P>
<P align=left>reg00命令寄存器:CR,command register,地址偏移量00H,為一個字節</P>
<TABLE cellSpacing=1 cellPadding=0 width=755 bgColor=#ccffff border=1>
<TBODY>
<TR>
<TD>位</TD>
<TD>7</TD>
<TD>6</TD>
<TD>5</TD>
<TD>4</TD>
<TD>3</TD>
<TD>2</TD>
<TD>1</TD>
<TD>0</TD></TR>
<TR>
<TD>名字</TD>
<TD>PS1</TD>
<TD>PS0</TD>
<TD>RD2</TD>
<TD>RD1</TD>
<TD>RD0</TD>
<TD>TXP</TD>
<TD>STA</TD>
<TD>STP</TD></TR>
<TR>
<TD> </TD>
<TD> </TD>
<TD> </TD>
<TD> </TD>
<TD> </TD>
<TD> </TD>
<TD> </TD>
<TD> </TD>
<TD> </TD></TR></TBODY></TABLE>
<P align=left>PS1和PS0這兩個位用來選擇寄存器頁,PS1 PS0=00時選擇寄存器頁0,=01時選擇寄存器頁1,
=10時選擇寄存器頁2,=11時選擇寄存器頁3.<BR>上面的程序的參數為pagenumber,用來指定第幾頁。<BR>temp=reg00
;//讀入命令寄存器的值。<BR>temp=temp&0x3f;//將高2位,即PS1,PS0清0<BR>pagenumber=pagenumber<<6;//將低2位移至高端<BR>temp=temp|pagenumber,
//寫入高2位<BR>reg00=temp; //設置第幾頁</P>
<P
align=left>當然也可以寫成更加簡單的幾句:<BR>temp=reg00&0x3f;<BR>pagenumber=pagenumber<<6;<BR>reg00=temp|pagenumber;
</P>
<P
align=left>但這樣對讀者來說不好理解。<BR>從執行的速度來說,上面的代碼也不是最快的。但作者主要講述原理,而不是探討最快的實現。<BR>--RD2,RD1,RD0這3個位代表要執行的功能。<BR>=001
讀網卡內存<BR>=010 寫網卡內存<BR>=011 發送網卡數據包<BR>=1**
完成或結束DMA的讀寫操作<BR>---TXP這個位寫入1時發送數據包,發完自動清零<BR>---STA,STP這兩個位用來啟動命令或停止命令<BR>=10
啟動命令<BR>=01 停止命令</P>
<P align=left>下面介紹網卡的初始化子程序:<BR>void ne2000init()<BR>{ reg00=0x21;
//選擇頁0的寄存器,網卡停止運行,因為還沒有初始化。<BR>reg01=0x4c; //寄存器Pstart<BR>reg02=0x80;
//Pstop<BR>reg03=0x4c; //BNRY<BR>reg04=0x45; //TPSR<BR>reg0c=0xcc;
//RCR<BR>reg0d=0xe0; //TCR<BR>reg0e=0xc8; //DCR 數據配置寄存器 8位數據dma
<BR>reg0f=0x00; //IMR disable all interrupt <BR>page(1);
//選擇頁1的寄存器<BR>reg07=0x4d; //CURR<BR>reg08=0x00; //MAR0<BR>reg09=0x41;
//MAR1<BR>reg0a=0x00; //MAR2<BR>reg0b=0x80; //MAR3<BR>reg0c=0x00;
//MAR4<BR>reg0d=0x00; //MAR5<BR>reg0e=0x00; //MAR6<BR>reg0f=0x00;
//MAR7<BR>reg00=0x22;//選擇頁0寄存器,網卡執行命令。 </P>
<P align=left><BR>} <BR><BR>PSTART 接收緩沖區的起始頁的地址。<BR>PSTOP
接收緩沖區的結束頁地址。(該頁不用于接收)<BR>BNRY 指向最后一個已經讀取的頁(讀指針)<BR>CURR
當前的接收結束頁地址。(寫指針)<BR><BR>--網卡含有16K字節的RAM,地址為0x4000-0x7fff(指的是網卡上的存儲地址,而不是ISA總線的地址,是網卡工作用的存儲器),每256個字節稱為一頁,共有64頁。頁的地址就是地址的高8位,頁地址為0x40--0x7f
。這16k的ram的一部分用來存放接收的數據包,一部分用來存儲待發送的數據包。當然也可以給用戶使用。(例如把網卡設置成使用8K的ram,另外8K的ram就可以用來給單片機作為存儲器,但我沒有這樣做,原因是操作網卡上的ram比較復雜)<BR>---在我的程序中使用0x40-0x4B為網卡的發送緩沖區,共12頁,剛好可以存儲2個最大的以太網包。使用0x4c-0x7f為網卡的接收緩沖區,共52頁。因此PSTART=0x4c,PSTOP=0x80(0x80為停止頁,就是直到0x7f,是接收緩沖區,不包括0x80)
剛開始,網卡沒有接收到任何數據包,所以,BNRY設置為指向第一個接收緩沖區的頁0x4c)
<BR>這四個寄存器用于接收的設置。<BR>--CURR是網卡寫內存的指針。它指向當前正在寫的頁的下一頁。那么初始化它就應該指向0x4c+1=0x4d
。網卡寫完接收緩沖區一頁,就將這個頁地址加一,<BR>CURR=CURR+1。這是網卡自動加的。當加到最后的空頁(這里是0x80,PSTOP)時,將CURR置為接收緩沖區的第一頁(這里是0x4c,PSTART),也是網卡自動完成的。當CURR=BNRY時,表示緩沖區全部被存滿,數據沒有被用戶讀走,這時網卡將停止往內存寫數據,新收到的數據包將被丟棄不要,而不覆蓋舊的數據。此時實際上出現了內存溢出。<BR>---而BNRR要由用戶來操作。用戶從網卡讀走一頁數據,要將BNRY加一,然后再寫到BNRY寄存器。
當BNRY加到最后的空頁(0x80,PSTOP)時,同樣要將BNRY變成第一個接收頁(PSTART,0x4c)BNRY=0x4c;<BR>---CURR和BNRY主要用來控制緩沖區的存取過程,保證能順次寫入和讀出)。<BR>當CURR=BNRY+1(或當BNRY=0x7f
,CURR=0x4c)時,網卡的接收緩沖區里沒有數據,表示沒有收到數據包。
用戶通過這個判斷知道沒有包可以讀。當上述條件不成立時,表示接收到新的數據包。然后用戶應該讀取數據包,直到上述條件成立時,表示所以數據包已經讀完,此時停止讀取數據包。<BR>--TPSR
為發送頁的起始頁地址。初始化為指向第一個發送緩沖區的頁,0x40。<BR>--RCR
接收配置寄存器,設置為使用接收緩沖區,僅接收自己的地址的數據包(以及廣播地址數據包)和多點播送地址包,小于64字節的包丟棄(這是協議的規定,設置成接收是用于網絡分析),校驗錯的數據包不接收。<BR>--TCR
發送配置寄存器,啟用crc自動生成和自動校驗,工作在正常模式。<BR>--DCR
數據配置寄存器,設置為使用FIFO緩存,普通模式,8位數據傳輸模式,字節順序為高位字節在前,低位字節在后(符合我們的習慣)(如果用16位的單片機,設置成16位的數據總線操作會更快,但80c52是8位總線的單片機)<BR>--IMR
中斷屏蔽寄存器,設置成0x00,屏蔽所有的中斷。設置成0xff將允許中斷)<BR>--MAR0--MAR8是設置多點播送的參數,這點我也不是很清楚,我從電腦讀出來是什么數,我也將這8個寄存器設置成這幾個數.
由于我們不使用多點播送,所以不要緊,只要保證網卡能正常工作就可以了。<BR>--PAGE2的寄存器是只讀的,所以不可以設置,不用設置,PAGE3的寄存器不是NE2000兼容的,所以也不用設置。
</P>
<P align=justify><FONT
size=+1>(未完)</FONT></P></TD></TR></TBODY></TABLE></CENTER></DIV></BODY></HTML>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -