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

📄 ethernet_mini_driver.c

📁 利用 pic18f67j60 单片机来实现10M IP网络的连接
💻 C
📖 第 1 页 / 共 5 页
字号:
		EDATA =  0x00;
		i--;
	};	
	i = 4;
	while(i)   			//write destination IP address	
	{
		EDATA = 0xFF;
		i--;
	};	
	tx_end += 20;
	//END IP HEADER
	
	//START UDP HEADER
	EDATA =  0x00;		//write UDP source port (68)
	EDATA =  0x44;
	EDATA =  0x00;		//write UDP destination port (67)
	EDATA =  0x43;
	EDATA =  0x00;		//write UDP length 
	EDATA =  0x00;
	EDATA =  0x00;		//write UDP checksum (no checksum)
	EDATA =  0x00;
	tx_end += 8;
	//END UDP HEADER
	
	/*

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     op (1)    |   htype (1)   |   hlen (1)    |   hops (1)    |
   +---------------+---------------+---------------+---------------+
   |                            xid (4)                            |
   +-------------------------------+-------------------------------+
   |           secs (2)            |           flags (2)           |
   +-------------------------------+-------------------------------+
   |                          ciaddr  (4)                          |
   +---------------------------------------------------------------+
   |                          yiaddr  (4)                          |
   +---------------------------------------------------------------+
   |                          siaddr  (4)                          |
   +---------------------------------------------------------------+
   |                          giaddr  (4)                          |
   +---------------------------------------------------------------+
   |                                                               |
   |                          chaddr  (16)                         |
   |                                                               |
   |                                                               |
   +---------------------------------------------------------------+
   |                                                               |
   |                          sname   (64)                         |
   +---------------------------------------------------------------+
   |                                                               |
   |                          file    (128)                        |
   +---------------------------------------------------------------+
   |                                                               |
   |                          options (312)                        |
   +---------------------------------------------------------------+

*/

	//BEGIN DHCP MESSAGE
	EDATA =  BOOT_REQUEST;		//write DHCP boot record type (request)
	EDATA =  HW_TYPE;		//write DHCP hw address type (10Mb Ethernet)
	EDATA =  HW_TYPE_LEN;		//write DHCP hw address length (6)
	EDATA =  0x00;		//write DHCP hops (0)
	EDATA =  0x01;		//write DHCP transaction id (01020304)
	EDATA =  0x02;		
	EDATA =  0x03;		
	EDATA =  0x04;		
	EDATA =  0x00;		//write DHCP elapsed boot time (0)
	EDATA =  0x00;		
	EDATA =  0x80;		//write DHCP flags (8000)
	EDATA =  0x00;		
	i = 16;
	while(i)   			//write ciaddr,yiaddr,siaddr,giaddr	
	{
		EDATA =  0x00;
		i--;
	};	
	bufferptr = macaddrc;
	i = 6;
	while(i)   			//write source MAC address to chaddr	

	{
		EDATA = *bufferptr;
		bufferptr++;
		i--;
	};	
	i = 202;
	while(i)   			//write remaining 10 bytes of 0x00 to chaddr	
						//write 64 bytes of 0x00 to sname
						//write 128 bytes of 0x00 to file
	{
		EDATA =  0x00;
		i--;
	};	
	tx_end += 236;  
	EDATA =  0x63;		//write DHCP magic cookie (63825363)
	EDATA =  0x82;		
	EDATA =  0x53;		
	EDATA =  0x63;		
	EDATA =  DHCP_MESSAGE_TYPE;		//write DHCP message type 
	EDATA =  DHCP_MESSAGE_TYPE_LEN;	 	
	EDATA =  dhcpmsgtype;		
	tx_end += 7;
	if(dhcpmsgtype == DHCP_DISCOVER_MESSAGE)
		clr_offerrec;
	if(dhcpmsgtype !=  DHCP_DISCOVER_MESSAGE &&
					   tempipaddrc[0] != 0x00 &&
					   tempipaddrc[1] != 0x00 &&
					   tempipaddrc[2] != 0x00 &&
					   tempipaddrc[3] != 0x00 )
		{
			EDATA =  DHCP_SERVER_IDENTIFIER;	   
			EDATA =  DHCP_SERVER_IDENTIFIER_LEN;		
			bufferptr = svridc;
			i = 4;
			while(i)   			//write server ip address (server id)
			{
				EDATA = *bufferptr;
				bufferptr++;
				i--;
			};
		tx_end += 6;
		}	
	EDATA =  DHCP_PARAM_REQUEST_LIST;		//write DHCP parameter list (2 entries)
	EDATA =  DHCP_PARAM_REQUEST_LIST_LEN;		
	EDATA =  DHCP_SUBNET_MASK;		//client's subnet mask
	EDATA =  DHCP_ROUTER;		//routers on the client's subnet	
	tx_end += 4;
	if(dhcpmsgtype == DHCP_REQUEST_MESSAGE)
	{
			EDATA =  DHCP_PARAM_REQUEST_IP_ADDRESS;	   
			EDATA =  DHCP_PARAM_REQUEST_IP_ADDRESS_LEN;		
			bufferptr = tempipaddrc;
			i = 4;
			while(i)   			//write requested ip address 
			{
				EDATA = *bufferptr;
				bufferptr++;
				i--;
			};
		tx_end += 6;
	}

	EDATA = 0xFF;		//end of options	
	tx_end += 1;
	//DHCP MESSAGE END
	
	// write ip header total length
    //banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART+0x11);
	EWRPTH = HIGH_BYTE(TXSTART+0x00);
	
	i = tx_end - 15;	
	EDATA =  HIGH_BYTE(i);   
	EDATA =  LOW_BYTE(i);   

	// write udp header total length
    //banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART+0x27);
	EWRPTH = HIGH_BYTE(TXSTART+0x00);
	
	i = tx_end - 35;	
	EDATA =  HIGH_BYTE(i);   
	EDATA =  LOW_BYTE(i);   

	//compute ip header checksum
    hdrlen = (0x45 & 0x0F) * 4; //hdrlen = 20 bytes
	offsetval = TXSTART+15;		//beginning of IP header
	EDMASTL = LOW_BYTE(offsetval);
	EDMASTH = HIGH_BYTE(offsetval);
	offsetval += (hdrlen-1);
	EDMANDL = LOW_BYTE(offsetval);
	EDMANDH = HIGH_BYTE(offsetval);
	ECON1 |= (ECON1_CSUMEN | ECON1_DMAST);
    while(ECON1 & ECON1_DMAST);
    chksum_lo =  EDMACSL;
    chksum_hi =  EDMACSH;
   
    //write ip checksum values to TX buffer
    offsetval = TXSTART+25;
    EWRPTL = LOW_BYTE(offsetval);
    EWRPTH = HIGH_BYTE(offsetval);
	EDATA =  chksum_hi;
	EDATA =  chksum_lo;
    tx_end += (TXSTART-1);
    //banksel(ETXNDL);
	ETXNDL = LOW_BYTE(tx_end);
	ETXNDH = HIGH_BYTE(tx_end);

   //send the contents of the transmit buffer onto the network
	temp =  EIR;
	if((temp & EIR_TXERIF) == 1)
	{
	 TXERIF = 0;
     TXRTS = 1;
   	 TXRTS = 0;
	}
	TXIF = 0;
   	TXRTS = 1;
	//do{
		//temp =  ECON1);
		//}while((temp & ECON1_TXRTS) == 1);
	while(1 == (ECON1 & ECON1_TXRTS));
//	++i;
}
//******************************************************************
//*	RECEIVE DHCP MESSAGE ROUTINE
//******************************************************************
char receive_dhcp(void)
{
	unsigned int i;
	//char *packetptr,dhcpmsgchar;
	msgtype = DHCP_UNKNOWN_MESSAGE;
	clr_done;
	if(packet[DHCP_op] == BOOT_REPLY)
	{
		if(bofferrec == 0)
		{
			for(i=0;i<4;++i)
				tempipaddrc[i] = packet[DHCP_yiaddr+i];
		}
		if(  packet[DHCP_chaddr] == macaddrc[0] &&
			   packet[DHCP_chaddr+1] == macaddrc[1] &&
			   packet[DHCP_chaddr+2] == macaddrc[2] &&
			   packet[DHCP_chaddr+3] == macaddrc[3] &&
			   packet[DHCP_chaddr+4] == macaddrc[4] &&
			   packet[DHCP_chaddr+5] == macaddrc[5])
			   {
				   packetptr = &packet[DHCP_options+4];
				   do{
					   dhcpmsgchar = *packetptr++;
					   switch(dhcpmsgchar)
					   {
						   case DHCP_MESSAGE_TYPE:
					   		msglen = *packetptr++;
					   		if(msglen == 0x01)
					   		{
						   		msgtype = *packetptr++;
						   		if(bofferrec && (msgtype == DHCP_OFFER_MESSAGE))
						   		{
							   		set_trashit;
							   	}
							   	
							 }
							 else
							 	set_trashit;
							break; 
							
							case DHCP_SERVER_IDENTIFIER:
					   		msglen = *packetptr++;
					   		if(msglen == 0x04)
					   		{
								for(i=0;i<4;++i)
								{
									tempsvridc[i] = *packetptr++;
								}
							 }
							 else
							 	set_trashit;
							break;
							
							case DHCP_SUBNET_MASK:
					   		msglen = *packetptr++;
					   		if(msglen == 0x04)
					   		{
								for(i=0;i<4;++i)
								{
									tempsubnetmaskc[i] = *packetptr++;
								}
							 }
							 else
							 	set_trashit;
							break;
							
							case DHCP_IP_LEASE_TIME:
					   		msglen = *packetptr++;
					   		if(msglen == 0x04)
					   		{
						   		if(bofferrec)
						   		{	
							   		for(i=0;i<4;++i)
							   			*packetptr++;
							   	}
							   	else
							   	{
									for(i=0;i<4;++i)
									{
										templeasetimec[i] = *packetptr++;
									}
								}
								leasetime = make32(templeasetimec[0],templeasetimec[1],templeasetimec[2],templeasetimec[3]);
								if(leasetime > 1800)
									leasetime -= 1800; //renew 30 minutes before the lease expires
								//uncomment line below to test DHCP RENEW	
								//leasetime = 60;
							 }
							 else
							 	set_trashit;
							break;
							
							case DHCP_ROUTER:
					   		msglen = *packetptr++;
					   		if(msglen >= 0x04) 
					   		{
						   		if(bofferrec)
						   		{	
							   		for(i=0;i<4;++i)
							   			*packetptr++;
							   	}
							   	else
							   	{
									for(i=0;i<4;++i)
									{
										tempgwayipaddrc[i] = *packetptr++;
									}
								}
							 }
							 else
							 	set_trashit;
							 msglen -= 4;
							 while(msglen--)
							 	*packetptr++;
							break;
							
							case DHCP_END_OPTION:
								set_done;
							break;
							
							default:
					   		msglen = *packetptr++;
							 while(msglen--)
							 	*packetptr++;
							break;
						}
					   
				   }while(bdone == 0);
			   }   
		}
		if(msgtype == DHCP_OFFER_MESSAGE)
		{
			for(i=0;i<4;++i)
				{
					svridc[i] = tempsvridc[i];
				}
			set_offerrec;

		}
		else
		{
			if( svridc[0] != tempsvridc[0] ||
				svridc[1] != tempsvridc[1] ||
				svridc[2] != tempsvridc[2] ||
				svridc[3] != tempsvridc[3] )
				{
					msgtype = DHCP_UNKNOWN_MESSAGE;
				}
		
	}
	if(btrashit)
		clr_newdhcppkt;

	return msgtype;			   
}
//******************************************************************
//*	Perform ARP Request
//*   This routine uses a known remote IP address to get a remote
//*   Ethernet modules's MAC (hardware) address.
//******************************************************************
void arp_request(void)
{
	//char temp;
	unsigned int i,tx_end;	

	clr_arpflag;
	tx_end = TXSTART;
   //load beginning page for transmit buffer
    //banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART);
	EWRPTH = HIGH_BYTE(TXSTART);

   //write control byte
	wr_sram(tx_control_byte);
	++tx_end;
   //build destination MAC address	
	for(i=0;i<6;++i)
	{
   		wr_sram(0xFF);
		++tx_end;
	}
   //build source MAC address	
 	for(i=0;i<6;++i)
	{
  		wr_sram(macaddrc[i]);
		++tx_end;
	}

	wr_sram(0x08);		//ARP packet type
	wr_sram(0x06);		
	tx_end +=2;
	wr_sram(0x00);		//hardware type = 10Mb Ethernet
	wr_sram(0x01);		
	tx_end +=2;
	wr_sram(0x08);		//IP protocol
	wr_sram(0x00);		
	tx_end +=2;
    wr_sram(0x06); 	 	//hardware addr len (06)
    wr_sram(0x04); 	 	//hardware protocol addr len(04)
	tx_end +=2;
	wr_sram(0x00);		//ARP request
	wr_sram(0x01);		
	tx_end += 2;
   //build source MAC address	
	for(i=0;i<6;++i)
	{
   		wr_sram(macaddrc[i]);
		++tx_end;
	}
   //build source IP address	
	for(i=0;i<4;++i)
	{
   		wr_sram(ipaddrc[i]);
		++tx_end;
	}
   //build unknown target MAC address area	
	for(i=0;i<6;++i)
	{
   		wr_sram(0x00);
		++tx_end;
	}
   //build target IP address	
	for(i=0;i<4;++i)
	{
   		wr_sram(remoteipaddrc[i]);
		++tx_end;
	}
   //mark end of ARP request packet	
	//banksel(ETXNDL);
	ETXNDL = LOW_BYTE(tx_end);
	ETXNDH = HIGH_BYTE(tx_end);
   //send the contents of the transmit buffer onto the network
	//temp =  EIR);
	//do{
		//temp =  ECON1);
	while((ECON1 & ECON1_TXRTS) == 1);

⌨️ 快捷键说明

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