娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2024年11月04日(星期一)

正在發生

2021年11月04日 | 2440+dm9000A裸機以太網通訊

發布者:RadiantBreeze 來源: eefocus關鍵字:以太網通訊 手機看文章 掃描二維碼
隨時隨地手機看文章

開頭的話,好吧,我只能說寫驅動程序的人都是瘋子,瘋子才能進入這個領域,或者一開始你沒瘋,后來你瘋了。真的,當問題出現的時候,有可能你無數次相信硬件沒問題,是自己的程序有問題,也可能最后真的是硬件本來就是壞的?;蛘吣愕阶詈蠖紱]搞清楚到底是硬件的問題還是軟件的問題。(按理說現在程序界這么火,說明底層支持著的硬件還是很可靠的,去找自己的問題吧!我也不知道我在說什么。


進入正題。


第一部分,如果你不知道單片機和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

   

//初始化設置步驟: 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("發送數據rn");

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    {

        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) == 0x04)

    {

    if((dm9000_reg_read(DM9000_TSR1)&0xfc) == 0x00)

    Printf("TSR1成功rn");

    else

    Printf("TSR1失敗rn");   

    }

    else

    {

    if((dm9000_reg_read(DM9000_TSR2)&0xfc) == 0x00)

    Printf("TSR2成功rn");

    else

    Printf("TSR2失敗rn");

    }

    */

    dm9000_reg_write(DM9000_NSR, 0x2c); //清除狀態寄存器,由于發送數據沒有設置中斷,因此不必處理中斷標志位

    dm9000_reg_write(DM9000_IMR, 0x81); //DM9000網卡的接收中斷使能

//Printf("發送數據完成rn");

}


第三塊,接受程序的編寫,最難的就是接收程序了,因為這里涉及到中斷,自己之前配置好外部中斷,中斷程序中接收DM9000的接收包。然后坑爹的是以太網幀開始位置的確定,到底從DM9000接收緩存的那個地方把數據復制到單片機內存中。手冊上說的是(0x01,狀態字節,長度低字節,長度高字節)這四個字節作為識別區,先用預讀取指令讀取緩沖區的字節,判斷是0x00還是0x01,否則就復位DM9000網卡,尼瑪坑爹就在這里啊,復位還是不好使啊。然后預讀取完只能直接讀取下面的字節了,但這樣會導致讀取的數據不對,可能讀到的數據并不是以真正的目的物理地址開頭的數據,可能錯位,前移或者后移(我不知道是不是網卡初始化對不對)。所以我只能這么做了,直接檢測0x01字節,加上判斷目的物理地址是否正確來確定以太網幀的位置,以及這個幀是否是傳給自己的。理論上這是可靠的。以下為代碼。

void IOSetInit(void)

{

rGPFCON = (rGPFCON & (~(0x03<<14))) | (0x02<<14); //GPF7設置為EINT7

rEXTINT0 = (rEXTINT0 & (~(0x07<<28))) | (0x01<<28);

rEINTMASK = rEINTMASK & (~(0x01<<7));

ClearPending(BIT_EINT4_7);

pISR_EINT4_7 = (U32)Eint7_ISR;

rINTMSK = rINTMSK & (~(BIT_EINT4_7));

}

static void __irq Eint7_ISR(void)

{

uint32 i;

uint16 type,m,n;

//Printf("Eint7中斷服務rn");

//VAR_RETURN VARRETURN;

//VAR_RETURN *var_re=&VARRETURN;

Buffer[12]=0,Buffer[13]=0;

len = receivepacket(Buffer);

//后面的可以自己添加,這里省略

}




uint32 receivepacket(uint8 *datas)

{

uint16 i,tmp,len=0,status=0;

uint8 ready=0;

 

//ready = 0; //希望讀取到"01H"

//status = 0; //數據包狀態

//len = 0;     //數據包長度

    if(dm9000_reg_read(DM9000_ISR) & 0x01)

    {

        dm9000_reg_write(DM9000_ISR, 0x01); //清除接收中斷標志位

    }

    else return 0;

//else { Printf("你好rn");return 0;}

//DM_ADD=DM9000_MRCMDX;

//ready = DM_CMD; // 第一次讀取,一般讀取到的是 00H

    //Printf("預讀取第一次:%xrn",ready);

//ready = DM_CMD ; // 第一次讀取,一般讀取到的是 01H

//Printf("預讀取第二次:%xrn",ready);

    

    

    

    DM_ADD = DM9000_MRCMD;

   

    status=DM_CMD ;//讀狀態字節

    while((status&0xff)!=0x01)

    {

    status=DM_CMD ;

    

    }

    //status=(status&0xff00)>>8;

    

    len = DM_CMD; //讀數據包長度

    

   

    //Printf("st=%x status=%x  len= %xrn",st,status,len);

    if( (len < 1522))//!(status & 0xbf) &&

    {

   

        for(i=0; i<6; i+=2)// 這個FOR語句是為了判斷數據包是否傳給自己,即檢查MAC地址

        {

            //udelay(20);

            tmp = DM_CMD;

            datas[i] = tmp & 0x0ff;

            if((datas[i]!=0xff)&&(datas[i]!=mac_addr[i])) return 0;

            datas[i + 1] = (tmp >> 8) & 0x0ff;

            if((datas[i+1]!=0xff)&&(datas[i+1]!=mac_addr[i+1])) return 0;

        }

        //Printf("狀態字:%xrn",status);

       

       

        for(i=6; i        {

            //udelay(20);

            tmp = DM_CMD;

            datas[i] = tmp & 0x0ff;

            datas[i + 1] = (tmp >> 8) & 0x0ff;

            

        }

  

        

    }

    else return 0;

// if(len > 1000) return 0;

//  if( (HON( ETHBUF->type ) != ETHTYPE_ARP) && (HON( ETHBUF->type ) != ETHTYPE_IP) )

// return 0;

 

   

return len;

}


第四部分:TCP/IP的知識(需要自己查資料看)。這里就是對接收到的以太網幀進行解封,和在發送數據之前對數據包進行封裝。鑒于TCP協議稍復雜,我暫時實現UDP協議。UDP數據包發送之前,需要先檢查本地是否有接收方IP地址所對應的物理地址,如果沒有,需要先發送ARP請求包(廣播),得到應答包以后解析應答包得到物理地址。然后在加上接收方目的物理地址發送加上數據的UDP包(非廣播)。所以這里至少要寫ARP請求包和發送ARP應答包的程序,UDP的封裝和解封程序(如果用UDP協議的話),當然也可以用TCP協議。

首先是TCP/IP一些報頭的結構體:


typedef struct eth_hdr //以太網頭部結構,為了以后使用方便

{

uint8 d_mac[6];    //目的地址

uint8 s_mac[6];    //源地址

uint16 type;    //協議類型

}ETH_HDR;

 

typedef struct arp        //ARP首部結構

{

uint16 hwtype;      //硬件類型(1表示傳輸的是以太網MAC地址)

uint16 protocol; //協議類型(0x0800表示傳輸的是IP地址)

uint8 hwlen; //硬件地址長度(6)

uint8 protolen; //協議地址長度(4)

uint16 opcode; //操作(1表示ARP請求,2表示ARP應答)

uint8 smac[6]; //發送端MAC地址

uint8 sipaddr[4]; //發送端IP地址

uint8 dmac[6]; //目的端MAC地址

uint8 dipaddr[4]; //目的端IP地址

}ARP;

 

typedef struct ip     //IP首部結構

{

uint8 vhl;      //4位版本號4位首部長度(0x45)

uint8 tos; //服務類型(0)

uint16 len; //整個IP數據報總字節長度

uint16 ipid;            //IP標識

uint16 ipoffset;      //3位標識13位偏移

uint8 ttl;              //生存時間(32或64)

uint8 proto;          //協議(1表示ICMP,2表示IGMP,6表示TCP,17表示UDP)

uint16 ipchksum;    //首部校驗和

uint8 srcipaddr[4];    //源IP

uint8 destipaddr[4];    //目的IP

}IP;

 

typedef struct tcp     //IP首部結構

{

uint16  sport;              //源端口號

uint16  dport; //目的端口號

uint32  sequencenum; //順序號

uint32  acknowledgenum; //確認號

uint8   tcplength;          //低四位為TCP報頭字(32位)的個數,高四位必須為0,是保留位

uint8   flags;    //低兩位為保留位,高6位為標志位[2:7]依次為

                            //URG:緊急指針。用到的時候值為1,用來處理避免TCP數據流中斷

                            //ACK:置1時表示確認號為合法,為0的時候表示數據段不包含確認信息,確認號被忽略。  

//PSH:置1時請求的數據段在接收方得到后就可直接送到應用程序,而不必等到緩沖區滿時才傳送。

//RST:用于復位因某種原因引起出現的錯誤連接,也用來拒絕非法數據和請求。

//SYN:在連接請求中,SYN=1,ACK=0,連接響應時,SYN=1,ACK=1。

//FIN:用來釋放連接,表明發送方已經沒有數據發送了。

uint16  window; //指定關于發送端能傳輸的下一段的大小的指令,表示想收到的每個TCP數據段的大小。

uint16  tcpchksum; //TCP校驗和

uint16  urgentpoint;  //緊急指針16位,緊急指針指出在本報文段中的緊急數據的位置,在URG標志設置了時才有效。

}TCP;

 

typedef struct udp              //UDP首部結構

{

uint16  sport;              //源端口號                        (34 35)

uint16 dport; //目的端口號                       (36 37)

uint16  length; //UDP數據包報總長度                (38 39)

uint16  udpchksum; //UDP校驗和(可選項)                (40 41)

}UDP;


各層封裝函數(解封函數就不貼了,比較靈活,不必要的情況下,可以簡單判斷一下就能知道各層是什么協議):

//這是一個物理層的程序,微數據加上MAC報頭

//by hongfangyu 2016/1/9

 

#include "dm9000.h"

 

void MAC_pack(uint8 *datas,uint16 length,uint16 type)

{

ETH_HDR *MACBUF;

uint8 packhead[14];

MACBUF=(ETH_HDR *)&packhead;

memcpy(MACBUF->d_mac, host_mac_addr, 6);

[1] [2]
關鍵字:以太網通訊 引用地址:2440+dm9000A裸機以太網通訊

上一篇:mini2440 裸機編程 -led
下一篇:一起學mini2440裸機開發(五)--定時器0的基礎實驗

推薦閱讀

集微網消息(文/鄧文標) 在上游晶圓緊缺和下游需求強烈等因素的傳導下,今年下半年以來CMOS傳感器(CIS)普遍開始漲價,其中三星率先發布CIS漲價通知,格科微、比亞迪跟隨,豪威科技(OmniVision,簡稱OV)和思比科也已經開始漲價。CIS已經成為繼MLCC、MOSFET等元器件漲價趨平后,半導體元器件又一大漲價市場,且未來一段時間內很難緩解。CIS是手機攝像...
后續訂單證明了Manz儲能技術具備高可靠性訂單總額約2,000萬歐元 消費性電子產品領域的持續成長態勢持續看漲 活躍于全球各地的高科技設備制造商 Manz 集團正與全球領先的知名電池制造商之一進一步地擴大合作關系,訂單約兩千萬歐元。因此,累計2019年用于消費電子產品的卷繞式鋰電池芯生產設備的訂單總額約為4,000萬歐元。 后續訂單是Manz在消費電子領域...
隨著技術發展以及新零售、無人零售等概念陸續落地,零售行業開始加快擁抱科技,推廣應用機器人、等智能產品和人工智能、等技術。例如,很多大型零售超市已經使用機器人來幫助理貨,或者是用無人機來配送貨物。然而,在推進科技應用的過程中,也會出現一些“倒退”的行為。 近日,作為全球知名零售巨頭的沃爾瑪發布消息,宣稱將放棄使用流動機器人掃描貨...
1、#typede使用typedef unsigned char u8;typedef unsigned int ul6;重新定義常用的關鍵詞,可以增強程序的可移植性,因為在不同的編譯軟件上,C語言的數據類型關鍵詞的位寬不一樣2、while循環函數while(i<10){i=i+1;}3.延時函數實質:占用CPU的執行過程,使之達到延時的目的void delay(ul6 i) // 大約延時10us{while(i--)}報錯一錯誤代碼原因ma...

史海拾趣

問答坊 | AI 解惑

單片機初學者的問題00-59計數匯編程序?

各位好,我是個單片機初學者,想向大家求教一下關于單片機00-59秒計數匯編程序 要求是P0作段選,P2作位選(不用譯碼器) 謝謝大家了,我的郵箱是gxlizhongren@sina.com…

查看全部問答∨

電力行業的發展與商機(電氣安裝公司尋求合作)

在網站上逛了好幾天,感嘆大家智慧的同時,我發現論壇上對電力市場的關注卻很少。電力市場是個大的概念,所涉及的面太廣,電力體制改革的深化,到底能給我們普通人帶來什么樣的商機?本人通過對電力產業鏈中配電電氣設備安裝這個環節進行分析,把這幾年的 ...…

查看全部問答∨

為什么ccs調試時單步運功會調到匯編程序?

為什么ccs調試時單步運功會調到匯編程序?源代碼都是用c寫的,編譯通過并裝載后開始運行,為什么有的程序只能在匯編中單步運行,卻不能在c中單步運行,連那個單步運行的按鈕都是灰色的…

查看全部問答∨

關于交流電量的測量的問題

各位好,我現在剛接觸電力測量方面的東西,很多都要一點點學習,還需要各位大俠多指點,呵呵~     現在我做的是使用微型互感器測量電壓和電流,互感器二次側的電流是交流量,通過取樣電阻來將電流轉換為電壓送至ADC。但是我使用的單片 ...…

查看全部問答∨

徹底擺脫nxp p89lpc936單片機isp煩惱

用過nxp lpc900系列單片機的同志都知道,其出廠自帶的isp程序極其難用,一旦燒寫失敗,即使神仙下凡,想再進isp幾乎都不大可能。按其所說的三種方法,不論是三個脈沖還是幀間隔的方法都無濟于事。我已經被它折磨了不止一次了,于是打算要找到一個方 ...…

查看全部問答∨

基于凌陽單片機的語音控制小車

文摘  本文主要介紹了凌陽單片機SPCE061A的性能、硬件結構及其各個部分的功能和它的應用領域。針對凌陽公司的語音小車,進行了改進,自行設計了控制電路,詳細介紹了小車外圍電路各部分的功能。我們根據自己錄制的語音命令通過程序來遠程 ...…

查看全部問答∨

ADC 前端電路的五個設計步驟

經典學習資料,可以鞏固基礎…

查看全部問答∨

ListCtrl如何禁用滾動條并且支持滾動,或者隱藏滾動條不讓重繪后出現滾動條

禁用滾動條我知道是LVS_NOSCROLL 我禁用了后就沒有滾動的功能了。。 我現在要做的是不顯示滾動條,并且要有滾動的功能。。望高手能幫忙。。 只有20分了。有高手回答的好我再追加分…

查看全部問答∨

485通訊最多能有多少站?

最近碰上一個叫“倍捻機”的紡機,總共有96或154錠,每一錠都需要計算產量在人機上顯示,請問這樣的話通過485通訊怎樣進行處理?我看過直捻機上是通過傳感器給一個電子板信號,然后電子板通過485傳給PLC的一個通訊模塊,最后傳給PLC進行處理。請問 ...…

查看全部問答∨

頻率測量

本帖最后由 paulhyde 于 2014-9-15 08:54 編輯 請教高手指點下面的代碼:用定時器A測頻率的代碼,紅色標注的是什么意思啊,求解?。?! void main(){  uchar temp=0;  WDTCTL=WDTPW+WDTHOLD;  int_clk();    & ...…

查看全部問答∨
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 游戏| 剑川县| 南澳县| 静宁县| 哈巴河县| 苗栗市| 滁州市| 绵竹市| 屯留县| 剑阁县| 资中县| 海口市| 涟水县| 修水县| 满洲里市| 北安市| 乌兰浩特市| 来宾市| 大渡口区| 武威市| 平昌县| 全州县| 石狮市| 乐安县| 阳谷县| 铁力市| 棋牌| 弥渡县| 诏安县| 关岭| 招远市| 乌拉特中旗| 府谷县| 南漳县| 永宁县| 无棣县| 麟游县| 汝州市| 方正县| 高邑县| 建德市|