新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 十一 ARM9(2440)的網卡接口擴展

        十一 ARM9(2440)的網卡接口擴展

        作者: 時間:2016-11-27 來源:網絡 收藏
        這幾天一直在調試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);


        上一頁 1 2 下一頁

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 山东省| 康平县| 新兴县| 龙里县| 洛隆县| 抚远县| 清水河县| 江油市| 枝江市| 斗六市| 凉城县| 固镇县| 加查县| 新乡市| 韶山市| 双峰县| 荣成市| 抚远县| 七台河市| 平阳县| 常州市| 宜君县| 大姚县| 柘城县| 庆元县| 江孜县| 田阳县| 芜湖市| 泾阳县| 广汉市| 利辛县| 易门县| 霞浦县| 祁连县| 龙井市| 富源县| 东城区| 方山县| 鄂托克旗| 商河县| 蓬莱市|