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

📄 main.c

📁 51单片机上实现tcp/ip的源代码
💻 C
字号:
/*********************************************************************
*            Copright(c) 2004,张会福 湖南科技大学计算机学院 
*						All rights reserved.
*
*文件名称:	main.c
*文件标识: 
*摘    要: 主程序,  串口工作在中断方式的接收和发送,可通过串口显示相关信息以及输入信息
*
*当前版本: V1.0
*完成日期: 2004.4.1
*
*
*********************************************************************/

/**********************************************************************************************/

#include "net_cfg.h"
//#include "global.c"		//全局变量以及以太网底层驱动程序
//#include "uart.c"   	//串口相关的程序
//#include "arp.c"		//地址解析程序
//#include "udp.c"		//
//#include "icmp.c"		//ping操作的程序
//#include "tcp.c"		//
//#include "input.c"    	//串口服务器数据接收程序
//=============================================================================================

sfr ckcon=0x8f;


main()
{
	unsigned char i;
	ckcon=0x01;
	AUXR = 0x00;		//使能P89C668的外部数据区
	RESET=0;
	Delay_MS(60);
	RESET=1;
	Delay_MS(60);
	RESET=0;
	/*********************************************************************************
	用户可在下面的程序中修改IP地址,只要输入您要设定的IP地址和网关地址分别代替下面程序中
	字符串的值即可
	*********************************************************************************/				
	My_Ip_Address.dwords = IP_SETTING;//函数的参数就是IP地址,可以直接设定	    
	Gateway_Ip_Address.dwords = GATEWAY_SETTING;	//可在此设置合适的网关值
	Mask_Ip_Address.dwords=IP_MARK_SETTING; 		//255.255.255.0,子网掩码
	
	/********************************************************************************/
	
	initial_system();
	
	Printf_String("\r\n**********欢迎来到单片网络验世界***************");
	Printf_String("\r\n当前的 IP = ");
	Printf_IPStr(My_Ip_Address);
	Printf_String("\r\n网关的 IP = ");
	Printf_IPStr(Gateway_Ip_Address);
	Printf_String("\r\n子网掩码 Mask= ");
	Printf_IPStr(Mask_Ip_Address);
	Printf_String("\r\n");
	
	while(1)
	{
		//超时处理把Tcp_Timeout清零Tcp_Timeout每10ms由定时器置位
		if(Tcp_Timeout)Process_Tcp_Timeout();//处理TCP超时,Tcp_Timeout标志在中断中置位
		//Process_Tcp_Timeout()每10ms处理一次
		if(BiSecond)
		{ //两秒处理一次
			BiSecond=0;
			if(TCP1024.State==0)	//本地机处于监听状态
				process_command();	//处理串口输入,可引发本地发起通讯
			Process_Ping();
			Process_Udp_Command();	//
			Gateway_Arp_Request();	//对网关的IP进行解析
		}
		
		for(i=0;i<5;i++)
		{//检查是否有新的数据包收到,如果有将置位have_new_packet,并将数据包接收进由RxdNetBuff指向的缓冲区
			if(Rec_NewPacket())
			{
				if(RxdNetBuff.EtherFrame.NextProtocal==0x0806)		//表示收到一个arp请求包
				{
					if(RxdNetBuff.ArpFrame.Operation==0x0001) 		//表示收到的数据包是一个ARP请求报文
					{
						Arp_Answer();
					}	//对ARP请求报文进行回答
					else if( RxdNetBuff.ArpFrame.Operation==0x0002)	//表示收到的数据包是一个ARP回答报文
					{
						Arp_Process();
					}//对ARP回答报文进行处理	
				}
				else if(RxdNetBuff.EtherFrame.NextProtocal==0x0800)	//表示收到的数据包是一个IP数据报
					if((RxdNetBuff.IpFrame.VerandIphLen&0xf0)==0x40)	//表示收到的IP数据报是IPv4版本
						if(VerifyIpHeadCrc())	//IP首部校验和正确
						{ 					//这时表示正确地接收到一个ip包,下面按照IP的下层协议类型进行相应处理
							switch(RxdNetBuff.IpFrame.NextProtocal)
							{
							case 1:			//表示收到的IP数据报为ICMP查询报文(本程序仅对PING操作进行处理)
								if(RxdNetBuff.IcmpFrame.type==8) 		//表示收到的ICMP报文是一个ping的请求包
								{
									Ping_Answer();
								}					//PING回答
								else if(RxdNetBuff.IcmpFrame.type==0)	//表示收到的ICMP报文是一个ping的应答包
								{
									Ping_Echo();
								} 						//PING操作的信息在本地回显,本程序通过串口实现
								break;
							case 6: 		//IPFrame的下层协议字段为6表示下层协议为TCP,表示收到TCP报文
								Process_Tcp();
								break;
							case 0x11:		//IPFrame的下层协议字段为17表示下层协议UDP,表示收到UDP报文
								Process_Udp();
								break;
							default:;
							}
						}
			}
		}
	}
}

/**********************************************************************
**函数原型:	void 	timer0() interrupt 1
**入口参数:	无
**出口参数:	无
**返 回 值:	无
**说    明:	中断函数,10ms中断一次,进行ARP老化处理,设置TCP超时
************************************************************************/
void timer0() interrupt 1
{
	//工作在16位定时模式,中断时间为10毫秒中断一次,误差小于千分之1,晶振使用22.1184Mhz
	tl0=9;
	th0=184;
	Msec++;
	Tcp_Timeout=1;	//置位TCP超时标志
	if(Msec==100)
	{ 	//100分频,就是1秒一次
		Msec=0;
		Sec++;
		BiSecond=1;		//置位两秒标志
		if(Sec==60)
		{
			Sec=0;	//每分钟一次
			Min++;
			if(Min==60)Min=0;
			//网关和PING操作对象主机的以太网地址生存时间每秒减一,实际上是ARP老化操作简单处理
			if(Gateway_IP_TTL>0)Gateway_IP_TTL=Gateway_IP_TTL-1;
			if(Ping_IP_TTL>0)Ping_IP_TTL=Ping_IP_TTL-1;
		}
		
	}
}

/**********************************************************************
**函数原型:	void 	serial(void) interrupt 4
**入口参数:	无
**出口参数:	无
**返 回 值:	无
**说    明:	串口中断函数:中断函数在接收中断处理中将接收数据放到接收缓冲区
**		  :	接收缓冲区ComRxdBuf大小可根据需要进行调整,由两个指针管理
ComRxdWrite和ComRxdRead进行管理;在发送中断处理中将数据由发送
缓冲区输出到串口,输出缓冲区由指针ComTxdRead和ComTxdWrite管理.
在global.c定义了一组对缓冲区进行操作的程序.
************************************************************************/
void serial(void) interrupt 4
{
	unsigned char temp;
	if(ti) 
	{	//串口发送中断处理
		ti=0;
		if(ComTxdRead!=ComTxdWrite)//发缓区有数据,继续发送数据
		{
			sbuf=ComTxdBuf[ComTxdRead];
			ComTxdRead++;
			if(ComTxdRead==COM_TXD_BUFF_SIZE)
				ComTxdRead=0;
			ComTxdBufempty=0;
		}
		else 
		{
			ComTxdBufempty=1;
		}
	}
	if (ri)
	{ 	//串口接收中断处理
		ri=0;
		temp=sbuf;
		ComRxdBuf[ComRxdWrite]=temp;
		if(!TcpConnected)
		{
			Printf_Char(temp);
		}
		ComRxdWrite++;
		if(ComRxdWrite==COM_TXD_BUFF_SIZE)
			ComRxdWrite=0;
		if(temp==0x0d)
		{
			if(!TcpConnected)
			{
				Printf_Char(0x0a);
			}
		}
	}
}

⌨️ 快捷键说明

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