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

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

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

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端口

udelay(20);

DM_CMD = data;//将数据写到DATA端口,即写进寄存器

}

//从DM9000寄存器读数据

unsigned int dm9000_reg_read(unsigned char reg)

{

udelay(20);

DM_ADD = reg;

udelay(20);

return DM_CMD;//将数据从寄存器中读出

}

只得注意的是前面的两个宏定义DM_ADD和DM_CMD,定义的内容表示指向无符号整形变量的指针,在这里0x800300是DM9000命令端口的地址,对它的赋值操作就相当于把数据写到该地址中,即把数据写到DM9000的命令端口中。读的道理也一样。这是一种很常见的宏定义,一般在处理器中定义通用寄存器也是这样定义的。

若没有总线接口的话,可以使用IO口模拟总线时序的方法实现寄存器的读写。这里只说明实现步骤。首先将处理器的I/O端口与DM9000的IOR等引脚直接相连(电平匹配的情况下),又假设已经有宏定义“IOR”I/O端口控制DM9000的IOR引脚,其它端口控制DM9000引脚的命名相同,“PIO1”(根据处理器情况,可以是8位、16位或32位的I/O端口组成)控制数据端口。这样宏命名更直观些。写寄存器的函数如下:

void dm9000_reg_write(unsigned char reg, unsigned char data)

{

PIO1 = reg;

AEN = 0;

CMD = 0;

IOR = 1;

IOW = 0;

udelay(1);

AEN = 1;

IOW = 1;

udelay(20);

PIO1 = data;

AEN = 0;

CMD = 0;

IOR = 1;

IOW = 0;

udelay(1);

AEN = 1;

IOW = 1;

}

读寄存器的写法类似,这里就略一下了。这一过程看上去有些复杂,呵呵,其实执行起来也蛮有效率的,执行时间差不多。这种模拟总线时序的方式实际并不复杂,只是把总线方式下自动执行的过程手动的执行了一遍而已。

在DM9000中,还有一些PHY寄存器,也称之为介质无关接口MII(Media Independent Interface)寄存器。对这些寄存器的操作会影响网卡芯片的初始化和网络连接,这里不对其进行操作,所以对这些寄存器的访问方法这里也略了(在上篇文章中有介绍)。操作不当反而使网卡不能连接到网络。

至此,我们已经写好了两个最基本的函数:dm9000_reg_write()和dm9000_reg_read(),以及前面的宏定义DM_ADD和DM_CMD。下面将一直用到。

2、初始化DM9000网卡芯片。

初始化DM9000网卡芯片的过程,实质上就是填写、设置DM9000的控制寄存器的过程,这里以程序为例进行说明。其中寄存器的名称宏定义在DM9000.H中已定义好。

注:一下函数中unsigned char为一个字节unsigned int为两个字节

//DM9000初始化

void DM9000_init(void)

{
unsigned int i;

IO0DIR |= 1 < 8;

IO1CLR |= 1 < 8;

udelay(500000);

IO2SET |= 1 < 8;

udelay(500000);

IO1CLR |= 1 < 8;

udelay(500000);

/*以上部分是利用一个IO口控制DM9000的RST引脚,使其复位。这一步可以省略,可以用下面的软件复位代替*/

dm9000_reg_write(GPCR, 0x01);//设置 GPCR(1EH) bit[0]=1,使DM9000的GPIO3为输出。

dm9000_reg_write(GPR, 0x00);//GPR bit[0]=0 使DM9000的GPIO3输出为低以激活内部PHY。

udelay(5000);//延时2ms以上等待PHY上电。

dm9000_reg_write(NCR, 0x03);//软件复位

udelay(30);//延时20us以上等待软件复位完成

dm9000_reg_write(NCR, 0x00);//复位完成,设置正常工作模式。

dm9000_reg_write(NCR, 0x03);//第二次软件复位,为了确保软件复位完全成功。此步骤是必要的。

udelay(30);

dm9000_reg_write(NCR, 0x00);

/*以上完成了DM9000的复位操作*/

dm9000_reg_write(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);

/*以上是功能控制,具体功能参考上一篇文章中的说明,或参考数据手册的介绍*/

for(i=0; i<6; i++)

dm9000_reg_write(PAR + i, mac_addr[i]);//mac_addr[]自己定义一下吧,6个字节的MAC地址

/*以上存储MAC地址(网卡物理地址)到芯片中去,这里没有用EEPROM,所以需要自己写进去*/

/*关于MAC地址的说明,要参考网络相关书籍或资料*/

dm9000_reg_write(NSR, 0x2c);

dm9000_reg_write(ISR

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

网站地图

Top