這幾天一直在調試DM9000,所以關于ARM9的PWM定時器,以及看門狗定時器的操作的筆記一直也沒有整理,等抽出時間來再整理吧,DM9000的調試還是費了一些精力,不過總算能夠正常的收發數據了。對于這一塊的具體操作,我就不細寫了,給大家推薦兩篇文章,寫的非常的詳細,我在這給出鏈接:
本文引用地址:http://www.104case.com/article/201611/322174.htm單片機驅動DM9000網卡芯片(詳細調試過程):http://hi.baidu.com/mikenoodle/blog/item/dda3a4cc034e871800e9287a.html
s3c2440的網卡接口擴展:
http://blog.csdn.net/zhaocj/article/details/5672588
這兩篇文章對我的幫助很大,我想對剛剛開始調DM9000的朋友來說會有點幫助,下面我就說一下我在這個過程中覺得應該注意的問題。
一 DM9000的的基地址設置,因為擴展網卡接口要將2440的nGCSn連接到DM9000的片選引腳,所以要想選中DM9000就必須要訪問nGCSn指定的內存區域以激活nGCSn信號,我的板子連接的是nGCS4,所以訪問0x20000000開始的區域可以激活nGCS4。因為DM9000由CMD引腳區分輸入的是數據還是地址,一般將CMD引腳連接在2440的addr2引腳,所以可以通過訪問addr2分別為0和1指定的內存區域控制addr2為0還是1,這樣就能區分輸入的是數據還是命令了,所以可以將DM9000的數據口地址和地址口地址都可以確定了。
二如果PC機網絡連接不正常的話應該是我們的初始化有問題,我們可以將DM9000初始化后的寄存器的值通過串口打印出來,看看是不是正確。
三如果進入不了中斷,說明是MMU的設置問題,因為我們用到了nGCS4,所以要設置MMU。如果我們沒有考慮MMU而通過仿真運行時肯定進入不了中斷的,這時我們可以將程序燒寫到flash中,看看程序的運行情況(在這種情況下可能有時候收到的數據是正常的,而有時候收到的數據卻不正確)。
四能夠收到數據,也就是能夠激發2440的外部中斷進入中斷的話,但收到的數據卻不正確,這是可以試一下在MMU的設置中:
解決辦法是:
在MMU_SetMTT(0x20000000,0x27f00000,0x20000000,RW_CNB); //bank4 for dm9000
把RW_CNB 改為RW_NCNB//cache_off,WR_BUF 以關閉cache
五 關于數據的傳輸,我相信看了上面的這兩篇文章大家都應該對ARP數據有了一定的了解,當我們的DM9000初始化成功后,PC機就會開發板發送ARP請求信號(我的是發送了3次),這個數據是一個廣播數據,里面有PC機的MAC和IP地址,所以如果我們數據接收正常的話我們可以獲得這些信息,因為我的程序中將收到的數據進行區分,如果是ARP數據的話通過串口進行打印。當我們向PC機發送ARP請求的話(發送的數據中必須是有PC機的IP),PC機會發送一個ARP應答信號,里面包括PC機的MAC和IP,也包括開發板的MAC和IP。
六關于數據的讀取,因為收到的數據剛開始會有一個無效數據,ARP數據的這個數據一般為0,我們必須將其讀出,然后接下來的數據會是1,表示有可以接收的數據,在接下來是ARP數據的狀態為,再接下來兩個字節是是數據的長度,然后后面才是真正的數據,包括地址信息等。
上面這些就是我在這個過程中遇到的一些問題,下面我給出實驗的截圖:


這就是我收到的數據的效果圖,里面有我電腦的MAC和我設置的IP。
下面是程序代碼及分析:
#include"2440addr.h"
#include"dm9000.h"
#include"def.h"
#define DM_ADDR_PORT(*((volatile unsigned short *) 0x20000300))//地址口3為0也行
#define DM_DATA_PORT(*((volatile unsigned short *) 0x20000304))//數據口3為0也行
extern void Uart_Printf(char *fmt,...);
int tran;
unsigned char arpsendbuf1[42]={//請求信號
0xff,0xff,0xff,0xff,0xff,0xff,//以太網目標地址,全1表示為廣播地址
0x00,0x01,0x02,0x03,0x04,0x05,//以太網源地址
0x08,0x06,//幀類型:ARP幀
0x00,0x01,//硬件類型:以太網
0x08,0x00,//協議類型:IP協議
0x06,//硬件地址長度:6字節
0x04,//協議地址長度:4字節
0x00,0x01,//操作碼:ARP請求
0x00,0x01,0x02,0x03,0x04,0x05,//發送端以太網硬件地址
192, 168, 1, 50,//發送端IP協議地址
0x00,0x00,0x00,0x00,0x00,0x00,//接收端以太網硬件地址,發送請求時不用設置,為0即可,可根據IP地址轉換為相應的硬件地址,即MAC
192, 168, 1, 120//接收端IP協議地址
};
int packet_len;
U8*buffer;
extern void ChangeRomCacheStatus(int attr);
//寫DM9000寄存器
void __inline dm_reg_write(unsigned char reg, unsigned char data)
{
DM_ADDR_PORT = reg;//將寄存器地址寫到地址端口
DM_DATA_PORT = data;//將數據寫到數據端口
}
//讀DM9000寄存器
unsigned char __inline dm_reg_read(unsigned char reg)
{
DM_ADDR_PORT = reg;
return DM_DATA_PORT;//將數據從數據端口讀出
}
void delay(U32 t)
{
U32 i;
for(;t>0;t--)
{
for(i=0;i<100;i++){}
}
}
void dm_init(void)
{
//int i;
dm_reg_write(DM9000_NCR,3);//1//軟件復位DM9000
delay(30);//延時至少20μs
dm_reg_write(DM9000_NCR,0);//清除復位位
dm_reg_write(DM9000_NCR,3);//1//為了確保復位正確,再次復位
delay(30);
dm_reg_write(DM9000_NCR,0);
dm_reg_write(DM9000_GPCR,1);//設置GPIO0為輸出
delay(50);
dm_reg_write(DM9000_GPR,0);//激活內部PHY
delay(50);/////////////////////////////////////
dm_reg_write(DM9000_NSR,0x2c);//清TX狀態
dm_reg_write(DM9000_ISR,0x3f); //0xf//清中斷狀態
dm_reg_write(DM9000_RCR,0x39);//設置RX控制
dm_reg_write(DM9000_TCR,0);//設置TX控制
dm_reg_write(DM9000_BPTR,0x3f);
dm_reg_write(DM9000_FCTR,0x3a);
dm_reg_write(DM9000_FCR,0xff);
dm_reg_write(DM9000_SMCR,0x00);
dm_reg_write(DM9000_PAR0,0x00);//設置MAC地址:00-01-02-03-04-05
dm_reg_write(DM9000_PAR1,0x01);
dm_reg_write(DM9000_PAR2,0x02);
dm_reg_write(DM9000_PAR3,0x03);
dm_reg_write(DM9000_PAR4,0x04);
dm_reg_write(DM9000_PAR5,0x05);
dm_reg_write(DM9000_NSR,0x2c);//再次清TX狀態
dm_reg_write(DM9000_ISR,0x3f); //0xf//再次清中斷狀態
dm_reg_write(DM9000_IMR,0x81);//打開接受數據中斷
}
void dm_tran_packet(unsigned char *datas, int length)
{
int i;
dm_reg_write(DM9000_IMR, 0x80);//在發送數據過程中禁止網卡中斷
dm_reg_write(DM9000_TXPLH, (length>>8) & 0x0ff);//設置發送數據長度
dm_reg_write(DM9000_TXPLL, length & 0x0ff);
DM_ADDR_PORT = DM9000_MWCMD;//發送數據緩存賦予數據端口
//發送數據
for(i=0;i{
delay(50);
DM_DATA_PORT = datas[i]|(datas[i+1]<<8);//8位數據轉換為16位數據輸出
}
dm_reg_write(DM9000_TCR, 0x01);//把數據發送到以太網上
while((dm_reg_read(DM9000_NSR) & 0x0c) == 0)
;//等待數據發送完成
delay(50);
評論