標(biāo)題:
UDP數(shù)據(jù)發(fā)送程序,緩沖區(qū)可以擴(kuò)展,不過(guò)得有足夠的SRAM
[打印本頁(yè)]
作者:
xuwei
時(shí)間:
2015-6-13 16:54
標(biāo)題:
UDP數(shù)據(jù)發(fā)送程序,緩沖區(qū)可以擴(kuò)展,不過(guò)得有足夠的SRAM
三個(gè)功能:
1.UDP標(biāo)準(zhǔn)配置
2.IP校驗(yàn)
3.向以太網(wǎng)中送UDP包!
/**本函數(shù)是一個(gè)類初始化函數(shù)
主要是一些不變的參數(shù)和部分?jǐn)?shù)據(jù)的初始化
**/
void UDP_Frame_Set(
TypeDef_MAC_Frame_H *MAC_Frame,
TypeDef_IP_Frame_H *IP_Frame,
TypeDef_UDP_Frame_H *UDP_Frame
)//設(shè)置UDP相關(guān)參數(shù)
{
/**
整個(gè)UDP幀是由
MAC幀+IP幀+UDP幀構(gòu)成的�。。。�!
編譯器要開(kāi)在大端模式!主要考慮用的外部RAM
*/
/*****MAC部首設(shè)置***************************************************/
/********目標(biāo)MAC地址***************/
MAC_Frame->Destination_MAC[0]=0;
MAC_Frame->Destination_MAC[1]=0;
MAC_Frame->Destination_MAC[2]=0;
MAC_Frame->Destination_MAC[3]=0;
MAC_Frame->Destination_MAC[4]=0;
MAC_Frame->Destination_MAC[5]=0;
/********源MAC地址*************/
MAC_Frame->Source_add_MAC[0]=0x00;
MAC_Frame->Source_add_MAC[1]=0x26;
MAC_Frame->Source_add_MAC[2]=0x9E;
MAC_Frame->Source_add_MAC[3]=0xC7;
MAC_Frame->Source_add_MAC[4]=0x6C; //本機(jī)MAC固定的
MAC_Frame->Source_add_MAC[5]=0xF3;
/********類型長(zhǎng)度******8*****/
MAC_Frame->Type[0]=0x08;
MAC_Frame->Type[1]=0x00;//0X0800IP包 0x0806ARP
/**************IP部首設(shè)置**************************************************/
IP_Frame ->IP_Version_Head=0x45;//IP版本是4,部首長(zhǎng)度是20個(gè)字節(jié)
IP_Frame ->IP_Tos=0;//IP的TOS一般設(shè)為0
IP_Frame ->IP_Total_Length[0]=0;//設(shè)置總長(zhǎng)度
IP_Frame ->IP_Total_Length[1]=0;//設(shè)置總長(zhǎng)度
IP_Frame ->IP_Indentification[0]=0;
IP_Frame ->IP_Indentification[1]=1; //標(biāo)識(shí)字段,發(fā)送一個(gè)都會(huì)加一
IP_Frame ->IP_Flage_FRAGMENT_OFFSET[0]=0; //3位標(biāo)識(shí)和片偏移,這里是指IP分片,盡量不產(chǎn)生IP分片
IP_Frame ->IP_Flage_FRAGMENT_OFFSET[1]=0;
IP_Frame ->IP_TTL=64;//生存時(shí)間默認(rèn)為32或者64,過(guò)一個(gè)路由器減去一!當(dāng)此值為0此份報(bào)文被丟棄
IP_Frame ->IP_Protocol=0x11;//表示協(xié)議,這是UDP協(xié)議
/*IP部首校驗(yàn)和*/
IP_Frame ->IP_Check_sum[0]=0;
IP_Frame ->IP_Check_sum[1]=0; //0;
/*本機(jī)IP*/
IP_Frame ->IP_Source[0]=192;
IP_Frame ->IP_Source[1]=168;
IP_Frame ->IP_Source[2]=1;
IP_Frame ->IP_Source[3]=233;
/*目標(biāo)IP地址這個(gè)得由ARP獲得這里做初始化設(shè)置*/
IP_Frame ->IP_Dstination[0]=0;
IP_Frame ->IP_Dstination[1]=0;
IP_Frame ->IP_Dstination[2]=0;
IP_Frame ->IP_Dstination[3]=0;
/***************UDP設(shè)置***************************************/
UDP_Frame->UDP_Source_Port[0]=0x1f;
UDP_Frame->UDP_Source_Port[1]=0x90;//源端口是8080
UDP_Frame->UDP_Dstination_Port[0]=0x1f;
UDP_Frame->UDP_Dstination_Port[1]=0x90;//目標(biāo)端口是8080
/*這個(gè)長(zhǎng)度也得有實(shí)際數(shù)據(jù)決定
他的長(zhǎng)度是UDP長(zhǎng)度+數(shù)據(jù)比如數(shù)據(jù)長(zhǎng)度是1個(gè)字節(jié), 那么
這個(gè)長(zhǎng)度就是UDP部首+1=8個(gè)字節(jié)+1個(gè)字節(jié)=9
*/
// UDP_Frame->UDP_Length[0]=0;
// UDP_Frame->UDP_Length[1]=0;
/*
校驗(yàn)和也是得有數(shù)據(jù)才可以算出來(lái),這里只是 初次賦值��!
*/
UDP_Frame->UDP_check_sum[0]=0;
UDP_Frame->UDP_check_sum[1]=0;
//UDP_Frame->UDP_Data[0];//數(shù)據(jù)
}
/***************************************
IP部首的校驗(yàn)和!他把IP部首看做是一連串的16位
數(shù)據(jù),然后把這些數(shù)據(jù)加起來(lái)然后取反,所謂的二進(jìn)制
反碼求和,并不是字面上的先去凡在求和,其實(shí)是相加后再取反!!坑爹啊
他的作用是:
1.在發(fā)送端他首先把校驗(yàn)字段清0,其后進(jìn)行二進(jìn)制反碼求和,
結(jié)果送到校驗(yàn)子段,
2。在發(fā)送端他接收到后直接的把所有數(shù)據(jù)進(jìn)行反碼求和,然后再讀取這個(gè)值,如果是0,那么是對(duì)的,如果不是
那么證明這個(gè)IP數(shù)據(jù)幀是有問(wèn)題的應(yīng)該丟棄或者發(fā)送差錯(cuò)報(bào)文!
2012年3月3日
日照高科園
王均偉
************************************/
uint IP_Check_Sum_Verify(TypeDef_IP_Frame_H *IP_Frame_Sum)
{
/*
一下算法源于百度,感謝再感謝��!
計(jì)算對(duì)IP首部檢驗(yàn)和的算法如下:
(1)把IP數(shù)據(jù)包的校驗(yàn)和字段置為0;
�。�2)把首部看成以16位為單位的數(shù)字組成,依次進(jìn)行二進(jìn)制求和
(注意:求和時(shí)應(yīng)將最高位的進(jìn)位保存,所以加法應(yīng)采用32位加法);
(3)將上述加法過(guò)程中產(chǎn)生的進(jìn)位(最高位的進(jìn)位)加到低16位
(采用32位加法時(shí),即為將高16位與低16位相加,之后還要把該次加
法最高位產(chǎn)生的進(jìn)位加到低16位)
�。�4)將上述的和取反,即得到校驗(yàn)和。
2012年3月3日于日照高科園
按照以上算法便可以!
*/
xdata unsigned long a,b;
xdata uchar i;
xdata uint tab[10];
xdata uint msb,lsb;
msb=IP_Frame_Sum->IP_Version_Head; //IP的版本號(hào)和IP的部首長(zhǎng)度,默認(rèn)為0X45,版本是4,部首是20字節(jié)
msb=msb<<8;
lsb=IP_Frame_Sum->IP_Tos; //ip的TOS據(jù)我抓包觀察一般是00
tab[0]=msb+lsb;
msb=IP_Frame_Sum->IP_Total_Length[0];//總數(shù)據(jù)報(bào)文長(zhǎng)度
msb=msb<<8;
lsb=IP_Frame_Sum->IP_Total_Length[1];//總數(shù)據(jù)報(bào)文長(zhǎng)度
tab[1]=msb+lsb;
msb=IP_Frame_Sum->IP_Indentification[0];//IP標(biāo)識(shí)字段,標(biāo)識(shí)字段唯一地標(biāo)識(shí)主機(jī)發(fā)送的每一份數(shù)據(jù)報(bào)。通常每發(fā)送一份報(bào)文它的值就會(huì)加1
msb=msb<<8;
lsb=IP_Frame_Sum->IP_Indentification[1];
tab[2]=msb+lsb;
msb=IP_Frame_Sum->IP_Flage_FRAGMENT_OFFSET[0];//標(biāo)志位和片偏移
msb=msb<<8;
lsb=IP_Frame_Sum->IP_Flage_FRAGMENT_OFFSET[1];//標(biāo)志位和片偏移
tab[3]=msb+lsb;
msb=IP_Frame_Sum->IP_TTL; //生存時(shí)間
msb=msb<<8;
lsb=IP_Frame_Sum->IP_Protocol; //協(xié)議類型
tab[4]=msb+lsb;
msb=IP_Frame_Sum->IP_Check_sum[0];//部首校驗(yàn)和
msb=msb<<8;
lsb=IP_Frame_Sum->IP_Check_sum[0];//部首校驗(yàn)和
tab[5]=msb+lsb;
msb=IP_Frame_Sum->IP_Source[0];//32IP位源地址
msb=msb<<8;
lsb=IP_Frame_Sum->IP_Source[1];//32IP位源地址
tab[6]=msb+lsb;
msb=IP_Frame_Sum->IP_Source[2];//32IP位源地址
msb=msb<<8;
lsb=IP_Frame_Sum->IP_Source[3];//32IP位源地址
tab[7]=msb+lsb;
msb=IP_Frame_Sum->IP_Dstination[0];//32位IP目標(biāo)地址
msb=msb<<8;
lsb=IP_Frame_Sum->IP_Dstination[1];//32位IP目標(biāo)地址
tab[8]=msb+lsb;
msb=IP_Frame_Sum->IP_Dstination[2];//32位IP目標(biāo)地址
msb=msb<<8;
lsb=IP_Frame_Sum->IP_Dstination[3];//32位IP目標(biāo)地址
tab[9]=msb+lsb;
/**我操原來(lái)是沒(méi)有清空變量草,費(fèi)了我一天時(shí)間,我說(shuō)第一次運(yùn)行正確,其后不對(duì)
沒(méi)有清零!我擦我操!
2012年3月7日
日照高科園
王均偉*/
a=0; //清零
b=0;
for(i=0;i<10;i++)
{
a=a+tab[i]; //變量加
b=a;//暫存A中
b+=(a>>16)&0x0000ffff; //取高位與地位相加,并且加完了清0高八位
}
b=~b; //取反
return b;
}
/*******************************8
發(fā)送UDP數(shù)據(jù)包
指定目標(biāo)IP,本地IP,本地端口,目標(biāo)端口
還有數(shù)據(jù)大小,什么數(shù)據(jù),第幾個(gè)包
uchar *MAC_Target_add,//MAC地址。一般情況下由ARP計(jì)算得出
uchar *IP_Source_add,//IP源地址
uchar *IP_Target_add,//IP目標(biāo)地址
uint UDP_Source_Port,UDP源端口
uint UDP_Target_Port,UDP目標(biāo)端口
uchar * UDP_Send_Data, UDP數(shù)據(jù)
uchar UDP_Send_Data_length UDP數(shù)據(jù)長(zhǎng)度
**********************************/
void Send_UDP_packet( uchar *MAC_Target_add,
uchar *IP_Target_add,
uchar *UDP_Source_Port,
uchar *UDP_Target_Port,
uchar *UDP_Send_Data,
uchar UDP_Send_Data_length
)
{
TypeDef_MAC_Frame_H xdata MAC_Frame_H;//MAC定義一個(gè)結(jié)構(gòu)體頭
TypeDef_IP_Frame_H xdata IP_Frame_H; //IP定義一個(gè)結(jié)構(gòu)體頭
TypeDef_UDP_Frame_H xdata UDP_Frame_H;//UDP定義數(shù)據(jù)結(jié)構(gòu)
xdata uchar d;
xdata uchar MSB,LSB; //中間量
xdata uint da; //
/*傳遞了一個(gè)結(jié)構(gòu)指針進(jìn)去指向了上面建立的變量
就是建立了一個(gè)映射,把所有的都映射了,
目的是要初始化
表示這里面的都是標(biāo)準(zhǔn)配置,一般不改變
要隨時(shí)改變的就在這個(gè)函數(shù)下面設(shè)置了
比如MAC_Frame_H.Destination_MAC
他是個(gè)傳遞參量!
*/
UDP_Frame_Set(&MAC_Frame_H,&IP_Frame_H,&UDP_Frame_H);//設(shè)置UDP相關(guān)參數(shù)
/*MAC目標(biāo)地址*/
MAC_Frame_H.Destination_MAC[0]=MAC_Target_add[0];
MAC_Frame_H.Destination_MAC[1]=MAC_Target_add[1];
MAC_Frame_H.Destination_MAC[2]=MAC_Target_add[2];
MAC_Frame_H.Destination_MAC[3]=MAC_Target_add[3];
MAC_Frame_H.Destination_MAC[4]=MAC_Target_add[4];
MAC_Frame_H.Destination_MAC[5]=MAC_Target_add[5];
/*IP目標(biāo)地址*/
IP_Frame_H.IP_Dstination[0]=IP_Target_add[0];
IP_Frame_H.IP_Dstination[1]=IP_Target_add[1];
IP_Frame_H.IP_Dstination[2]=IP_Target_add[2];
IP_Frame_H.IP_Dstination[3]=IP_Target_add[3];
//數(shù)據(jù)長(zhǎng)度,
/*這個(gè)長(zhǎng)度等于IP部首20字節(jié)+UDP部首8字節(jié)+UDP數(shù)據(jù),這里是1字節(jié)UDP_Send_Data_length表示這是數(shù)據(jù)長(zhǎng)度*/
da=28+UDP_Send_Data_length;
LSB=da;
MSB=(da>>8)&0x00ff;
IP_Frame_H.IP_Total_Length[0]=MSB;//設(shè)置總長(zhǎng)度
IP_Frame_H.IP_Total_Length[1]=LSB;//設(shè)置總長(zhǎng)度 //29字節(jié)
/*加入IP校驗(yàn)和*/
da=IP_Check_Sum_Verify(&IP_Frame_H); //計(jì)算IP部首校驗(yàn)和
LSB=da;
MSB=(da>>8)&0x00ff;
IP_Frame_H.IP_Check_sum[0]=MSB;
IP_Frame_H.IP_Check_sum[1]=LSB; //寫入IP部首校驗(yàn)和
/*****************UDP***********************/
UDP_Frame_H.UDP_Source_Port[0]=UDP_Source_Port[0];
UDP_Frame_H.UDP_Source_Port[1]=UDP_Source_Port[1];//源端口是8080
UDP_Frame_H.UDP_Dstination_Port[0]=UDP_Target_Port[0];
UDP_Frame_H.UDP_Dstination_Port[1]=UDP_Target_Port[1];//目標(biāo)端口是8080
/*這個(gè)長(zhǎng)度也得有實(shí)際數(shù)據(jù)決定
他的長(zhǎng)度是UDP長(zhǎng)度+數(shù)據(jù)比如數(shù)據(jù)長(zhǎng)度是1個(gè)字節(jié), 那么
這個(gè)長(zhǎng)度就是UDP部首+1=8個(gè)字節(jié)+1個(gè)字節(jié)=9
*/
da=8+UDP_Send_Data_length; //計(jì)算UDP數(shù)據(jù)長(zhǎng)度
LSB=da;
MSB=(da>>8)&0x00ff;
UDP_Frame_H.UDP_Length[0]=MSB;
UDP_Frame_H.UDP_Length[1]=LSB;
/*加載數(shù)據(jù)*/
//注意這里的UDP數(shù)據(jù)我只分配了10個(gè)字節(jié),要想加大數(shù)據(jù)量就得改結(jié)構(gòu)體!
for(d=0;d<UDP_Send_Data_length;d++)
{
UDP_Frame_H.UDP_Data[d]=UDP_Send_Data[d];//數(shù)據(jù)寫入
}
//以上實(shí)際上就是設(shè)置了三個(gè)結(jié)構(gòu)體,全部圍繞這三個(gè)結(jié)構(gòu)體展開(kāi)的
/* 物理操作 */
set_send_buffer_add(0x0200,0x023f);//緩沖區(qū)的大小設(shè)定,開(kāi)始200結(jié)束1fff
write_buffer_add(0x0200,0x0e);//控制字節(jié)
// MAC
write_buffer_add(0x0201,MAC_Frame_H.Destination_MAC[0]);//
write_buffer_add(0x0202,MAC_Frame_H.Destination_MAC[1]);//
write_buffer_add(0x0203,MAC_Frame_H.Destination_MAC[2]);//
write_buffer_add(0x0204,MAC_Frame_H.Destination_MAC[3]);//
write_buffer_add(0x0205,MAC_Frame_H.Destination_MAC[4]);// MAC目的地址
write_buffer_add(0x0206,MAC_Frame_H.Destination_MAC[5]);//
write_buffer_add(0x0207, MAC_Frame_H.Source_add_MAC[0]);//
write_buffer_add(0x0208, MAC_Frame_H.Source_add_MAC[1]);//
write_buffer_add(0x0209, MAC_Frame_H.Source_add_MAC[2]);// MAC源地址
write_buffer_add(0x020A, MAC_Frame_H.Source_add_MAC[3]);//
write_buffer_add(0x020B, MAC_Frame_H.Source_add_MAC[4]);//
write_buffer_add(0x020C, MAC_Frame_H.Source_add_MAC[5]);//
write_buffer_add(0x020D, MAC_Frame_H.Type[0]);// MAC類型
write_buffer_add(0x020E, MAC_Frame_H.Type[1]);//
//IP
write_buffer_add(0x020F,IP_Frame_H.IP_Version_Head);//
write_buffer_add(0x0210,IP_Frame_H.IP_Tos);//
write_buffer_add(0x0211,IP_Frame_H.IP_Total_Length[0]);
write_buffer_add(0x0212,IP_Frame_H.IP_Total_Length[1]);
write_buffer_add(0x0213,IP_Frame_H.IP_Indentification[0]);
write_buffer_add(0x0214,IP_Frame_H.IP_Indentification[1]);
write_buffer_add(0x0215,IP_Frame_H.IP_Flage_FRAGMENT_OFFSET[0]);
write_buffer_add(0x0216,IP_Frame_H.IP_Flage_FRAGMENT_OFFSET[1]);
write_buffer_add(0x0217,IP_Frame_H.IP_TTL);
write_buffer_add(0x0218,IP_Frame_H.IP_Protocol);
write_buffer_add(0x0219,IP_Frame_H.IP_Check_sum[0]);
write_buffer_add(0x021A,IP_Frame_H.IP_Check_sum[1]);
write_buffer_add(0x021B,IP_Frame_H.IP_Source[0]);
write_buffer_add(0x021C,IP_Frame_H.IP_Source[1]);
write_buffer_add(0x021D,IP_Frame_H.IP_Source[2]);
write_buffer_add(0x021E,IP_Frame_H.IP_Source[3]);
write_buffer_add(0x021F,IP_Frame_H.IP_Dstination[0]);
write_buffer_add(0x0220,IP_Frame_H.IP_Dstination[1]);
write_buffer_add(0x0221,IP_Frame_H.IP_Dstination[2]);
write_buffer_add(0x0222,IP_Frame_H.IP_Dstination[3]);
//UDP
write_buffer_add(0x0223,UDP_Frame_H.UDP_Source_Port[0]);
write_buffer_add(0x0224,UDP_Frame_H.UDP_Source_Port[1]);
write_buffer_add(0x0225,UDP_Frame_H.UDP_Dstination_Port[0]);
write_buffer_add(0x0226,UDP_Frame_H.UDP_Dstination_Port[1]);
write_buffer_add(0x0227,UDP_Frame_H.UDP_Length[0]);
write_buffer_add(0x0228,UDP_Frame_H.UDP_Length[1]);
write_buffer_add(0x0229,UDP_Frame_H.UDP_check_sum[0]);
write_buffer_add(0x022A,UDP_Frame_H.UDP_check_sum[1]);
//數(shù)據(jù) //發(fā)送數(shù)量UDP_Send_Data_length
//數(shù)據(jù)在 UDP_Frame_H.UDP_Data[]里;
for(d=0;d<UDP_Send_Data_length;d++)
{
write_buffer_add((0x022B+d),UDP_Frame_H.UDP_Data[d]);
}
write_ENC28J60_REG_SPI(ECON1,0x0c);//允許發(fā)送,允許接收
for(;;)
{
d=read_ENC28J60_REG_SPI(EIR);//讀取數(shù)據(jù)包接收標(biāo)志位
if((d&0x08)==0x08)break; //發(fā)送完畢??OK退出ifNO死在里面
}
}
復(fù)制代碼
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1