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;i 0x7f) 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包 } //*******************************************************