📄 428.htm
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>CTerm非常精华下载</title>
</head>
<body bgcolor="#FFFFFF">
<table border="0" width="100%" cellspacing="0" cellpadding="0" height="577">
<tr><td width="32%" rowspan="3" height="123"><img src="DDl_back.jpg" width="300" height="129" alt="DDl_back.jpg"></td><td width="30%" background="DDl_back2.jpg" height="35"><p align="center"><a href="http://202.112.58.200"><font face="黑体"><big><big>Tsinghua</big></big></font></a></td></tr>
<tr>
<td width="68%" background="DDl_back2.jpg" height="44"><big><big><font face="黑体"><p align="center"> 嵌入式系统 (BM: turbolinux jacobw) </font></big></big></td></tr>
<tr>
<td width="68%" height="44" bgcolor="#000000"><font face="黑体"><big><big><p align="center"></big></big><a href="http://cterm.163.net"><img src="banner.gif" width="400" height="60" alt="banner.gif"border="0"></a></font></td>
</tr>
<tr><td width="100%" colspan="2" height="100" align="center" valign="top"><br><p align="center">[<a href="嵌入式系统.htm">回到开始</a>][<a href="398.htm">上一层</a>][<a href="429.htm">下一篇</a>]
<hr><p align="left"><small>发信人: turbolinux (hoho~神啊,救救我吧...), 信区: Embedded <br>
标 题: 单片机与TCP/IP网络 (八) <br>
发信站: BBS 水木清华站 (Fri Jul 13 00:35:57 2001) <br>
<br>
单片机与TCP/IP网络 <br>
--版主 老古 http://www.laogu.com <br>
<br>
(八)网卡初始化 <br>
<br>
<br>
------------------------------------------------------------------------ <br>
-------- <br>
<br>
---- 完成复位之后,你要对网卡的工作参数进行设置.以使网卡开始工作. <br>
先介绍一个子函数 <br>
#define reg00 XBYTE[0xc000] //对应于地址240H 为命令寄存器CR地址 <br>
<br>
void page(uchar pagenumber) <br>
{ uchar data temp; <br>
temp=reg00;//command register <br>
temp=temp&0x3f; <br>
pagenumber=pagenumber <<6; <br>
temp=temp | pagenumber; <br>
reg00=temp; <br>
} <br>
作用是选择指定的页,网卡共有4页寄存器,Ne2000兼容的有3页。第四页可以不用 <br>
。 <br>
<br>
reg00命令寄存器:CR,command register,地址偏移量00H,为一个字节 <br>
<br>
位 7 6 5 4 3 2 1 0 <br>
名字 PS1 PS0 RD2 RD1 RD0 TXP STA STP <br>
<br>
<br>
PS1和PS0这两个位用来选择寄存器页,PS1 PS0=00时选择寄存器页0,=01时选择寄存 <br>
器页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; //设置第几页 <br>
<br>
当然也可以写成更加简单的几句: <br>
temp=reg00&0x3f; <br>
pagenumber=pagenumber<<6; <br>
reg00=temp|pagenumber; <br>
<br>
但这样对读者来说不好理解。 <br>
从执行的速度来说,上面的代码也不是最快的。但作者主要讲述原理,而不是探讨 <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 停止命令 <br>
<br>
下面介绍网卡的初始化子程序: <br>
void ne2000init() <br>
{ reg00=0x22; //选择页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>
} <br>
<br>
PSTART 接收缓冲区的起始页的地址。 <br>
PSTOP 接收缓冲区的结束页地址。(该页不用于接收) <br>
BNRY 指向最后一个已经读取的页(读指针) <br>
CURR 当前的接收结束页地址。(写指针) <br>
<br>
<br>
--网卡含有16K字节的RAM,地址为0x4000-0x7fff(指的是网卡上的存储地址,而 <br>
不是ISA总线的地址,是网卡工作用的存储器),每256个字节称为一页,共有64页 <br>
。页的地址就是地址的高8位,页地址为0x40--0x7f 。这16k的ram的一部分用来存 <br>
放接收的数据包,一部分用来存储待发送的数据包。当然也可以给用户使用。(例 <br>
如把网卡设置成使用8K的ram,另外8K的ram就可以用来给单片机作为存储器,但我 <br>
没有这样做,原因是操作网卡上的ram比较复杂) <br>
---在我的程序中使用0x40-0x4B为网卡的发送缓冲区,共12页,刚好可以存储 <br>
2个最大的以太网包。使用0x4c-0x7f为网卡的接收缓冲区,共52页。因此 <br>
PSTART=0x4c,PSTOP=0x80(0x80为停止页,就是直到0x7f,是接收缓冲区,不包括 <br>
0x80) 刚开始,网卡没有接收到任何数据包,所以,BNRY设置为指向第一个接收 <br>
缓冲区的页0x4c) <br>
这四个寄存器用于接收的设置。 <br>
--CURR是网卡写内存的指针。它指向当前正在写的页的下一页。那么初始化它就 <br>
应该指向0x4c+1=0x4d 。网卡写完接收缓冲区一页,就将这个页地址加一, <br>
CURR=CURR+1。这是网卡自动加的。当加到最后的空页(这里是0x80,PSTOP)时, <br>
将CURR置为接收缓冲区的第一页(这里是0x4c,PSTART),也是网卡自动完成的。 <br>
当CURR=BNRY时,表示缓冲区全部被存满,数据没有被用户读走,这时网卡将停止 <br>
往内存写数据,新收到的数据包将被丢弃不要,而不覆盖旧的数据。此时实际上出 <br>
现了内存溢出。 <br>
---而BNRR要由用户来操作。用户从网卡读走一页数据,要将BNRY加一,然后再 <br>
写到BNRY寄存器。 当BNRY加到最后的空页(0x80,PSTOP)时,同样要将BNRY变成 <br>
第一个接收页(PSTART,0x4c)BNRY=0x4c; <br>
---CURR和BNRY主要用来控制缓冲区的存取过程,保证能顺次写入和读出)。 <br>
当CURR=BNRY+1(或当BNRY=0x7f ,CURR=0x4c)时,网卡的接收缓冲区里没有数据 <br>
,表示没有收到数据包。 用户通过这个判断知道没有包可以读。当上述条件不成 <br>
立时,表示接收到新的数据包。然后用户应该读取数据包,直到上述条件成立时, <br>
表示所以数据包已经读完,此时停止读取数据包。 <br>
--TPSR 为发送页的起始页地址。初始化为指向第一个发送缓冲区的页,0x40。 <br>
<br>
--RCR 接收配置寄存器,设置为使用接收缓冲区,仅接收自己的地址的数据包( <br>
以及广播地址数据包)和多点播送地址包,小于64字节的包丢弃(这是协议的规定 <br>
,设置成接收是用于网络分析),校验错的数据包不接收。 <br>
--TCR 发送配置寄存器,启用crc自动生成和自动校验,工作在正常模式。 <br>
--DCR 数据配置寄存器,设置为使用FIFO缓存,普通模式,8位数据传输模式, <br>
字节顺序为高位字节在前,低位字节在后(符合我们的习惯)(如果用16位的单片 <br>
机,设置成16位的数据总线操作会更快,但80c52是8位总线的单片机) <br>
--IMR 中断屏蔽寄存器,设置成0x00,屏蔽所有的中断。设置成0xff将允许中断 <br>
) <br>
--MAR0--MAR8是设置多点播送的参数,这点我也不是很清楚,我从电脑读出来 <br>
是什么数,我也将这8个寄存器设置成这几个数. 由于我们不使用多点播送,所以 <br>
不要紧,只要保证网卡能正常工作就可以了。 <br>
--PAGE2的寄存器是只读的,所以不可以设置,不用设置,PAGE3的寄存器不是 <br>
NE2000兼容的,所以也不用设置。 <br>
<br>
(未完) <br>
<br>
<br>
-- <br>
<br>
※ 来源:·BBS 水木清华站 smth.org·[FROM: 166.111.174.125] <br>
</small><hr>
<p align="center">[<a href="嵌入式系统.htm">回到开始</a>][<a href="398.htm">上一层</a>][<a href="429.htm">下一篇</a>]
<p align="center"><a href="http://cterm.163.net">欢迎访问Cterm主页</a></p>
</table>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -