ImageVerifierCode 换一换
格式:DOCX , 页数:20 ,大小:27.27KB ,
资源ID:20167236      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/20167236.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(单片机驱动DM9000网卡芯片详细调试过程Word格式文档下载.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

单片机驱动DM9000网卡芯片详细调试过程Word格式文档下载.docx

1、 如图所示,对处理器驱动网卡芯片来说,我们比较关心的有以下几个引脚:IOR、IOW、AEN、CMD(SA2)、INT、RST,以及数据引脚SD0-SD15-SD31和地址引脚SA4-SA9。其中,地址引脚配合AEN引脚来选通该网卡芯片,对于大多数的应用来说没有意义,因为在我们的应用中一般只用一个网卡芯片,而这些地址引脚主要用于在多网卡芯片环境下选择其中之一。DM9000工作的默认基地址为0x300,这里我们按照默认地址选择,将SA9、SA8接高电平,SA7-DA4接低电平。多网卡环境可以根据TXD0-TXD3配置SA4-SA7来选择不同的网卡,这里不做介绍,有兴趣的朋友请参考应用手册和数据手册

2、。数据引脚SD0-SD31则根据前面所讲的配置处理器模式与处理器的数据总线进行选择连接即可,没用到的引脚悬空。那么,除了地址、数据引脚外,剩下的与处理器有关引脚对我们来说及其重要了,而与处理器无关的引脚,只需按照应用手册连接即可。IOR和IOW是DM9000的读写选择引脚,低电平有效,即低电平时进行读(IOR)写(IOW)操作;AEN是芯片选通引脚,低电平有效,该引脚为低时才能进行读写操作;CMD的命令/数据切换引脚,低电平时读写命令操作,高电平时读写数据操作。图2 读时序图3 写时序 这些引脚接口和其它单片机外围器件的引脚接口基本相同,其使用也一样。对于有总线接口的单片机来说,如51系列,A

3、RM等直接连接即可。对于没有总线接口的来说,如AVR mega32等可以直接用I/O引脚模拟总线时序进行连接。连接时要参考读写时序,如上图所示。具体连接电路,有时间我再画出来,暂时先略了。 二、编写驱动程序 在这,我使用C语言编写驱动程序,这需要非常注意一点,即处理器所用的C编译器使用“大端格式”还是“小端格式”,这可以在相应处理器的C编译器说明上找到。一般比较常见的是小端格式。而对于8位处理器来说,在编写驱动程序时,可以不考虑,但是在编写网络协议的时候,一定好考虑,因为网络协议的格式是大端格式,而大部分编译器或者我们习惯的是小端格式,这一点需要注意。 在DM9000中,只有两个可以直接被处理

4、器访问的寄存器,这里命名为CMD端口和DATA端口。事实上,DM9000中有许多控制和状态寄存器(这些寄存器在上一篇文章中有详细的使用说明),但它们都不能直接被处理器访问,访问这些控制、状态寄存器的方法是:(1)、将寄存器的地址写到CMD端口;(2)、从DATA端口读写寄存器中的数据; 1、读、写寄存器其实,INDEX端口和DATA端口的就是由芯片上的CMD引脚来区分的。低电平为INDEX(ADDRESS)端口,高电平为DATA端口。所以,要想实现读写寄存器,就必须先控制好CMD引脚。 若使用总线接口连接DM9000的话,假设总线连接后芯片的基地址为0x800300(24根地址总线),只需如下

5、方法:#define DM_ADD (*(volatile unsigned int *) 0x8000300) #define DM_CMD (*(volatile unsigned int *) 0x8000304)/向DM9000寄存器写数据void dm9000_reg_write(unsigned char reg, unsigned char data) udelay(20);/之前定义的微妙级延时函数,这里延时20us DM_ADD = reg;/将寄存器地址写到INDEX端口 DM_CMD = data;/将数据写到DATA端口,即写进寄存器/从DM9000寄存器读数据unsi

6、gned int dm9000_reg_read(unsigned char reg) return DM_CMD;/将数据从寄存器中读出 只得注意的是前面的两个宏定义DM_ADD和DM_CMD,定义的内容表示指向无符号整形变量的指针,在这里0x800300是DM9000命令端口的地址,对它的赋值操作就相当于把数据写到该地址中,即把数据写到DM9000的命令端口中。读的道理也一样。这是一种很常见的宏定义,一般在处理器中定义通用寄存器也是这样定义的。 若没有总线接口的话,可以使用IO口模拟总线时序的方法实现寄存器的读写。这里只说明实现步骤。首先将处理器的I/O端口与DM9000的IOR等引脚直接

7、相连(电平匹配的情况下),又假设已经有宏定义“IOR”I/O端口控制DM9000的IOR引脚,其它端口控制DM9000引脚的命名相同,“PIO1”(根据处理器情况,可以是8位、16位或32位的I/O端口组成)控制数据端口。这样宏命名更直观些。写寄存器的函数如下:PIO1 = reg;AEN = 0;CMD = 0;IOR = 1;IOW = 0;udelay(1);AEN = 1;IOW = 1;udelay(20);PIO1 = data; 读寄存器的写法类似,这里就略一下了。这一过程看上去有些复杂,呵呵,其实执行起来也蛮有效率的,执行时间差不多。这种模拟总线时序的方式实际并不复杂,只是把总

8、线方式下自动执行的过程手动的执行了一遍而已。 在DM9000中,还有一些PHY寄存器,也称之为介质无关接口MII(Media Independent Interface)寄存器。对这些寄存器的操作会影响网卡芯片的初始化和网络连接,这里不对其进行操作,所以对这些寄存器的访问方法这里也略了(在上篇文章中有介绍)。操作不当反而使网卡不能连接到网络。 至此,我们已经写好了两个最基本的函数:dm9000_reg_write()和dm9000_reg_read(),以及前面的宏定义DM_ADD和DM_CMD。下面将一直用到。 2、初始化DM9000网卡芯片。 初始化DM9000网卡芯片的过程,实质上就是填

9、写、设置DM9000的控制寄存器的过程,这里以程序为例进行说明。其中寄存器的名称宏定义在DM9000.H中已定义好。注:一下函数中unsigned char为一个字节unsigned int为两个字节/DM9000初始化void DM9000_init(void) unsigned int i; IO0DIR |= 1 8; IO1CLR |= 1 udelay(500000); IO2SET |= 1 /*以上部分是利用一个IO口控制DM9000的RST引脚,使其复位。这一步可以省略,可以用下面的软件复位代替*/ dm9000_reg_write(GPCR, 0x01);/设置 GPCR(1

10、EH) bit0=1,使DM9000的GPIO03为输出。 dm9000_reg_write(GPR, 0x00);/GPR bit0=0 使DM9000的GPIO3输出为低以激活内部PHY。 udelay(5000);/延时2ms以上等待PHY上电。 dm9000_reg_write(NCR, 0x03);/软件复位 udelay(30);/延时20us以上等待软件复位完成 dm9000_reg_write(NCR, 0x00);/复位完成,设置正常工作模式。/第二次软件复位,为了确保软件复位完全成功。此步骤是必要的。/*以上完成了DM9000的复位操作*/ dm9000_reg_write

11、(NSR, 0x2c);/清除各种状态标志位 dm9000_reg_write(ISR, 0x3f);/清除所有中断标志位/*以上清除标志位*/ dm9000_reg_write(RCR, 0x39);/接收控制 dm9000_reg_write(TCR, 0x00);/发送控制 dm9000_reg_write(BPTR, 0x3f); dm9000_reg_write(FCTR, 0x3a); dm9000_reg_write(RTFCR, 0xff); dm9000_reg_write(SMCR, 0x00);/*以上是功能控制,具体功能参考上一篇文章中的说明,或参考数据手册的介绍*/

12、for(i=0; i8) & 0x0ff); dm9000_reg_write(TXPLL, len &/*这两句是将要发送数据的长度告诉DM9000的寄存器*/ DM_ADD = MWCMD;/这里的写法是针对有总线接口的处理器,没有总线接口的处理器要注意加上时序。len; i+=2)/16 bit mode DM_CMD = datasi | (datasi+18); /*上面是将要发送的数据写到DM9000的内部SRAM中的写FIFO中,注意没有总线接口的处理器要加上适当的时序*/*只需要向这个寄存器中写数据即可,MWCMD是DM9000内部SRAM的DMA指针,根据处理器模式,写后自动

13、增加*/ dm9000_reg_write(TCR, 0x01);/发送数据到以太网上 while(dm9000_reg_read(NSR) & 0x0c) = 0);/等待数据发送完成/清除状态寄存器,由于发送数据没有设置中断,因此不必处理中断标志位/DM9000网卡的接收中断使能 以上是发送数据包,过程很简单。而接收数据包确需要些说明了。DM9000从网络中接到一个数据包后,会在数据包前面加上4个字节,分别为“01H”、“status”(同RSR寄存器的值)、“LENL”(数据包长度低8位)、“LENH”(数据包长度高8位)。所以首先要读取这4个字节来确定数据包的状态,第一个字节“01H”

14、表示接下来的是有效数据包,若为“00H”则表示没有数据包,若为其它值则表示网卡没有正确初始化,需要从新初始化。 如果接收到的数据包长度小于60字节,则DM9000会自动为不足的字节补上0,使其达到60字节。同时,在接收到的数据包后DM9000还会自动添加4个CRC校验字节。可以不予处理。于是,接收到的数据包的最小长度也会是64字节。当然,可以根据TCP/IP协议从首部字节中出有效字节数,这部分在后面讲解。下面为接收数据包的函数。/接收数据包datas为接收到是数据存储位置(以字节为单位)/返回值:接收成功返回数据包类型,不成功返回0unsigned int receivepacket(unsi

15、gned 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寄存器如果第一次读不到数据,还要读一次才能确

16、定完全没有数据。在做 PING 实验时证明:每个数据包都是通过第二次的读取MRCMDX寄存器操作而获知为有效数据包的,对初始化的寄存器做了多次修改依然是此结果,但是用如下方法来实现,绝不会漏掉数据包。*/ ready = dm9000_reg_read(MRCMDX); / 第一次读取,一般读取到的是 00H if(ready & 0x0ff) != 0x01)ready = dm9000_reg_read(MRCMDX); / 第二次读取,总能获取到数据 0x01) != 0x00) /若第二次读取到的不是 01H 或 00H ,则表示没有初始化成功/屏幕网卡中断 DM9000_init()

17、;/重新初始化/打开网卡中断 retrun 0;/* ready = dm9000_reg_read(MRCMDX); / read a byte without pointer increment if(!(ready & 0x01) return 0; */*以上表示若接收到的第一个字节不是“01H”,则表示没有数据包,返回0*/ status = dm9000_reg_read(MRCMD); len = DM_CMD;(status & 0xbf00) & (len 8) & else/*以上接收数据包,注意的地方与发送数据包的地方相同*/ if(len 1000) if( (HON(

18、 ETHBUF-type ) != ETHTYPE_ARP) &(HON( ETHBUF-= ETHTYPE_IP) ) packet_len = len;/*以上对接收到的数据包作一些必要的限制,去除大数据包,去除非ARP或IP的数据包*/ return HON( ETHBUF-type ); /返回数据包的类型,这里只选择是ARP或IP两种类型 注意:上面的函数用到了一些宏定义,已经在头文件中定义过,这里说明一下:其中uint16定义为两个字节的变量,根据C编译器进行定义。unsigned char Buffer1000;/定义了一个1000字节的接收发送缓冲区uint16 packet_

19、len;/接收、发送数据包的长度,以字节为单位。struct eth_hdr /以太网头部结构,为了以后使用方便unsigned char d_mac6; /目的地址unsigned char s_mac6; /源地址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 smac6; /发送端MAC地址unsigned char sipaddr4; /发送端IP地址unsigned char dmac6; /目的端MAC地址unsigned char dipaddr4; /目的端IP地址struct ip_hdr /以太网头部+IP首部结构unsigned char vhl, /4位版本号4位首部长度(0x45) tos; /服务类型(0) uint16 len,

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1