⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ethernet.c

📁 此代码是实现将lwip协议移植于51单片机的测试程序
💻 C
字号:
//****test ram 0xFDF0-0xFE0F ,write and read, compare two value so that test 8019as physical circuit.
//****mac ---txdnet(source MAC)   init8019as;add mask command
//****host ---txdnet
//****initNIC ---txdnet(source MAC/IP)
//SNMP==UDP?
//****add lc/ls command to display host mask mac.../arp table
//****arp_process ---force to write to some location when table full.
//****ping_echo ---print IP answer.and set pinganswerd flag.
//****subnet/net/self.(ping/udp)
//****add ping/udp command.
//findmacadr add index parameter
//****Don't set global varible before read.(Host/Mac...)
//开始时发ARP包;主动更新ARP缓存;不是给自己的ARP广播也用于刷新缓存;收到ARP应答
//则更新定时器。
//
//extern long int secondtimer;
#include <general.h>
//#include <serial.h>
//#include <snmp.h>
//#include <word.h>
//#include <ethernet.h>
//#include <SerEEROM.h>
//#include <convert.h>
//#include <string.h>
//#include <mystring.h>

//extern long int secondtimer;
static long int secondtimer=0;

xdata union ethernet_address_type my_ethernet_address;		//本机的以太网地址
xdata union ethernet_address_type gateway_ethernet_address; //网关的以太网地址
xdata union ethernet_address_type ping_ethernet_address;	//用来ping的以太网地址

xdata union ip_address_type my_ip_address;		//本机的ip地址
xdata union ip_address_type gateway_ip_address;	//网关的ip地址
xdata union ip_address_type mask_ip_address;	//子网掩码
xdata union ip_address_type SNMP_ip_address;	//网管SNMP主机的ip地址
xdata union ip_address_type ping_ip_address;	//用于ping命令
xdata union ip_address_type temp_ip_address;	//临时变量

xdata union arp_table_type arp_tab[MaxLenARPtable];

bit txd_buffer_select=0;		//选择网卡的发送缓冲区
unsigned char ping_count;		//ping的次数
unsigned char udp_count;		//udp的次数

xdata union netcard rxdnet;
xdata union netcard txdnet;

unsigned char index=0;			//ARP table 循环加入点
unsigned int frameindex=0;		//IP包的序列号

struct TXBUF{
	unsigned char status;
	unsigned char ttl;
	union ip_address_type ip;
	unsigned char type;
	unsigned char pinganswerd;
	unsigned int length;
	union netcard pack;
} txdbuf[MaxLenTxBuf];

void page(unsigned char pagenumber)//ne2000页选择
{
	unsigned char data temp;
	temp=reg00&0x3B;//注意txp位不能要
	pagenumber=pagenumber <<6;
	temp=temp | pagenumber;
	reg00=temp;
}

void getadr(unsigned char id,unsigned char *bytes)//读取MAC地址参数
{
	int len;

	if(id==MACADR) len=6;		//不是很安全,没有检测参数错误!
	else len=4;	
	opx5045(READ,id,len,bytes);	//读出地址存到bytes[]里
}

void setadr(unsigned char id,unsigned char *bytes)//设置MAC地址参数
{
	int len;
	unsigned char i,WIP;

	if(id==MACADR) len=6;		//不是很安全,没有检测参数错误!
	else len=4;	
	//			
		do{
			opx5045(RDSR,0,0,&WIP);
		}while((WIP&0x1)==1);
	//
	for(i=0;i<len;i++,id++){	//将地址写入X5045.		
		opx5045(WREN,id,1,&bytes[i]);
		opx5045(WRITE,id,1,&bytes[i]);
		//			
		do{
			opx5045(RDSR,0,0,&WIP);
		}while((WIP&0x1)==1);
		//
	}	
}

void initNIC(void)//初始化网卡配置参数
{
	unsigned char i;

	getadr(MACADR,&my_ethernet_address.bytes[0]);//读出网卡的物理地址存到my_ethernet_address.bytes[6]里
	
	page(1);//init 8019as PAR
	reg01=my_ethernet_address.bytes[0];
	reg02=my_ethernet_address.bytes[1];
	reg03=my_ethernet_address.bytes[2];
	reg04=my_ethernet_address.bytes[3];
	reg05=my_ethernet_address.bytes[4];
	reg06=my_ethernet_address.bytes[5];

	for(i=0;i<3;i++)
		txdnet.etherframe.sourcenodeid[i]=my_ethernet_address.words[i];

	getadr(HOST,&my_ip_address.bytes[0]);//读出本机IP地址存到my_ip_address.bytes[4]里
	getadr(MASK,&mask_ip_address.bytes[0]);//读出本机掩码存到mask_ip_address.bytes[4]里
	getadr(GATEWAY,&gateway_ip_address.bytes[0]);//读出网关IP地址存到gateway_ip_address.bytes[4]里	
	getadr(SNMPHOST,&SNMP_ip_address.bytes[0]);//读出SNMP网管主机IP地址存到SNMP_ip_address.bytes[4]里	
}

void delay_ms(unsigned char ms_number)//延时
{
//延时子程序,延时时间单位为1毫秒,晶振使用22。1184兆赫,芯片使用mcs51兼容芯片
//ms_number为需要延时的毫秒数,最大为255毫秒  误差小于1 % 
	unsigned int  i;
	unsigned char j;
	for(j=0;j<ms_number;j++)
		for(i=0;i<229;i++);
}

void rtl8019as_rst()//RTL8019AS复位
{	
	unsigned char temp;
	
	delay_ms(200);
	temp=reg1f;//读网卡的复位端口
	reg1f=temp; //写网卡的复位端口
	delay_ms(200);
}

void ne2000init()//ne2000网卡初始化
{
	rtl8019as_rst();

//??????????????????????????????????删
	
#ifdef debug	
	page(2);
	PrintStr("\nPSTART=");
	PrintByte(reg01);
	PrintStr("\nPSTOP=");
	PrintByte(reg02);	
	PrintStr("\nTPSR=");
	PrintByte(reg04);
	PrintStr("\nRCR=");
	PrintByte(reg0c);
	PrintStr("\nTCR=");
	PrintByte(reg0d);
	PrintStr("\nDCR=");
	PrintByte(reg0e);
#endif
} 

void send_packet(union netcard *txdnet,unsigned int length)//ne2000发包子程序
{//发送一个数据包的命令,长度最小为60字节,最大1514字节需要发送的数据包要先存放在txdnet缓冲区
	unsigned char i;
	unsigned int ii;
	
//??????????????????????????????????删
	
	reg00=0x3E;				//to sendpacket;  
}

bit recv_packet(union netcard *rxdnet)//ne2000收包子程序
{
	unsigned char i;
	unsigned int ii;
	unsigned char bnry,curr;
   
//??????????????????????????????????删
	return 0;
}

void trans_pack(union netcard *txdnet,union ip_address_type destip,unsigned int length,unsigned char type)//发包至缓冲区
{
	unsigned char i;
	unsigned int j;

	for(i=0;i<MaxLenTxBuf;i++){
		if(txdbuf[i].status==0){
			txdbuf[i].status=1;
			txdbuf[i].length=length;
			txdbuf[i].type=type;
			txdbuf[i].ip.dwords=destip.dwords;
			txdbuf[i].ttl=8;
			if(type==PINGTYPE) txdbuf[i].pinganswerd=1;
			for(j=0;j<length;j++)
				txdbuf[i].pack.bytes.bytebuf[j]=txdnet->bytes.bytebuf[j];
			break;
		}
	}
}

void process_trans_pack()//发包缓冲区发送处理
{
	unsigned char i,j;
	unsigned char ipstr[16];
	
	for(i=0;i<MaxLenTxBuf;i++){
		if(txdbuf[i].status==1){
			if(txdbuf[i].type==PINGTYPE){
				if(txdbuf[i].ttl==0)
					txdbuf[i].status=0;					
				else{
					txdbuf[i].ttl--;

					ping_ip_address.dwords=txdbuf[i].ip.dwords;
	
					if(txdbuf[i].pinganswerd==0){
						PrintStr("\n\tRequest timed out.(");
						HEXToIPadr(ipstr,&txdbuf[i].ip.dwords);
						PrintStr(ipstr);
						PrintStr(")\n");
					}
					else
						txdbuf[i].pinganswerd=0;
	
				    if(ping_ip_address.dwords==my_ip_address.dwords){
						PrintStr("\n\tReply from ");
						HEXToIPadr(ipstr,&txdbuf[i].ip.dwords);
						PrintStr(ipstr);
						//PrintLong(txdbuf[i].ip.dwords);
						PrintStr(" TTL=80\n");
						txdbuf[i].pinganswerd=1;
					}
					else if((ping_ip_address.dwords&mask_ip_address.dwords)!=(my_ip_address.dwords&mask_ip_address.dwords))
						ping_ip_address.dwords=gateway_ip_address.dwords;//not in same subnet.
			
					if(findmacadr(ping_ip_address,&ping_ethernet_address)==1){
						ping_request();
						//for(j=0;j<3;j++)
					    //	txdbuf[i].pack.etherframe.destnodeid[j]=ping_ethernet_address.words[j];
						for(j=0;j<3;j++)
					    	txdnet.etherframe.destnodeid[j]=ping_ethernet_address.words[j];
						//send_packet(&txdbuf[i].pack,txdbuf[i].length);
						send_packet(&txdnet,txdbuf[i].length);
					}
					else{
						arp_request(ping_ip_address.dwords);
					}
				}
			}
			else if(txdbuf[i].type==UDPTYPE){
				if(txdbuf[i].ttl==0)
					txdbuf[i].status=0;					
				else{
					txdbuf[i].ttl--;

					ping_ip_address.dwords=txdbuf[i].ip.dwords;
		
				    if(ping_ip_address.dwords==my_ip_address.dwords){
						PrintStr("\nUDP myself ERROR!\n");
						txdbuf[i].ttl=0;						
					}
					else if((ping_ip_address.dwords&mask_ip_address.dwords)!=(my_ip_address.dwords&mask_ip_address.dwords))
						ping_ip_address.dwords=gateway_ip_address.dwords;//not in same subnet.
			
					if(findmacadr(ping_ip_address,&ping_ethernet_address)==1){
						for(j=0;j<3;j++)
					    	txdbuf[i].pack.etherframe.destnodeid[j]=ping_ethernet_address.words[j];
						//remake_udp(&txdbuf[i].pack);
						send_packet(&txdbuf[i].pack,txdbuf[i].length);
						txdbuf[i].ttl=0;
					}
					else{
						arp_request(ping_ip_address.dwords);
					}
				}
			}
		}
	}
}

void arp_request(unsigned long ip_address)//ARP请求
{//请求解析ip地址
	unsigned char i;
    
//??????????????????????????????????删

	for(i=0x2E;i<(0x2E+18);i++)
		txdnet.bytes.bytebuf[i]=0x00;
	send_packet(&txdnet,60);
}

void arp_answer()//ARP应答
{
	unsigned char i;

//??????????????????????????????????删

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -