www.pudn.com > 8019udp.zip > net.c


//******************************************** 
//              网络通信子程序 
//                2007.4.13 
//                 Passion  
//******************************************** 
#include "reg51.h" 
#include  
#include  
#include  
#include  
 
sbit P3_4 = P3^4; 
//************************************************************************* 
#define H_H_Length   pac_head[16] 
#define L_H_Length   pac_head[17] 
#define H_CRC        Send_Buff[24] 
#define L_CRC        Send_Buff[25]  
#define H_Loc_Port   pac_head[34] 
#define L_Loc_Port   pac_head[35] 
#define H_Aim_Port   pac_head[36] 
#define L_Aim_Port   pac_head[37] 
#define H_UDP_Length pac_head[38] 
#define L_UDP_Length pac_head[39] 
#define HUDPCRC      Send_Buff[40] 
#define LUDPCRC      Send_Buff[41] 
#define reg00   XBYTE[0x8000]   //reg00- 10为isa网卡接口的寄存器地址300-310; 
#define reg01   XBYTE[0x8001] 
#define reg02   XBYTE[0x8002] 
#define reg03   XBYTE[0x8003] 
#define reg04   XBYTE[0x8004] 
#define reg05   XBYTE[0x8005] 
#define reg06   XBYTE[0x8006] 
#define reg07   XBYTE[0x8007] 
#define reg08   XBYTE[0x8008] 
#define reg09   XBYTE[0x8009] 
#define reg0a   XBYTE[0x800a] 
#define reg0b   XBYTE[0x800b] 
#define reg0c   XBYTE[0x800c] 
#define reg0d   XBYTE[0x800d] 
#define reg0e   XBYTE[0x800e] 
#define reg0f   XBYTE[0x800f] 
#define reg10   XBYTE[0x8010] 
#define reg1f   XBYTE[0x801f] 
#define Reset_Low 	P3_4 = 0;//P5 &= ~(0x4); 	// P52  
#define Reset_High 	P3_4 = 1;//P5 |= 0x4; 		// P52 
//********************************************************************** 
 
//extern void InitUART(); 
 
void UDP_Send(void);                                     //UDP协议发送处理 
void UDP_Recv(void); 
void page_select(unsigned char pagenumber);              //RTL8019页选择函数 
void read_mac_add(void);                                 //RTL8019网卡MAC读取函数 
void Reset_8019(void);                                   //RTL8019复位函数 
void RTL8019_init(void);                                 //RTL8019初始化函数 
bit RTL8019_receive(void);                              //RTL8019接收函数 
void PORT_Init (void);                                   //C8051F020端口初始化 
void write_mac_add(void);                                //写网卡物理地址 
void SYSCLK_Init (void);                                 //外部时钟初始化 
void RTL8019_send(void);                                 //RTL8019发送函数 
void ARP_Request();                                      //ARP请求处理 
//void ARP_Answer(void);                                    
void RARP(void);                                         //ARP应答处理                                         
bit ARP_Process(void);                                   //ARP请求包处理 
bit IP_Process(void);                                    //IP包处理 
bit UDP_Process(void);                                   //UDP包处理 
bit WRQ_Process(void);                                   //WRQ包处理 
bit DATA_Process(void);                                  //DATA包处理 
bit OVER_Process(void);                                  //OVER包处理 
void ACK_Send(unsigned int count);                       //ACK包发送 
void Pag_TimeOut(void);                                  //数据包接收超时 
void Config_Timmer(void);                                //定时器配置函数                                        
unsigned int CRC_Process(unsigned char LEN,unsigned char mov,unsigned char type);        //校验位生成函数 
//*********************************************************************** 
unsigned int kk; 
unsigned int Protocol; 
unsigned int Pag_Head;                                            //包头寄存器 
unsigned int Loc_Port;                                            //源端口 
unsigned int Aim_Port;                                            //目的端口 
unsigned int Package=0;                                           //块寄存器 
unsigned int Count_Pag=1;                                         //块计数器 
unsigned int H_Package=0;                                         //总数据块数 
unsigned int ms=0;                                                //毫秒计时 
unsigned char s=0;                                                //秒计时 
unsigned char min=0;                                              //分计时 
unsigned char xdata Send_Buff[558]={0x00};                     //发送缓存 
unsigned char xdata Receive_Buff[68]={0x00};                            //接收缓存 
unsigned char bnry; 
unsigned char curr; 
unsigned char xdata A_m_a[6]={0x00};                                //目的物理地址 
unsigned char xdata A_IP_add[4]={0x00};                                 //目的IP地址 
unsigned char xdata hard_add[6]={0x00,0x01,0x02,0x03,0x04,0x05};         //网卡物理地址 
//unsigned char IP_add[4]={0x0a,0x05,0x84,0xd9};                    //网卡IP地址 
unsigned char xdata IP_add[4]={13,2,168,192};                    //网卡IP地址 
unsigned char xdata UDP_F_Head[12]={0x00};                              //UDP伪头 
unsigned char xdata DATA_Buff[512]={0x00};                        //接收数据缓存 
unsigned char xdata pac_head[42]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05, 
                                  0x08,0x00,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x11, 
                                  0x00,0x00,0x0a,0x05,0x84,0xd9,0x00,0x00,0x00,0x00,0x00,0x00, 
								  0x00,0x00,0x00,0x00,0x00,0x00}; //UDP数据包 
 
 
//*********************************************************************** 
void main(void) 
{ 
    unsigned char i; 
	InitUART(); 
 
//	WDTCN = 0xDE;              // Disable watchdog timer 
//	WDTCN = 0xAD; 
//    EMI0CF =0x24; 
 
	Prints("asdfasldfhalsdjfalsdfhas\r\n"); 
 
	SYSCLK_Init (); 
 
	PORT_Init();  
 
    RTL8019_init(); 
 
    for(i=0;i<6;i++) 
      hard_add[i]=i; 
 
	while(1) 
	{ 
        //P2=0x00; 
		//if(ms>5) 
			//Pag_TimeOut(); 
		//if(s>1) 
            //Request_TimeOut(); 
		//if(min>=1) 
			//OFF_TimeOut(); 
    	RTL8019_receive();                          //接收一个数据包 
 
		for(i=0;i<68;i++) 
			PrintHex(Receive_Buff[i]); 
 
		Prints("\r\n\r\n\r\n"); 
 
		Protocol=Receive_Buff[16]; 
		 
		//Prints("Protocol: "); 
		//PrintHex(Protocol); 
		//Prints("\r\n"); 
 
	    Protocol=Protocol<<8; 
		Protocol+=Receive_Buff[17];                  //取出协议类型 
		if(Protocol!=0x0806&&Protocol!=0x0800) 
		{ 
			//PrintLongIntHex(Protocol); 
			//Prints(" continue\r\n"); 
			continue;                                  //既不是ARP包也不是IP包则丢弃 
		} 
	    else if(Protocol==0x0806)                   //若为ARP包 
		{ 
			Prints("ARP_Process();Protocol==0x0806\r\n"); 
			ARP_Process();                          //ARP包处理函数 
		} 
		else  
		{ 
			Prints("IP_Process();\r\n"); 
			IP_Process();                           //IP报处理函数 
		} 
	} 
} 
//********************************************************************* 
bit ARP_Process(void) 
{ 
	unsigned char i; 
	                     
		for(i=42;i<46;i++) 
		{ 
			if(Receive_Buff[i]!=IP_add[i-42])       //是否与本地IP地址相符               
				return 0; 
		} 
		for(i=0;i<6;i++) 
			A_m_a[i]=Receive_Buff[i+10];        //取出客户机物理地址 
		for(i=0;i<4;i++) 
            A_IP_add[i]=Receive_Buff[i+32];         //取出客户机IP地址 
		if(Receive_Buff[25]==0x01)                  //是否为ARP请求 
			RARP();                                 //应答 
		return 1; 
} 
//********************************************************************* 
bit IP_Process(void) 
{ 
    unsigned char i; 
	for(i=0;i<6;i++) 
    { 
		if(Receive_Buff[4+i]!=hard_add[i]) 
			return 0; 
    } 
	if(Receive_Buff[27]!=0x11)                      //上层协议是否为UDP 
		return 0; 
	else 
	{ 
	    for(i=0;i<6;i++) 
			A_m_a[i]=Receive_Buff[i+10];        //取出客户机物理地址 
        for(i=0;i<4;i++) 
            A_IP_add[i]=Receive_Buff[i+30];         //取出客户机IP地址 
		UDP_Process();                               //UDP报处理函数 
		return 1; 
	} 
} 
//********************************************************************* 
bit UDP_Process(void) 
{ 
	unsigned int Pag_Head; 
	Aim_Port=Receive_Buff[38]; 
	Aim_Port<<=8; 
	Aim_Port+=Receive_Buff[39];                      //取出源端口装入目的端口寄存器 
    Loc_Port=Receive_Buff[40]; 
	Loc_Port<<=8; 
	Loc_Port+=Receive_Buff[41];                      //取出目的端口装入源端口    
	Pag_Head=Receive_Buff[46]; 
	Pag_Head<<=8; 
	Pag_Head+=Receive_Buff[47]; 
	if(Pag_Head>=0x0004||Pag_Head<0x0000)          //检验数据包头 
		return 0; 
	else if(Pag_Head==0x0000)                       //如果为写请求WRQ 
	{    
		s=0; 
		ms=0; 
		WRQ_Process();                              //WRQ报处理函数 
		return 1; 
	} 
	else if(Pag_Head==0x0001)                       //如果为数据块包 
	{ 
		ms=0; 
		DATA_Process();                             //DATA报处理函数 
		return 1; 
	} 
	else if(Pag_Head==0x0003)                       //如果为完成标示OVER 
	{ 
		min=0; 
		s=0; 
		ms=0; 
		OVER_Process();                             //OVER报处理函数 
		return 1; 
	} 
	else 
		return 0; 
} 
//********************************************************************* 
bit WRQ_Process(void) 
{ 
    s=0;                                            //秒计数器清零 
	H_Package=Receive_Buff[48]; 
	H_Package<<=8; 
	H_Package+=Receive_Buff[49];                     //取出总数据块数 
	ACK_Send(0); 
	return 1; 
} 
//********************************************************************* 
bit DATA_Process(void) 
{ 
	unsigned char i; 
	ms=0;                                           //毫秒计数器清零 
	Package=Receive_Buff[48]; 
	Package<<=8; 
	Package+=Receive_Buff[49];                       //取出当前块数 
	if(Package!=Count_Pag) 
		return 0; 
	else 
	{ 
		Count_Pag++;                                //计数器加一   
		for(i=0;i<512;i++) 
			DATA_Buff[i]=Receive_Buff[i+50];        //取出有效数据 
		ACK_Send(Package); 
		return 1; 
	} 
} 
//********************************************************************* 
bit OVER_Process(void) 
{ 
	ms=0;                                           //毫秒计数器清零                      
	H_Package=Receive_Buff[48]; 
	H_Package<<=8; 
	H_Package+=Receive_Buff[49];                     //取出总数据块数 
	return 1; 
} 
//********************************************************************* 
void Config_Timmer(void) 
{ 
	TMOD=0x01;                                      //定时器零工作与16位方式 
	TL0=0x66; 
	TH0=0xFC; 
	ET0=1;                                          //定时器零中断使能 
	EA=1;                                           //开总中断 
	TR0=1; 
} 
//********************************************************************* 
void timmer0() interrupt 1 using 1 
{ 
	TR0=0; 
	TL0=0x66; 
	TH0=0xFC; 
    if(ms>=999) 
	{ 
		ms=0; 
		if(s>=59) 
		{ 
			s=0; 
			if(min>=59) 
				min=0; 
			else 
				min++; 
		} 
		else 
			s++; 
	} 
	else 
		ms++; 
    TR0=1; 
} 
//************************************************************************ 
void PORT_Init (void) 
{ 
//   XBR0    = 0x07;                     // Enable SMBus, SPI0, and UART0 
 //  XBR1    = 0x00; 
  // XBR2    = 0x44;                     // Enable crossbar and weak pull-ups 
 //  EMI0TC  = 0x21; 
 //  P74OUT  = 0xFF; 
   //P0MDOUT = 0x15; 
   //P3MDOUT=0xff; 
   //P1MDOUT=0xff; 
   //P2MDOUT=0xff; 
} 
//************************************************************************ 
void RTL8019_init(void) 
{ 
	unsigned char i; 
	unsigned char j; 
    for(i=0;i<255;i++) 
	    for(j=0;j<255;j++); 
    Reset_8019();          //复位8019 
	//chip_select();         //片选 
    page_select(0); 
	reg00=0x21;            //020与8019通信禁止,发送禁止,即进入停止状态 
    for(i=0;i<255;i++) 
	    for(j=0;j<255;j++); 
	reg0a=0x00; 
	reg0b=0x00;            //020与8019通信字节计数器清零 
	reg0c=0xe0;            //接受禁止 
	reg0d=0xe2;            //发送禁止,使用CRC 
	reg01=0x4c;            //配置接受缓存起始页地址 
	reg02=0x80;            //配置接收缓存结束页地址 
	reg03=0x4c;            //接收缓存边界页地址 
	reg04=0x40;            //发送缓存起始页地址 
	reg07=0xff;            //清中断标志 
	reg0f=0x00;            //终止所有中断 
    reg0e=0xc8;            //8位DMA 
	page_select(1);        //选择第一页 
	reg07=0x4d;            //接收缓冲区首页地址 
	reg08=0x00; 
	reg09=0x00; 
	reg10=0x00; 
	reg0a=0x00; 
	reg0b=0x00; 
	reg0c=0x00; 
	reg0d=0x00; 
	reg0e=0x00; 
	reg0f=0x00;            //地址过滤位 
	reg00=0x22;            //RTL8019工作使能 
//	read_mac_add();        //读取物理地址  
	write_mac_add();       //写物理地址至ram 
	page_select(0);        //选择第零页 
	reg0c=0xcc;            //接收使能 
	reg0d=0xe0;     
	reg00=0x22;            //RTL8019工作使能 
	reg07=0xff;            //清中断位 
	//read_reg(reg0f,reg00,0x00,16); 
} 
//*********************************************************** 
void Reset_8019(void) 
{ 
	unsigned char i; 
	unsigned char j; 
 
	unsigned char tmp; 
 
	Reset_High;  
    for(i=0;i<255;i++) 
	    for(j=0;j<255;j++); 
	Reset_Low; 
	for(i=0;i<255;i++) 
	    for(j=0;j<255;j++); 
 
 
	tmp = reg1f; 
	reg1f = tmp; 
 
    for(i=0;i<255;i++) 
	    for(j=0;j<255;j++); 
} 
//*********************************************************** 
/*void read_mac_add(void) 
{ 
	unsigned char i; 
	page_select(0); 
	reg09=0x00;             //读取物理地址的ram地址为0x0000 
	reg08=0x00; 
	reg0b=0x00; 
	reg0a=0x12; 
	reg00=0x0a;             //020读RTL8019 
	for(i=0;i<6;i++) 
	{ 
		mac_add[i]=reg10;   
	} 
}*/ 
//*********************************************************** 
void page_select(unsigned char pagenumber) 
{ 
	unsigned char data temp; 
	temp=reg00;		 
	temp=temp&0x3B ; 
	pagenumber=pagenumber <<6; 
	temp=temp | pagenumber; 
	reg00=temp; 
} 
//*********************************************************** 
 
//*********************************************************** 
void SYSCLK_Init (void) 
{ 
   int i;                              // delay counter 
//    OSCXCN = 0x67;                      // start external oscillator with 
                                       // 18.432MHz crystal 
    for (i=0; i < 256; i++) ;           // Wait for osc. to start up 
//    while (!(OSCXCN & 0x80)) ;          // Wait for crystal osc. to settle 
//    OSCICN = 0x88;                      // select external oscillator as SYSCLK 
                                       // source and enable missing clock 
} 
//*********************************************************** 
void write_mac_add(void) 
{ 
	page_select(1); 
	reg01=hard_add[0]; 
	reg02=hard_add[1]; 
	reg03=hard_add[2]; 
	reg04=hard_add[3]; 
	reg05=hard_add[4]; 
	reg06=hard_add[5]; 
	page_select(0); 
} 
//*********************************************************** 
void RTL8019_send(void) 
{ 
    unsigned int length=64; 
	unsigned char i; 
	reg09=0x40;                       //设置发送起始页高地址 
	reg08=0x00;                       //发送起始页地地址 
	reg0b=length>>8;                  //字节计数器高字节 
	reg0a=length&0xff;                //字节计数器低字节 
	reg00=0x12;                       //020写RTL8019 
	for(i=0;i>8;                  //发送字节高位 
	reg05=length&0xff;                //发送字节低位 
	reg07=0xff;                       //清中断 
	reg00=0x3e; 
} 
//*********************************************************************** 
//*********************************************************************** 
bit RTL8019_receive(void) 
{ 
    unsigned int X_length; 
    unsigned int i; 
	page_select(0); 
	bnry=reg03; 
	page_select(1); 
	curr=reg07; 
	page_select(0); 
    if((curr==0))	 
        return 0;	//读的过程出错 
	bnry=bnry++; 
	if(bnry>0x7f) 
		bnry=0x4c; 
	if(bnry!=curr) 
	{ 
		page_select(0); 
		reg09=bnry; 
		reg08=0x00; 
		reg0b=0x00; 
		reg0a=18; 
		reg00=0x0a; 
		for(i=0;i<18;i++) 
		{ 
			Receive_Buff[i]=reg10; 
		} 
		reg0b=0x00; 
	    reg0a=0x00; 
	    reg00=0x22; 
		Protocol=Receive_Buff[16]; 
	    Protocol=Protocol<<8; 
		Protocol+=Receive_Buff[17];      
        X_length=Receive_Buff[3]; 
        X_length<<=8; 
        X_length+=Receive_Buff[2]; 
		if((Receive_Buff[1]>0x7f)||(Receive_Buff[1]<0x4c)||(Receive_Buff[3])>0x06) 
		{ 
		     page_select(1); 
			 curr=reg07; 
			 page_select(0); 
			 bnry=curr-1; 
			 if(bnry<0x4c) 
			     bnry=0x7f; 
			 reg03=bnry; 
			 reg07=0xff; 
			 return 0; 
		} 
		else 
		{ 
		     
		        reg09=bnry; 
		        reg08=0x00; 
		        reg0b=X_length>>8; 
		        reg0a=X_length&0xff; 
		        reg00=0x0a; 
		        for(i=0;i0x7f) 
			        bnry=0x4c; 
		        reg03=bnry; 
		        reg07=0xff; 
			    return 1; 
		} 
	}     
} 
//***********OKOKOKOKOKOKOK************************* 
void ARP_Request() 
{ 
	unsigned char i; 
	for(i=0;i<6;i++) 
	{ 
		Send_Buff[i]=0xff; 
		Send_Buff[i+6]=hard_add[i]; 
	} 
	Send_Buff[12]=0x08; 
	Send_Buff[13]=0x06; 
	Send_Buff[14]=0x00; 
	Send_Buff[15]=0x01; 
	Send_Buff[16]=0x08; 
	Send_Buff[17]=0x00; 
	Send_Buff[18]=0x06; 
	Send_Buff[19]=0x04; 
	Send_Buff[20]=0x00; 
	Send_Buff[21]=0x01; 
	Send_Buff[28]=0x0a; 
	Send_Buff[29]=0x05; 
	Send_Buff[30]=0x84; 
	Send_Buff[31]=0xd7; 
	Send_Buff[38]=0x0a; 
	Send_Buff[39]=0x05; 
	Send_Buff[40]=0x84; 
	Send_Buff[41]=0x37; 
	for(i=0;i<6;i++) 
	{ 
		Send_Buff[i+22]=hard_add[i]; 
		Send_Buff[i+32]=0x00; 
	} 
	for(i=42;i<64;i++) 
	{ 
	    Send_Buff[i]=i; 
	} 
	RTL8019_send(); 
} 
//************************************************************ 
void RARP(void) 
{ 
    unsigned int i; 
    for(i=0;i<558;i++) 
        Send_Buff[i]=0x00; 
	for(i=0;i<6;i++) 
	{ 
	    Send_Buff[i]=Receive_Buff[i+10]; 
		Send_Buff[i+6]=hard_add[i]; 
    } 
	Send_Buff[12]=0x08; 
	Send_Buff[13]=0x06; 
	Send_Buff[14]=0x00; 
	Send_Buff[15]=0x01; 
	Send_Buff[16]=0x08; 
	Send_Buff[17]=0x00; 
	Send_Buff[18]=0x06; 
	Send_Buff[19]=0x04; 
	Send_Buff[20]=0x00; 
	Send_Buff[21]=0x02; 
	for(i=22;i<28;i++) 
	    Send_Buff[i]=hard_add[i-22]; 
    for(i=28;i<32;i++) 
	    Send_Buff[i]=IP_add[i-28]; 
    for(i=32;i<38;i++) 
	    Send_Buff[i]=Receive_Buff[i-22]; 
    for(i=38;i<42;i++) 
	    Send_Buff[i]=Receive_Buff[i-6]; 
	RTL8019_send(); 
} 
//**************************************************************** 
void ACK_Send(unsigned int count) 
{ 
	unsigned int i; 
	for(i=0;i<558;i++) 
	    Send_Buff[i]=0x00; 
	Send_Buff[42]=0x00; 
	Send_Buff[43]=0x02;                             //填入包类型 
	Send_Buff[44]=count>>8;  
	Send_Buff[45]=count;                            //填入当前包数 
    for(i=0;i<42;i++) 
		Send_Buff[i]=pac_head[i];                   //填入IP头 
	for(i=0;i<6;i++) 
		pac_head[i]=A_m_a[i];                  //填入目的物理地址 
//	pac_head[0]=0x00; 
  //  pac_head[1]=0x13; 
//	pac_head[2]=0xd4; 
//	pac_head[3]=0x3e; 
//	pac_head[4]=0x58; 
//	pac_head[5]=0x67; 
    for(i=0;i<4;i++) 
       pac_head[30+i]=A_IP_add[i];                //填入目的IP地址 
	//pac_head[30]=0x0a; 
	//pac_head[31]=0x05; 
	//pac_head[32]=0x84; 
	//pac_head[33]=0x37; 
    H_H_Length=0x00;                                //IP报总长度高位 
	L_H_Length=0x2e;                                //IP包总长度低位 
    H_Loc_Port=Loc_Port>>8; 
	L_Loc_Port=Loc_Port;                            //填入源端口 
	H_Aim_Port=Aim_Port>>8; 
    L_Aim_Port=Aim_Port;                            //填入目的端口 
	H_UDP_Length=0x00; 
	L_UDP_Length=0x1E;                              //填入UDP长度 
    for(i=0;i<42;i++) 
		Send_Buff[i]=pac_head[i];                   //填入IP头 
    kk=CRC_Process(20,14,0); 
    H_CRC=kk>>8; 
	L_CRC=kk;                                      //填入IP首部校验和 
	kk=CRC_Process(30,34,1);                       //求UDP校验和 
    HUDPCRC=kk>>8; 
	LUDPCRC=kk;                                    //填入校验和 
	RTL8019_send();                                 //发送 
} 
//**************************************************************** 
unsigned int CRC_Process(unsigned char LEN,unsigned char mov,unsigned char type) 
{ 
   	unsigned int b; 
	unsigned long Crc=0x0000; 
	unsigned int i; 
	//p=a; 
	for(i=0;i>16)&0xffff)+(Crc&0xffff); 
	if(Crc&0xffff0000) 
	   Crc++; 
    return ((unsigned int)(~(Crc&0xffff))); 
} 
//******************************************************* 
void Pag_TimeOut(void) 
{ 
	ACK_Send(Package);                          //重发ACK包 
} 
//*******************************************************