开头的话,好吧,我只能说写驱动程序的人都是疯子,疯子才能进入这个领域,或者一开始你没疯,后来你疯了。真的,当问题出现的时候,有可能你无数次相信硬件没问题,是自己的程序有问题,也可能最后真的是硬件本来就是坏的。或者你到最后都没搞清楚到底是硬件的问题还是软件的问题。(按理说现在程序界这么火,说明底层支持着的硬件还是很可靠的,去找自己的问题吧!我也不知道我在说什么。
进入正题。
第一部分,如果你不知道单片机和DM9000网卡的以太网通讯思路,请赶紧百度上查阅DM9000的以太网设计,如果直接看DM9000数据手册,真的会看死人。建议先看看整体思路,再然后有时间最好通看一下DM9000的数据手册。
第二部分,2440单片机的知识至少要掌握中断和串口(当然越多越好)。搞清楚中断入口程序的地址和中断函数的联系。
第三部分,DM9000这部分程序的编写。主要部分分三块。
第一块,DM9000的初始化
void DM9000_init(void)
{
uint32 i;
Test_DM9000AE();
IOSetInit();
dm9000_reg_write(DM9000_IMR, 0x80); //中断关闭
//初始化设置步骤: 1
dm9000_reg_write(DM9000_GPCR, 0x01); //设置 GPCR(1EH) bit[0]=1,使DM9000的GPIO3为输出。
dm9000_reg_write(DM9000_GPR, 0x00); //GPR bit[0]=0 使DM9000的GPIO3输出为低以激活内部PHY。
udelay(500); //延时2ms以上等待PHY上电。
//初始化设置步骤: 2
dm9000_reg_write(DM9000_NCR, 0x03); //软件复位
udelay(300); //延时20us以上等待软件复位完成
dm9000_reg_write(DM9000_NCR, 0x00); //复位完成,设置正常工作模式。
dm9000_reg_write(DM9000_NCR, 0x03); //第二次软件复位,为了确保软件复位完全成功。此步骤是必要的。
udelay(300);
dm9000_reg_write(DM9000_NCR, 0x00);
//初始化设置步骤: 3
dm9000_reg_write(DM9000_NSR, 0x2c); //清除各种状态标志位
dm9000_reg_write(DM9000_ISR, 0xbf); //清除所有中断标志位
//初始化设置步骤: 4
<span style="white-space:pre"> </span>
//初始化设置步骤: 5
for(i=0; i<6; i++)
dm9000_reg_write(DM9000_PAR + i, mac_addr[i]);//mac_addr[]自己定义一下吧,6个字节的MAC地址
//初始化设置步骤: 6
dm9000_reg_write(DM9000_NSR, 0x2c); //清除各种状态标志位
dm9000_reg_write(DM9000_ISR, 0x3f); //清除所有中断标志位
//初始化设置步骤: 7
dm9000_reg_write(DM9000_IMR, 0x81); //中断使能}
第二块,发送程序的编写
void DM9000_sendPcket(uint8 *datas, uint32 length)
{
uint32 len,i;
//uint8 tmp;
//Printf("发送数据\r\n");
dm9000_reg_write(DM9000_IMR,0x80); //先禁止网卡中断,防止在发送数据时被中断干扰
len = length; //把发送长度写入
dm9000_reg_write(DM9000_TXPLH, (len>>8) & 0x0ff);
dm9000_reg_write(DM9000_TXPLL, len & 0x0ff);
DM_ADD = DM9000_MWCMD;
for(i=0; i<len; i+=2) //16 bit mode
{
udelay(2);
DM_CMD = datas[i] | (datas[i+1]<<8);
}
dm9000_reg_write(DM9000_TCR, 0x01); //发送数据到以太网上
while(1)//等待数据发送完成
{
uint8 data;
data = dm9000_reg_read(DM9000_TCR);//DM9000_NSR
if((data&0x01) == 0x00) break;
}
/* tmp = dm9000_reg_read(DM9000_NSR);
if((tmp & 0x01) =&