单片机与TCP/IP网络
--版主 老古 http://www.laogu.com

(七)网卡上电复位


----当你买到一个新的RTL8019AS网卡,你要先将该网卡设置为以下的配置:

操作方式Operating Mode:跳线方式Jumperless(不是即插即用Plug and Play)
端口I/O base:0240-25FH
中断Interrupt: 2/9(我的程序没有用到网卡中断,所以也可以不用设置)
你要将这个网卡插到你的电脑里,用这个网卡带的设置程序RSET8019.exe将这个卡按照上面的配置设置好。(最好在纯DOS方式下设置) .

--在介绍网卡驱动程序之前,先介绍一下RTL8019AS的基本情况:

输入输出地址:共32个,地址偏移量为00H--1FH,(对应于240H--25FH,240H的地址偏移量为0,241H的地址偏移量为1,。。。25FH的地址偏移量为1FH)。

其中00H--0FH共16个地址,为寄存器地址。
10H--17H共8个地址,为DMA地址。
18H--1FH共8个地址,为复位端口。
对于8位的操作方式,上面的地址中只有18个是有用的:
00H--0FH共16个寄存器地址。
10H DMA地址 (10H--17H的8个地址是一样的,都可以用来做DMA端口,只要用其中的一个就可以了)
1FH 复位地址。(18H到1FH共8个地址都是复位地址,每个地址的功能都是一样的,只要其中的一个就可以了,但实际上只有18H,1AH,1CH,1EH这几个复位端口是有效的,其他不要使用,有些兼容卡不支持19H,1BH,1DH等奇数地址的复位)


跟复位有关的引脚:

RSTDRV连接到ISA总线的RSTDRV的引脚上。RSTDRV同时也是ISA总线的复位信号。RSTDRV为高电平有效,至少需要 800ns的宽度。给该引脚施加一个1us以上的高电平就可以复位。施加一个高电平之后,然后施加一个低电平。


RSTDRV从高电平到低电平之后要等多久,单片机才可以对网卡进行操作?
复位的过程将执行一些操作,比如将93c46读入,将内部寄存器初始化等。这些至少需要2毫秒的时间。我们推荐大家等待更久的时间之后才对网卡操作,比如100毫秒之后才对它操作,以确保完全复位。
对RSTDRV可以接单片机的一个引脚进行对网卡的复位。但也可以直接将RSTDRV跟单片机的RESET引脚并联,单片机复位的时候,网卡也复位,以减少一个单片机的引脚的使用。这种情况下,为了保证能够完全复位,可以使用下面介绍的热复位代码。

跟复位有关的寄存器:

18H--1FH共8个地址,为复位端口。对该端口偶数地址的读,或者写入任何数,都引起网卡的复位。
跟复位有关的标志位:

其中的第7位RST跟复位有关。
网卡执行正确的复位之后该位为1。在linux或windows的驱动程序中,一般在复位之后检查该标志位以确认是否正确复位,特别是在即插即用的检测过程中。对于我们用单片机控制网卡来说,我们可以不检查该标志位,因为如果复位不正常的情况通常是网卡坏了。

寄存器:00H--0FH共16个地址是寄存器地址。寄存器分成4页PAGE0--PAGE3,但NE2000兼容的寄存器只有3页(Page0-Page2),(第四页是RTL8019AS自己定义的,我们不用去管这些寄存器,因为你对第四页的寄存器的操作仅对这个网卡是有效的,如果你换成其他Ne2000兼容的网卡,例如DM9008,DP8390等,你的程序将无法正常运行。 为了保证驱动程序对所有Ne2000的网卡有效,不要去操作第四页的寄存器)
由于寄存器较多,我将在用到该寄存器的时候才对该寄存器介绍。

---对网卡进行复位:
这是网卡驱动程序的需要做的第一个内容,由于我们将网卡设置为跳线模式,而不是即插即用的模式,RTL8019AS.PDF中介绍的PLUG and PLAY的一些过程,我们不需要做,因为单片机的资源有限,能够减少的操作,都尽量减少。

程序从main()开始执行:

#include <my.h> /*my.h 为作者所用的头文件,包含所有89c52寄存器的大写和小写的定义,
和一些常用的子函数,一些宏的定义*/
main()

{

delaymsecond(10);//延时大约1秒,保证电源稳定和网卡自身的上电完成。
netcardreset();//复位网卡的子程序

。。。。

}
下面介绍网卡的复位子程序:
#define reg1f XBYTE[0xdf00] //网卡的复位端口的地址,对应于网卡的地址25FH。
#define uint unsigned int //uint 代表unsigned int ,作者一般使用缩写uint
#define uchar unsigned char //uchar 代表unsigned char,我比较懒,不愿意多写
sbit reset=p3^4; //单片机的p3.4脚连接到网卡的RSTDRV复位引脚

void netcardreset()
{uint data i;
uchar data temp;
reset=1; //使网卡的RSTDRV引脚变成高电平,网卡是高电平复位的。
for(i=0;i<250;i++);//延时程序,至少需要
reset=0; //使网卡的RSTDRV引脚变成低电平,网卡上电复位完毕
for(i=0;i<250;i++);
temp=reg1f;//读网卡的复位端口
reg1f=temp; //写网卡的复位端口
for(i=0;i<250;i++);


}
上面所讲的实际上是网卡复位的两种情况,
reset=1;reset=0相当于冷复位
temp=reg1f;reg1f=temp相当于热复位
对网卡的复位端口的读或写将复位网卡,网卡内部将执行复位过程。读写是随意的,写入任意的数都将复位网卡。
实际上只要使用冷复位就可以了,热复位程序可以不要。热复位主要在电脑里有用,冷复位就像电脑的冷启动,热复位相当于电脑的热启动。

--作者的复位网卡的过程是简化了的,一个电脑里的复位过程是比较复杂的,如果你有网卡驱动的UNIX,LINUX程序的源代码,它的代码将会做一些判断和检查,检查网卡是否存在,和是否工作正常,和是否存在地址和中断冲突 。但在我们的这个系统里可以省去这些,我们认为网卡的地址和I/O是没有冲突和正常工作的。当然如果读者愿意,也可以写一些检查代码。

(未完)