《2022年单片机驱动DM网卡芯片[下] .pdf》由会员分享,可在线阅读,更多相关《2022年单片机驱动DM网卡芯片[下] .pdf(11页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、单片机驱动 DM9000 网卡芯片 下 网络方面2010-01-31 23:25:00 阅读 96 评论 0 字号:大中小订阅4、验证初始化中的各个函数。下面我们来看一下,上面所写的初始化函数是否可用。以上我们写好了三个函数,分别为DM9000_init(),sendpacket()和 receivepacket(),保存并命名为dm9000.c 。既然我们要进行调试,当然要有结果输出,根据自己的处理器的情况写一个串口程序,这些函数是学某个单片机的基础,这里不做详细介绍,用到是时候会在函数里注释一下。接下来我们来写个主函数,新建C文件,命名为mian.c ,填写如下函数:void main(v
2、oid) unsigned int i; unsigned char c; uart0_init();/初始化串口,调试时用到 DM9000_init();/初始化网卡 print_regs();/*通过串口,将 DM9000中的寄存器打印出来,显示在超级终端上。此函数根据自己的处理器进行修改,功能仅仅是读DM9000寄存器 dm9000_reg_read(),再通过串口打印出来而已*/名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 11 页 - - - - - - -
3、- - 函数写好,保存文件,连接硬件,连接网线到电脑上或局域网上,运行结果如下图所示:图 4 显示寄存器值这里首先检查,各个控制寄存器是否是自己写进去的值,在检查状态寄存器是否正确,其中主要要看 NSR寄存器的 bit6是否为“ 1”,该位表示是否连接成功。本例中NSR的值为 40H,括号里的数为对应的十进制数。下面我们将主函数改进一下,增加个中断接收函数,查看是否能接收到数据。void main(void) unsigned int i; unsigned char c; uart0_init();/初始化串口,调试时用到名师资料总结 - - -精品资料欢迎下载 - - - - - - -
4、- - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 11 页 - - - - - - - - - DM9000_init();/初始化网卡/*/* 这一部分要根据自己的处理器情况,将DM9000的 INT 引脚连接到处理器的外部中断上,打开中断 */*/ sendpacket(60);/*我事先已经在Buffer中存储了 ARP请求数据包,这里就直接发送了,以便接收ARP应答包。大家可以先参考后面讲的ARP协议,根据自己机器的情况, 将数据事先存到Buffer中*/ while(1);/等待中断void int_issue(void) /中断处
5、理函数,需要根据自己的处理器进行设置 unsigned int i; i = receivepacket(Buffer);/将数据读取到Buffer中。int_again : if(i = 0) return; else print_buffer();/将接收到的所有数据打印出来 while(1);/停止在这里等待观察,注意:实际应用中是不允许停止在中断中的。 /*/* 这里加上这一段,目的是判断中断期间是否接收到其它数据包。有则加以处理。不加也完全可以*/* 根据自己的处理器,判断处理器是否还处在中断状态,若是则进行如下操作,不是则跳过该段。 */ i = receivepacket(Buf
6、fer);名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 11 页 - - - - - - - - - if(i != 0) goto int_again; /*/编译调试,运行结果如下:图 5 接收数据包中的数据这是一个 ARP应答包,包含了我电脑上的MAC地址和局域网内的IP 地址。反正我也不是啥重要人物,这里就不保密了,呵呵。如果一些顺利,到这里对DM9000网卡芯片的初始化工作就完成了。如果出现问题,首先要名师资料总结 - - -精品资料欢迎下载 - - - -
7、- - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 11 页 - - - - - - - - - 检查寄存器的值是否正确。可以将DM9000中的寄存器打印出来,查看到底是哪里的问题。如果打印出的值很混乱,在确保串口程序无误的前提下,查看硬件连接,以及寄存器读写时序是否正确,重复调试几次查找原因。三、 ARP 协议的实现 1、ARP协议原理简述 ARP协议( Address Resolution Protocol 地址解析协议),在局域网中,网络中实际传输的是“帧”,帧里面有目标主机的MAC 地址。在以太网中,一个注意要和另一个主机进
8、行直接通信,必须要知道目标主机的MAC地址。这个MAC地址就是标识我们的网卡芯片唯一性的地址。但这个目标MAC地址是如何获得的呢?这就用到了我们这里讲到的地址解析协议。所有“地址解析”,就是主机在发送帧前将目标 IP 地址转换成MAC地址的过程。 ARP协议的基本功能就是通过目标设备的IP 地址,查询目标设备的 MAC地址,以保证通信的顺利进行。所以在第一次通信前,我们知道目标机的IP 地址,想要获知目标机的MAC地址,就要发送ARP报文(即ARP数据包)。它的传输过程简单的说就是:我知道目标机的IP 地址,那么我就向网络中所有的机器发送一个ARP请求,请求中有目标机的IP 地址,请求的意思是
9、目标机要是收到了此请求,就把你的MAC地址告诉我。如果目标机不存在,那么此请求自然不会有人回应。若目标机接收到了此请求,它就会发送一个ARP应答,这个应答是明确发给请求者的,应答中有MAC地址。我接到了这个应答,我就知道了目标机的MAC地址,就可以进行以后的通信了。因为每次通信都要用到 MAC地址。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 11 页 - - - - - - - - - ARP报文被封装在以太网帧头部中传输,如图为ARP请求报文的头部格式。图 6 用于
10、以太网的ARP请求或应答分组格式注意,以太网的传输存储是“大端格式”,即先发送高字节后发送低字节。例如,两个字节的数据,先发送高8 位后发送低8 位。所以接收数据的时候要注意存储顺序。整个报文分成两部分,以太网首部和ARP请求 / 应答。下面挑重点讲述。“以太网目的地址”字段:若是发送ARP请求,应填写广播类型的MAC地址 FF-FF-FF-FF-FF-FF ,意思是让网络上的所有机器接收到;“帧类型”字段:填写08-06 表示次报文是ARP协议;“硬件类型”字段:填写00-01 表示以太网地址,即MAC地址;“协议类型”字段:填写08-00 表示 IP ,即通过IP 地址查询MAC地址;“硬
11、件地址长度”字段:MAC地址长度为6(以字节为单位);“协议地址长度”字段:IP 地址长度为4(以字节为单位);“操作类型”字段:ARP数据包类型,0 表示 ARP请求, 1 表示 ARP应答;“目的以太网地址”字段:若是发送ARP请求,这里是需要目标机填充的。 2、ARP的处理程序 ARP协议原理很简单,下面我们来编写ARP协议的处理函数。新建文件命名为arp.c ,填写如下函数:unsigned char mac_addr6 = *,*,* ,* ,*,*;unsigned char ip_addr4 = 192, 168, *, * ;unsigned char host_ip_addr
12、4 = 192, 168, *, * ;unsigned char host_mac_addr6= 0 xff, 0 xff, 0 xff, 0 xff, 0 xff, 0 xff ; unsigned char Buffer1000;uint16 packet_len;名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 11 页 - - - - - - - - - /* 这些全局变量,在前面将的文件中有些已经有过定义,这里要注意在前面加上“extern ”关键字。“*”应该
13、根据自己的机器修改*/#define HON(n) (uint16)(n) & 0 xff) 8)/* 此宏定义是将小端格式存储的字(两个字节)转换成大端格式存储*/void arp_request(void) /发送 ARP请求数据包/ 以太网首部memcpy(ARPBUF-ethhdr.d_mac, host_mac_addr, 6);/* 字符串拷贝函数,文件要包含头文件。参数依次是,拷贝目标指针,拷贝数据源指针,拷贝字符数 */memcpy(ARPBUF-ethhdr.s_mac, mac_addr, 6);ARPBUF-ethhdr.type = HON( 0 x0806 );/*
14、小端格式的编译器,可以用HON()宏来转换成大端格式,如果你的编译器是大端格式,直接填写0 x0806 即可 */* 就是简单的按照协议格式填充,以下同*/ARP 首部ARPBUF-hwtype = HON( 1 );ARPBUF-protocol = HON( 0 x0800 );ARPBUF-hwlen = 6;ARPBUF-protolen = 4;ARPBUF-opcode = HON( 0 );memcpy(ARPBUF-smac, mac_addr, 6);memcpy(ARPBUF-sipaddr, ip_addr, 4);memcpy(ARPBUF-dipaddr, host_
15、ip_addr, 4);packet_len = 42;/14+28=42sendpacket( Buffer, packet_len );名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 11 页 - - - - - - - - - 注释:ARPBUF的宏定义和ARP首部结构,在前面已经讲过。同时注意执行该函数时中断的处理。这里没作处理。看上去很 easy 吧,下面函数实现接收ARP请求或接收ARP应答的处理。unsigned char arp_process(void)
16、/ARP接收函数,成功返回1,否则返回0/ 简单判断 ARP数据包有无损坏, 有损坏则丢弃, 不予处理if( packet_len opcode ) ) case 0 : /处理 ARP请求 if( ARPBUF-dipaddr0 = ip_addr0 & ARPBUF-dipaddr1 = ip_addr1 & ARPBUF-dipaddr2 = ip_addr2 & ARPBUF-dipaddr3 = ip_addr3 )/判断是否是自己的IP ,是否向自己询问MAC地址。 ARPBUF-opcode = HON( 2 );/设置为 ARP应答 memcpy(ARPBUF-dmac, AR
17、PBUF-smac, 6); memcpy(ARPBUF-ethhdr.d_mac, ARPBUF-smac, 6); memcpy(ARPBUF-smac, mac_addr, 6); memcpy(ARPBUF-ethhdr.s_mac, mac_addr, 6); memcpy(ARPBUF-dipaddr, ARPBUF-sipaddr, 4); memcpy(ARPBUF-sipaddr, ip_addr, 4); ARPBUF-ethhdr.type = HON( 0 x0806 ); packet_len = 42; sendpacket( Buffer, packet_len
18、);/发送 ARP数据包名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 11 页 - - - - - - - - - return 1; else return 0; break; case 1 : /处理 ARP应答 if( ARPBUF-dipaddr0 = ip_addr0 & ARPBUF-dipaddr1 = ip_addr1 & ARPBUF-dipaddr2 = ip_addr2 & ARPBUF-dipaddr3 = ip_addr3 )/再次判断 IP,
19、是否是给自己的应答 memcpy(host_mac_addr, ARPBUF-smac, 6);/保存服务器MAC地址 return 1; else return 0; break;default :/不是 ARP协议 return 0;根据 ARP协议格式看这两个函数并不困难。于是我们又得到两个函数:arp_request()和arp_process()。 3、ARP程序调试下面我们修改主函数和中断处理函数。将 mian() 函数中的“ sendpacket(60);”语句换成“ arp_request();”语句。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - -
20、 - - - - - - - - - 名师精心整理 - - - - - - - 第 9 页,共 11 页 - - - - - - - - - void int_issue(void) /中断处理函数,需要根据自己的处理器进行设置 unsigned int i; i = receivepacket(Buffer);/将数据读取到Buffer中。 if(i = 0) return; else i = arp_process(); if(i = 1)/判断是否是ARP协议 print_hostmacaddr();/打印目标机的MAC 地址,就是用串口打印host_mac_addr中的 6个字节 保存
21、运行调试。图 7 主机 MAC地址至此,关于DM9000的调试过程就完成了。之后我还调试了UDP通讯、 TCP通讯等,主要是关于协议的处理了,这里就不介绍了。有兴趣的朋友可以参看TCP/IP 协议第一卷,将会有很大帮助。希望这些调试过程能为读者或多或少的提供些有用的信息,也欢迎大家和我一起讨论。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 11 页 - - - - - - - - - 我的 Email :名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 11 页,共 11 页 - - - - - - - - -