標籤:
前兩天從晚上買了個enc28j60模組,準備做個乙太網路的測試,回來的時候稍微有點小激動,為什麼呢,據我的經驗看來,一個人面對新的未知的事物,總會有點害怕,然後又有種躍躍欲試之感,或許我就是這樣的,然後我把小小的模組拿出來,用杜邦線連結好之後找了段代碼少了進去,那時候不知道咋連,他們說如果和路由器串連的話用直連網線,和pc機串連的話用交叉網線,什麼呀,現在的pc機都可以判斷裝置的連接埠類型了額,自動轉換直連和交叉,不需要費那麼多功夫了。
話說一開始怎麼都串連不上,ping不通,什麼玩意兒啊,弄半天了沒反應,一度陷入懷疑,懷疑這個模組是不是壞的,然後人家又說什麼亂七八糟的原因,什麼杜邦線導致時鐘頻率紊亂啊什麼的,都是什麼呀。後來我查了資料,原來需要設定pc機的ip子網路遮罩等資訊,我就設定了下,然後斷開無線網,Ping了下,臥槽,竟然通了,你能理解我當時的心情嗎,當時腦海只閃現過三個字:我艸啦。。。
話不多說,雖然只是ping通,離項目完成還差的遠,但是至少說明模組是好的吧,然後就開始看協議,tcp/ip,udp,lwip,uip,arp,。。。。。。無奈了,這都是啥玩意啊,我只用到udp啊,然後我把該刪的全刪了,然後看了udp的報文怎麼組成的,然後。。。。。。。。。。。。。。。。。。。。。。。。
然後就可以發送資料了啊,也可以接受了啊,可是為毛線板子可以無限次接受,但是只能發送一次呢,當時有兩個函數
void make_udp_reply_from_request(unsigned char *buf, char *data, unsigned int datalen, unsigned int port)
enc28j60PacketReceive(BUFFER_SIZE, buf);
第一個是發送報文的,第二個是接收報文的,我一直在解決為啥發送不出去的問題,然後想了想,不可能一個請求一個回複這種單工模式的,肯定可以無限發送的,因為我想到了我寫的一個socket程式,以前上大一寫的,對於伺服器端,需要設定通訊端啊,綁定連接埠啊,監聽啊什麼的,然後發送什麼的,對於用戶端,不需要綁定通訊端,知道伺服器的ip連接埠直接可以發送資料啊,我這麼一想,對,有理,於是就根據udp協議開始組報文,什麼20位元組ip前序,8位元組udp前序,什麼什麼的,還需要知道伺服器的ip,mac,連接埠資訊,然後就可以無限發送了,到此這個模組udp功能算是搞懂了,把發送的代碼貼上,讓大家看下,
// you can send a max of 220 bytes of data//srcport 我的連接埠,dstport 對方連接埠void make_udp_send(unsigned int srcport, unsigned int dstport, unsigned char* data, unsigned char datalen){ unsigned char i = 0; unsigned int ck; //make_eth(buf); // if((stateSend==0)||(stateStop==0))return; //if(stateSend==0)return; while (i < 6) { sendbuf[ETH_DST_MAC + i] = dstmac[i]; sendbuf[ETH_SRC_MAC + i] = mymac[i]; i++; } i=0; if (datalen > 220) { datalen = 220; } // total length field in the IP header must be set: sendbuf[IP_TOTLEN_H_P] = 0; sendbuf[IP_TOTLEN_L_P] = IP_HEADER_LEN + UDP_HEADER_LEN + datalen; //make_dstip(buf); sendbuf[12] = 0x08; sendbuf[13] = 0x00; sendbuf[14] = 0x45; sendbuf[15] = 0x00; sendbuf[20] = 0x00; sendbuf[21] = 0x00; sendbuf[22] = 0x40; sendbuf[23] = 0x11; i = 0; while (i < 4) { sendbuf[IP_DST_P + i] = dstip[i]; sendbuf[IP_SRC_P + i] = myip[i]; i++; } i = 0; fill_ip_hdr_checksum(sendbuf); sendbuf[UDP_SRC_PORT_H_P] = srcport >> 8; sendbuf[UDP_SRC_PORT_L_P] = srcport & 0xff; sendbuf[UDP_DST_PORT_H_P] = dstport >> 8; sendbuf[UDP_DST_PORT_L_P] = dstport & 0xff; // source port does not matter and is what the sender used. // calculte the udp length: sendbuf[UDP_LEN_H_P] = 0; sendbuf[UDP_LEN_L_P] = UDP_HEADER_LEN + datalen; // zero the checksum sendbuf[UDP_CHECKSUM_H_P] = 0; sendbuf[UDP_CHECKSUM_L_P] = 0; // copy the data: while (i < datalen) { sendbuf[UDP_DATA_P + i] = data[i]; i++; } ck = checksum(&sendbuf[IP_SRC_P], 16 + datalen, 1); sendbuf[UDP_CHECKSUM_H_P] = ck >> 8; sendbuf[UDP_CHECKSUM_L_P] = ck & 0xff; enc28j60PacketSend(UDP_HEADER_LEN + IP_HEADER_LEN + ETH_HEADER_LEN + datalen, sendbuf);}
知識是需要共用的,希望中國人不要藏私,這樣中國才能發展起來,國家才能富強!
關於ENC28J60在stm32上的應用的分析