1.DM9000简介
DM9000 是一款完全集成的、 性价比高、 引 脚数少、 带有通用处理器接口的 单芯片快速以太网控制器。 自 带一个 10/100M PHY 和 4K 双字的 SRAM , DM9000A 为适应各种处理器提供了 8 位、 16 位数据接口访问 内部存储器, DM9000 拥有自 动协商功能, DM9000 特性如下:
- 集成自 适应 10/100M 收发器。
- 内置 16k 字节的 SRAM。
- 支持硬件帧校验。
- 兼容 3.3V 和 5.0V 输入输出电压。
DM9000 有多种型号, 有 100 引 脚和 48 引 脚的, 开发板选择的是 48 引 脚的 DM9000,型号为 DM9000CEP。
2.DM9000硬件接口
引脚 | 说明 |
PWRST | DM9000 复位信号 |
WR(IOW) | 处理器写命令 |
RD(IOR) | 处理器读命令 |
CMD | 命令/数据标志, 0,读写命令; 1,读写数据 |
CS | DM9000 的片选信号 |
SD0~SD15 | 16 位双向数据线 |
DM9000 的 34(INT) 引 脚为中断输出引 脚, 默认情况下该引 脚高电平有效。 可以通过设置 DM9000 的 20(EEDCK) 引 脚来改变 INT 的有效电平, 当 EEDCK 拉高 以后, INT 低电平有效, 否则的话 INT 是高电平有效的。开发板上 R66 电阻为 EEDCK 的上拉电阻, 因此开发板上 DM9000 的 INT 引 脚是低电平有效的。
DM9000 支持 8 位和 16 位两种数据位宽, 可以通过 DM9000 的 21(EEDCS) 引 脚设置其数据位宽, 当 EEDCS 上拉的时候 DM9000 选择 8 位数据位宽, 否则的话选择 16 位数据位宽。 开发板上的 R65 电阻为 EECS 的上拉电阻, 但是此电阻并未焊接! DM9000 芯片的数据位宽为 16 位。
3.开发平台
硬件平台:STM32F103ZET6开发板集成DM9000网卡
开发环境:Windows下Keil5
驱动时序:硬件FSMC
若没有DM9000有线网卡设备,可自行购买DM9000网卡模块.
DM9000网卡模块链接:DM9000有线网卡
4.DM9000硬件配置
DM9000 网卡接在 FSMC 的第 2 块上,数据线地址: 0x64000000
PA7 地址线作为命令与数据线切换引脚。
外接16位宽度存储器: HADDR[25:1] FSMC_A[24:0]
外部地址线0对应内部地址线1。
0x64000000基地址:01100100000000000000000000000000
0x64000000写数据:01100100000000000000000000000000
0x64000100写命令:01100100000000000000000100000000
- DM9000硬件初始化:
/******************DM9000初始化**************
**硬件接口:
** FSMC_D0~D1 -- PD14~PD15
** FSMC_D2~D3 -- PD0~PD1
** FSMC_D4~D12 -- PE7~PE15
** FSMC_D13~D14-- PD8~PD9
** FSMC_D15 -- PD10
** CS(FSMC_NE2) -- PG9(片选)
** WR(FSMC_NWE) -- PD5(写使能)
** RD(FSMC_NOE) -- PD4(读使能)
** DM9000_RST -- PD7(复位脚)
** CMD(FSMC_A7) -- PF13(数据命令选择脚)
** DM9000_INT --PG6(中断脚)
**
*********************************************/
void DM9000_GPIO_Init(void)
{
/*开时钟*/
RCC->APB2ENR|=1<<3;//PB
RCC->APB2ENR|=1<<5;//PD
RCC->APB2ENR|=1<<6;//PE
RCC->APB2ENR|=1<<7;//PF
RCC->APB2ENR|=1<<8;//PG
GPIOD->CRL&=0x0F00FF00;//PD5写使能,PD4读使能,PD7复位脚
GPIOD->CRL|=0x30BB00BB;
GPIOD->CRH&=0x00FFF000;
GPIOD->CRH|=0xBB000BBB;
GPIOE->CRL&=0x0FFFFFFF;
GPIOE->CRL|=0xB0000000;
GPIOE->CRH&=0x00000000;
GPIOE->CRH|=0xBBBBBBBB;
GPIOG->CRH&=0xFFFFFF0F;
GPIOG->CRH|=0x000000B0;//片选NE2
GPIOF->CRH&=0xFF0FFFFF;
GPIOF->CRH|=0x00B00000;//数据命令选择脚
GPIOG->CRL&=0xF0FFFFFF;
GPIOG->CRL|=0x08000000;//DM9000中断脚
GPIOG->ODR|=1<<6;//上拉
EXTI->IMR|=1<<6; //开放中断线6的中断请求
EXTI->FTSR|=1<<6; //允许中断线6下降沿触发请求
RCC->APB2ENR|=1<<0;//AFIO时钟使能
AFIO->EXTICR[1]&=~(0xF<<(2*4));//选择输入源为PG6
AFIO->EXTICR[1]|=0x6<<(2*4);//选择输入源为PG6
STM32_NVIC_SetPriority(EXTI9_5_IRQn,1,1);//设置优先级
/*FSMC核心寄存器配置*/
RCC->AHBENR|=1<<8;//FSMC
FSMC_Bank1->BTCR[2]=0;//BCR2
FSMC_Bank1->BTCR[3]=0;//BTR2
FSMC_Bank1->BTCR[2]&=~(0x1<<19);//异步模式
FSMC_Bank1->BTCR[2]&=~(0x1<<14);//读写使用相同时序
FSMC_Bank1->BTCR[2]|=1<<12;//允许写操作
FSMC_Bank1->BTCR[2]|=0x1<<4;//16位宽度
FSMC_Bank1->BTCR[3]|=0x1<<8;//2个时钟周期
FSMC_Bank1->BTCR[3]&=~(0xF<<4);//地址保持时间1个时钟周期
FSMC_Bank1->BTCR[3]&=~(0xF<<0);//地址保持时间1个时钟周周期
FSMC_Bank1->BTCR[2]|=1<<0;//启动存储器块
}
- 底层读写数据:
/******************向指定寄存器写入数据***********/
void DM9000_WriteReg(u16 reg,u16 dat)
{
DM9000_RW_REG=reg;
DM9000_RW_DAT=dat;
}
/*******************读取指定寄存器的数据************/
u16 DM9000_ReadReg(u16 reg)
{
u16 data;
DM9000_RW_REG=reg;
data=DM9000_RW_DAT;
return data;
}
5.获取网卡信息
#include "dm9000.h"
u8 dm9000_tx_buff[64]={0x11,0x22,0x33,0x44,0x55};
u8 dm9000_rx_buff[1024];
int main()
{
u8 stat;
u16 i;
int len;
Beep_Init();
Usartx_Init(USART1,115200,72);
TIMx_Init(TIM2,72,20*1000);
printf("初始化完成\r\n");
/*DM9000初始化*/
if(DM9000_Init()==0)printf("DM9000初始化成功\r\n");
else printf("DM9000初始化失败\r\n");
/*获取DM9000工作模式*/
stat=DM9000_Get_SpeedAndDuplex();//获取连接状态和工作方式
if(stat!=0xff)printf("网卡速度:%d Mbps 模式:%s\r\n",(stat&0x02)?10:100,(stat&0x01)?"全双工":"半双工");
else printf("DM9000网卡状态信息获取失败!\r\n");
while(1)
{
len=DM9000_ReadPacketLen();//读取数据包长度
if(len>0)
{
printf("读取数据长度:%d\r\n",len);
DM9000_ReadPacketData(dm9000_rx_buff,len);//读取数据
for(i=0;i<len;i++)
{
printf("%#x ",dm9000_rx_buff[i]);
}
printf("\r\n");
}
}
}