日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

单片机驱动DM9000网卡芯片(详细调试过程)【下】

發布時間:2025/1/21 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 单片机驱动DM9000网卡芯片(详细调试过程)【下】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

???

http://hi.baidu.com/mcu8031/blog/item/c95903138671c625dc540171.html

單片機驅動DM9000網卡芯片(詳細調試過程)【下】

4、驗證初始化中的各個函數。

下面我們來看一下,上面所寫的初始化函數是否可用。以上我們寫好了三個函數,分別為

DM9000_init(),sendpacket()和receivepacket(),保存并命名為dm9000.c。既然我們要進行調試,當

然要有結果輸出,根據自己的處理器的情況寫一個串口程序,這些函數是學某個單片機的基礎,這里不

做詳細介紹,用到是時候會在函數里注釋一下。

接下來我們來寫個主函數,新建C文件,命名為mian.c,填寫如下函數:

void main(void)

{

??? unsigned int i;

??? unsigned char c;

??? uart0_init();//初始化串口,調試時用到

??? DM9000_init();//初始化網卡

??? print_regs();/*通過串口,將DM9000中的寄存器打印出來,顯示在超級終端上。此函數根據自己

的處理器進行修改,功能僅僅是讀DM9000寄存器dm9000_reg_read(),再通過串口打印出來而已*/

}

函數寫好,保存文件,連接硬件,連接網線到電腦上或局域網上,運行結果如下圖所示:

圖4 顯示寄存器值

這里首先檢查,各個控制寄存器是否是自己寫進去的值,在檢查狀態寄存器是否正確,其中主要要

看NSR寄存器的bit[6]是否為“1”,該位表示是否連接成功。本例中NSR的值為40H,括號里的數為對應

的十進制數。

下面我們將主函數改進一下,增加個中斷接收函數,查看是否能接收到數據。

void main(void)

{

??? unsigned int i;

??? unsigned char c;

??? uart0_init();//初始化串口,調試時用到

??? DM9000_init();//初始化網卡

/********************************************************************************/

/*這一部分要根據自己的處理器情況,將DM9000的INT引腳連接到處理器的外部中斷上,打開中斷*/

/********************************************************************************/

??? sendpacket(60);/*我事先已經在Buffer[]中存儲了ARP請求數據包,這里就直接發送了,以便接收

ARP應答包。大家可以先參考后面講的ARP協議,根據自己機器的情況,將數據事先存到Buffer[]中*/

??? while(1);//等待中斷

}

void int_issue(void) //中斷處理函數,需要根據自己的處理器進行設置

{

??? unsigned int i;

??? i = receivepacket(Buffer);//將數據讀取到Buffer中。

int_again :

??? if(i == 0)

??? {

??????? return;

??? }

???? else

???? {

??????? print_buffer();//將接收到的所有數據打印出來

???????? while(1);//停止在這里等待觀察,注意:實際應用中是不允許停止在中斷中的。

???? }

/************************************************************************************/

/*這里加上這一段,目的是判斷中斷期間是否接收到其它數據包。有則加以處理。不加也完全可以*/

/* 根據自己的處理器,判斷處理器是否還處在中斷狀態,若是則進行如下操作,不是則跳過該段。*/

??? i = receivepacket(Buffer);

??? if(i != 0)

??? {

??????? goto int_again;

??? }

/************************************************************************************/

}

編譯調試,運行結果如下:

圖5 接收數據包中的數據

這是一個ARP應答包,包含了我電腦上的MAC地址和局域網內的IP地址。反正我也不是啥重要人物,

這里就不保密了,呵呵。

如果一些順利,到這里對DM9000網卡芯片的初始化工作就完成了。如果出現問題,首先要

檢查寄存器的值是否正確。可以將DM9000中的寄存器打印出來,查看到底是哪里的問題。如果打印出的

值很混亂,在確保串口程序無誤的前提下,查看硬件連接,以及寄存器讀寫時序是否正確,重復調試幾

次查找原因。

三、ARP協議的實現

??? 1、ARP協議原理簡述

??? ARP協議(Address Resolution Protocol 地址解析協議),在局域網中,網絡中實際傳輸的是“

幀”,幀里面有目標主機的MAC地址。在以太網中,一個注意要和另一個主機進行直接通信,必須要知

道目標主機的MAC地址。這個MAC地址就是標識我們的網卡芯片唯一性的地址。但這個目標MAC地址是如

何獲得的呢?這就用到了我們這里講到的地址解析協議。所有“地址解析”,就是主機在發送幀前將目

標IP地址轉換成MAC地址的過程。ARP協議的基本功能就是通過目標設備的IP地址,查詢目標設備的MAC

地址,以保證通信的順利進行。所以在第一次通信前,我們知道目標機的IP地址,想要獲知目標機的

MAC地址,就要發送ARP報文(即ARP數據包)。它的傳輸過程簡單的說就是:我知道目標機的IP地址,

那么我就向網絡中所有的機器發送一個ARP請求,請求中有目標機的IP地址,請求的意思是目標機要是

收到了此請求,就把你的MAC地址告訴我。如果目標機不存在,那么此請求自然不會有人回應。若目標

機接收到了此請求,它就會發送一個ARP應答,這個應答是明確發給請求者的,應答中有MAC地址。我接

到了這個應答,我就知道了目標機的MAC地址,就可以進行以后的通信了。因為每次通信都要用到MAC地

址。

??? ARP報文被封裝在以太網幀頭部中傳輸,如圖為ARP請求報文的頭部格式。

圖6 用于以太網的ARP請求或應答分組格式

注意,以太網的傳輸存儲是“大端格式”,即先發送高字節后發送低字節。例如,兩個字節的數據

,先發送高8位后發送低8位。所以接收數據的時候要注意存儲順序。

整個報文分成兩部分,以太網首部和ARP請求/應答。下面挑重點講述。

“以太網目的地址”字段:若是發送ARP請求,應填寫廣播類型的MAC地址FF-FF-FF-FF-FF-FF,意思是

讓網絡上的所有機器接收到;

“幀類型”字段:填寫08-06表示次報文是ARP協議;

“硬件類型”字段:填寫00-01表示以太網地址,即MAC地址;

“協議類型”字段:填寫08-00表示IP,即通過IP地址查詢MAC地址;

“硬件地址長度”字段:MAC地址長度為6(以字節為單位);

“協議地址長度”字段:IP地址長度為4(以字節為單位);

“操作類型”字段:ARP數據包類型,0表示ARP請求,1表示ARP應答;

“目的以太網地址”字段:若是發送ARP請求,這里是需要目標機填充的。

??? 2、ARP的處理程序

??? ARP協議原理很簡單,下面我們來編寫ARP協議的處理函數。新建文件命名為arp.c,填寫如下函數

unsigned char mac_addr[6] = {*,*,*,*,*,*};

unsigned char ip_addr[4] = { 192, 168, *, * };

unsigned char host_ip_addr[4] = { 192, 168, *, * };

unsigned char host_mac_addr[6]={ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

unsigned char Buffer[1000];

uint16 packet_len;

/*這些全局變量,在前面將的文件中有些已經有過定義,這里要注意在前面加上“extern”關鍵字。“

*”應該根據自己的機器修改*/

#define HON(n) ((((uint16)((n) & 0xff)) << 8) | (((n) & 0xff00) >> 8))

/*此宏定義是將小端格式存儲的字(兩個字節)轉換成大端格式存儲*/

void arp_request(void) //發送ARP請求數據包

{

//以太網首部

memcpy(ARPBUF->ethhdr.d_mac, host_mac_addr, 6);

/*字符串拷貝函數,文件要包含<string.h>頭文件。參數依次是,拷貝目標指針,拷貝數據源指針,拷

貝字符數*/

memcpy(ARPBUF->ethhdr.s_mac, mac_addr, 6);

ARPBUF->ethhdr.type = HON( 0x0806 );

/*小端格式的編譯器,可以用HON()宏來轉換成大端格式,如果你的編譯器是大端格式,直接填寫

0x0806即可*/

/*就是簡單的按照協議格式填充,以下同*/

//ARP首部

ARPBUF->hwtype = HON( 1 );

ARPBUF->protocol = HON( 0x0800 );

ARPBUF->hwlen = 6;

ARPBUF->protolen = 4;

ARPBUF->opcode = HON( 0 );

memcpy(ARPBUF->smac, mac_addr, 6);

memcpy(ARPBUF->sipaddr, ip_addr, 4);

memcpy(ARPBUF->dipaddr, host_ip_addr, 4);

packet_len = 42;//14+28=42

sendpacket( Buffer, packet_len );

}

注釋:ARPBUF的宏定義和ARP首部結構,在前面已經講過。同時注意執行該函數時中斷的處理。這里沒

作處理。

看上去很easy吧,下面函數實現接收ARP請求或接收ARP應答的處理。

unsigned char arp_process(void)//ARP接收函數,成功返回1,否則返回0

{

//簡單判斷ARP數據包有無損壞,有損壞則丟棄,不予處理

if( packet_len < 28 )//ARP數據長度為28字節為無效數據

{

return 0;

}

switch ( HON( ARPBUF->opcode ) )

{

?? case 0??? : //處理ARP請求

???????? if( ARPBUF->dipaddr[0] == ip_addr[0] &&

???????????? ARPBUF->dipaddr[1] == ip_addr[1] &&

???????????? ARPBUF->dipaddr[2] == ip_addr[2] &&

???????????? ARPBUF->dipaddr[3] == ip_addr[3] )//判斷是否是自己的IP,是否向自己詢問MAC地址

???????? {
???????????? ARPBUF->opcode = HON( 2 );//設置為ARP應答

???????????? memcpy(ARPBUF->dmac, ARPBUF->smac, 6);

???????????? memcpy(ARPBUF->ethhdr.d_mac, ARPBUF->smac, 6);

???????????? memcpy(ARPBUF->smac, mac_addr, 6);

???????????? memcpy(ARPBUF->ethhdr.s_mac, mac_addr, 6);

???????????? memcpy(ARPBUF->dipaddr, ARPBUF->sipaddr, 4);

???????????? memcpy(ARPBUF->sipaddr, ip_addr, 4);

???????????? ARPBUF->ethhdr.type = HON( 0x0806 );

???????????? packet_len = 42;

???????????? sendpacket( Buffer, packet_len );//發送ARP數據包

???????????? return 1;

???????? }

???????? else

???????? {

???????????? return 0;

???????? }

???????? break;

?? case 1??? : //處理ARP應答

???????? if( ARPBUF->dipaddr[0] == ip_addr[0] &&

???????????? ARPBUF->dipaddr[1] == ip_addr[1] &&

???????????? ARPBUF->dipaddr[2] == ip_addr[2] &&

???????????? ARPBUF->dipaddr[3] == ip_addr[3] )//再次判斷IP,是否是給自己的應答

???????? {

????????? memcpy(host_mac_addr, ARPBUF->smac, 6);//保存服務器MAC地址

????????? return 1;

???????? }

???????? else

???????? {

???????????? return 0;

???????? }

???????? break;

default???? ://不是ARP協議

???????? return 0;

}

}

根據ARP協議格式看這兩個函數并不困難。于是我們又得到兩個函數:arp_request()和

arp_process()。

??? 3、ARP程序調試

下面我們修改主函數和中斷處理函數。

將mian()函數中的“sendpacket(60);”語句換成“arp_request();”語句。

void int_issue(void) //中斷處理函數,需要根據自己的處理器進行設置

{

??? unsigned int i;

??? i = receivepacket(Buffer);//將數據讀取到Buffer中。

??? if(i == 0)

??? {

??????? return;

??? }

???? else

???? {

???????? i = arp_process();

???????? if(i == 1)//判斷是否是ARP協議

???????????? print_hostmacaddr();//打印目標機的MAC地址,就是用串口打印host_mac_addr[]中的6

個字節

???? }

}

保存運行調試。

圖7 主機MAC地址

至此,關于DM9000的調試過程就完成了。之后我還調試了UDP通訊、TCP通訊等,主要是關于協議的

處理了,這里就不介紹了。有興趣的朋友可以參看《TCP/IP協議》第一卷,將會有很大幫助。希望這些

調試過程能為讀者或多或少的提供些有用的信息,也歡迎大家和我一起討論。

我的Email:mengqx25@163.com

轉載于:https://www.cnblogs.com/xilentz/archive/2010/07/12/1775611.html

總結

以上是生活随笔為你收集整理的单片机驱动DM9000网卡芯片(详细调试过程)【下】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 96毛片| 亚洲激情另类 | 亚洲tv在线观看 | 日日射日日操 | 亚洲第5页 | 在线观看欧美日韩视频 | 美美女高清毛片视频免费观看 | 免费伊人 | 欧美人与动牲交a欧美精品 欧美三级在线看 | 一级片aaaaa 国产又黄又粗又猛又爽 | 久久精品—区二区三区舞蹈 | 视频在线观看91 | 国产亚洲精品美女久久久久 | 亚洲精品1 | 日韩欧美国产精品综合嫩v 国产小毛片 | 欧美日韩精品在线观看 | 成人在线视频免费观看 | 久久资源365 | 狠狠爱婷婷| 国产精品毛片在线 | 一区二区三区伦理 | 少妇av片 | 日本免费一区二区在线 | 岳乳丰满一区二区三区 | 亚洲AV成人午夜无码精品久久 | 91禁看片 | 91av导航 | 亚洲 欧美 自拍偷拍 | 天天干人人干 | 97精品人妻一区二区三区 | 欧美日韩在线视频免费 | 亚洲成人网在线观看 | a级一片 | 色婷婷久| 久久精品视频8 | 熟妇高潮精品一区二区三区 | 国产一区二区不卡视频 | 麻豆精品在线 | 男生插女生视频在线观看 | 咪咪色影院| 3d成人动漫在线观看 | 少妇熟女高潮流白浆 | 免费国产黄色 | 五月婷婷色丁香 | 三浦理惠子av在线播放 | 国产成人亚洲一区二区 | 国产三级精品三级 | jizzjizz日本免费视频 | 免费黡色av| 黄色aa大片 | 国产a级淫片 | 久久精品久久精品久久 | av官网在线 | 日本一级一片免费视频 | 亚洲欧美999 | 亚洲图片自拍偷拍区 | 黄色av网站在线免费观看 | 国产精品毛片一区二区 | 麻豆av网址 | 亚洲欧美在线一区二区 | 日韩av在线观看免费 | 日韩视频免费观看高清完整版在线观看 | 九一国产在线 | 一区二区三区黄色录像 | 草草地址线路①屁屁影院成人 | 春物催眠 | 少妇性高潮视频 | 中文字幕网伦射乱中文 | 伊人9| 国产无遮挡免费观看视频网站 | 日韩丝袜一区 | 国产91一区二区三区 | 亚洲乱码国产乱码精品精98午夜 | 欧美一区二区国产 | 亚洲一区av在线 | 亚洲人成在线观看 | 香蕉视频一区二区三区 | 九九影院最新理论片 | 国产精品久久久国产盗摄 | 美国色综合 | 亚欧美视频 | 麻豆传媒网站 | 亚洲综合在线播放 | 人妻少妇被猛烈进入中文字幕 | 日韩欧美久久 | a黄色大片 | www.99re7.com| 色播综合 | 国产日韩精品在线 | 91网站在线免费观看 | 亚洲福利社 | 亚洲一级在线观看 | 日韩一区二区三区电影 | 日韩一区二区在线看 | 黄色片免费观看视频 | 国产人成免费视频 | 日日摸夜夜添夜夜 | 精品免费国产一区二区三区 | 国产精选一区二区三区 |