单片机驱动DM9000网卡芯片详细调试过程
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 { } /*以上接收数据包,注意的地方与发送数据包的地方相同*/ if(len > 1000) return 0; if( (HON( ETHBUF->type ) != ETHTYPE_ARP) && (HON( ETHBUF->type ) != ETHTYPE_IP) ) { return 0; } packet_len = len; /*以上对接收到的数据包作一些必要的限制,去除大数据包,去除非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
return 0;
return HON( ETHBUF->type ); //返回数据包的类型,这里只选择是ARP或IP两种类型
单片机驱动DM9000网卡芯片调试过 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)