微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 单片机驱动DM9000网卡芯片详细调试过程

单片机驱动DM9000网卡芯片详细调试过程

时间:12-03 来源:互联网 点击:

, 0x3f);

/*为了保险,上面有清除了一次标志位*/

dm9000_reg_write(IMR, 0x81);

/*中断使能(或者说中断屏蔽),即开启我们想要的中断,关闭不想要的,这里只开启的一个接收中断*/

/*以上所有寄存器的具体含义参考上一篇文章,或参考数据手册*/

}

这样就对DM9000初始化完成了,怎么样,挺简单的吧。

3、发送、接收数据包

同样,以程序为例,通过注释说明。

//发送数据包

//参数:datas为要发送的数据缓冲区(以字节为单位),length为要发送的数据长度(两个字节)。

void sendpacket(unsigned char *datas, unsigned int length)

{
unsigned int len, i;

dm9000_reg_write(IMR, 0x80);//先禁止网卡中断,防止在发送数据时被中断干扰

len = length;

dm9000_reg_write(TXPLH, (len>>8) & 0x0ff);

dm9000_reg_write(TXPLL, len & 0x0ff);

/*这两句是将要发送数据的长度告诉DM9000的寄存器*/

DM_ADD = MWCMD;//这里的写法是针对有总线接口的处理器,没有总线接口的处理器要注意加上时序。

for(i=0; i

{

udelay(20);

DM_CMD = datas[i] | (datas[i+1]<8);

}

/*上面是将要发送的数据写到DM9000的内部SRAM中的写FIFO中,注意没有总线接口的处理器要加上适当的时序*/

/*只需要向这个寄存器中写数据即可,MWCMD是DM9000内部SRAM的DMA指针,根据处理器模式,写后自动增加*/

dm9000_reg_write(TCR, 0x01);//发送数据到以太网

while((dm9000_reg_read(NSR) & 0x0c) == 0);//等待数据发送完成

udelay(20);

dm9000_reg_write(NSR, 0x2c);//清除状态寄存器,由于发送数据没有设置中断,因此不必处理中断标志位

dm9000_reg_write(IMR, 0x81);//DM9000网卡的接收中断使能

}

以上是发送数据包,过程很简单。而接收数据包确需要些说明了。DM9000从网络中接到一个数据包后,会在数据包前面加上4个字节,分别为“01H”、“status”(同RSR寄存器的值)、“LENL”(数据包长度低8位)、“LENH”(数据包长度高8位)。所以首先要读取这4个字节来确定数据包的状态,第一个字节“01H”表示接下来的是有效数据包,若为“00H”则表示没有数据包,若为其它值则表示网卡没有正确初始化,需要从新初始化。

如果接收到的数据包长度小于60字节,则DM9000会自动为不足的字节补上0,使其达到60字节。同时,在接收到的数据包后DM9000还会自动添加4个CRC校验字节。可以不予处理。于是,接收到的数据包的最小长度也会是64字节。当然,可以根据TCP/IP协议从首部字节中出有效字节数,这部分在后面讲解。下面为接收数据包的函数。

//接收数据包

//参数:datas为接收到是数据存储位置(以字节为单位)

//返回值:接收成功返回数据包类型,不成功返回0

unsigned int receivepacket(unsigned char *datas)

{

unsigned int i, tem;

unsigned int status, len;

unsigned char ready;

ready = 0;//希望读取到“01H”

status = 0;//数据包状态

len = 0; //数据包长度

/*以上为有效数据包前的4个状态字节*/

if(dm9000_reg_read(ISR) & 0x01)

{

dm9000_reg_write(ISR, 0x01);

}

/*清除接收中断标志位*/

/***********************************************************************************/

/*这个地方遇到了问题,下面的黑色字体语句应该替换成成红色字体,也就是说MRCMDX寄存器如果第一次读不到数据,还要读一次才能确定完全没有数据。

在做 PING 实验时证明:每个数据包都是通过第二次的读取MRCMDX寄存器操作而获知为有效数据包的,对初始化的寄存器做了多次修改依然是此结果,但是用如下方法来实现,绝不会漏掉数据包。*/

ready = dm9000_reg_read(MRCMDX); // 第一次读取,一般读取到的是 00H

if((ready & 0x0ff) != 0x01)

{

ready = dm9000_reg_read(MRCMDX); // 第二次读取,总能获取到数据

if((ready & 0x01) != 0x01)

{

if((ready & 0x01) != 0x00) //若第二次读取到的不是 01H 或 00H ,则表示没有初始化成功

{

dm9000_reg_write(IMR, 0x80);//屏幕网卡中断

DM9000_init();//重新初始化

dm9000_reg_write(IMR, 0x81);//打开网卡中断

}

retrun 0;

}

}

/* ready = dm9000_reg_read(MRCMDX); // read a byte without pointer increment

if(!(ready & 0x01))

{

return 0;

}*/

/***********************************************************************************/

/*以上表示若接收到的第一个字节不是“01H”,则表示没有数据包,返回0*/

status = dm9

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top