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

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

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

000_reg_read(MRCMD);

udelay(20);

len = DM_CMD;

if(!(status & 0xbf00) && (len < 1522))

{

for(i=0; i

{

udelay(20);

tem = DM_CMD;

datas[i] = tem & 0x0ff;

datas[i + 1] = (tem >> 8) & 0x0ff;

}

}

else

{
return 0;

}

/*以上接收数据包,注意的地方与发送数据包的地方相同*/

if(len > 1000) return 0;

if( (HON( ETHBUF->type ) != ETHTYPE_ARP) &&

(HON( ETHBUF->type ) != ETHTYPE_IP) )

{

return 0;

}

packet_len = len;

/*以上对接收到的数据包作一些必要的限制,去除大数据包,去除非ARP或IP的数据包*/

return HON( ETHBUF->type ); //返回数据包的类型,这里只选择是ARP或IP两种类型

}

注意:上面的函数用到了一些宏定义,已经在头文件中定义过,这里说明一下:其中uint16定义为两个字节的变量,根据C编译器进行定义。

unsigned char Buffer[1000];//定义了一个1000字节的接收发送缓冲区

uint16 packet_len;//接收、发送数据包的长度,以字节为单位。

struct eth_hdr //以太网头部结构,为了以后使用方便

{

unsigned char d_mac[6]; //目的地址

unsigned char s_mac[6]; //源地址

uint16 type; //协议类型

};

struct arp_hdr //以太网头部+ARP首部结构

{

struct eth_hdr ethhdr; //以太网首部

uint16 hwtype; //硬件类型(1表示传输的是以太网MAC地址)

uint16 protocol; //协议类型(0x0800表示传输的是IP地址)

unsigned char hwlen; //硬件地址长度(6)

unsigned char protolen; //协议地址长度(4)

uint16 opcode; //操作(1表示ARP请求,2表示ARP应答)

unsigned char smac[6]; //发送端MAC地址

unsigned char sipaddr[4]; //发送端IP地址

unsigned char dmac[6]; //目的端MAC地址

unsigned char dipaddr[4]; //目的端IP地址

};

struct ip_hdr //以太网头部+IP首部结构

{

struct eth_hdr ethhdr; //以太网首部

unsigned char vhl, //4位版本号4位首部长度(0x45)

tos; //服务类型(0)

uint16 len, //整个IP数据报总字节长度

ipid, //IP标识

ipoffset; //3位标识13位偏移

unsigned char ttl, //生存时间(32或64)

proto; //协议(1表示ICMP,2表示IGMP,6表示TCP,17表示UDP)

uint16 ipchksum; //首部校验和

unsigned char srcipaddr[4], //源IP

destipaddr[4]; //目的IP

};

以上定义的三种首部结构,是根据TCP/IP协议的相关规范定义的,后面会对ARP协议进行详细讲解。

4、验证初始化中的各个函数。

下面我们来看一下,上面所写的初始化函数是否可用。以上我们写好了三个函数,分别为

DM9000_init(),sendpacket()和receivepacket(),保存并命名为dm9000.c。既然我们要进行调试,当

然要有结果输出,根据自己的处理器的情况写一个串口程序,这些函数是学某个单片机的基础,这里不

做详细介绍,用到是时候会在函数里注释一下。

接下来我们来写个主函数,新建C文件,命名为mian.c,填写如下函数:

void main(void)

{

unsigned int i;

unsigned char c;

uart0_init();//初始化串口,调试时用到

DM9000_init();//初始化网卡

print_regs();/*通过串口,将DM9000中的寄存器打印出来,显示在超级终端上。此函数根据自己

的处理器进行修改,功能仅仅是读DM9000寄存器dm9000_reg_read(),再通过串口打印出来而已*/

}

函数写好,保存文件,连接硬件,连接网线到电脑上或局域网上,运行结果如下图所示:

图4 显示寄存器值

这里首先检查,各个控制寄存器是否是自己写进去的值,在检查状态寄存器是否正确,其中主要要

看NSR寄存器的bit[5]是否为“1”,该位表示是否连接成功。本例中NSR的值为40H,括号里的数为对应

的十进制数。

下面我们将主函数改进一下,增加个中断接收函数,查看是否能接收到数据。

void main(void)

{

unsigned int i;

unsigned char c;

uart0_init();//初始化串口,调试时用到

DM9000_init();//初始化网卡

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

/*这一部分要根据自己的处理器情况,将DM9000的INT引脚连接到处理器的外部中断上,打开中断*/

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

sendpacket(60);/*我事先已经在Buffer[]中存储了ARP请求数据包,这里就直接发送了,以便接收

ARP应答包。大家可以先参考后面讲的ARP协议,根据自己机器的情况,将数据事先存到Buffer[]中*/

while(1);//等待中断

}

void int_issue(void) //中断处理函数,需要根据自己的处理器进行设置

{

unsigned int i;

i = receivepacket(Bu

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

网站地图

Top