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

📄 main.c

📁 基于51单片机和RTL8019以太网控制器的嵌入式以太网控制程序。
💻 C
字号:
#include <general.h>
#include <string.h>
struct timer
{
	unsigned char count;
	unsigned char arrived;
};
data struct timer  D10ms,D1s;

unsigned char xdata count_connect;
unsigned char xdata bConnect;
unsigned char xdata bFirst;
unsigned char Count10ms;
unsigned char xdata IndexOfClient;	 //客户端套接字序号
sbit P10=P1^0;
sbit P11=P1^1;

//外部数据
extern xdata union Ethernet_address my_ethernet_address;
extern xdata union IP_address my_ip_address;
extern xdata union netcard rxdnet;
extern xdata union netcard txdnet;
extern xdata union IP_address ping_ip_address;
extern unsigned long  xdata initial_sequence_nr;
extern xdata union sw Server_PORT;
extern xdata struct connection  conxn[NO_CONNECTION];
extern xdata union IP_address my_ServerIP;

#define   TIMEH1ms    0xF8
#define   TIMEL1ms    0x96

extern void Disp_All(void);


//------------------------------------------------------------------------
//函数功能:延时程序
//
//入参:	无
//
//返回值:	无
//
//作者:	Mingtree
//
//注释:	Mingtree
//日期:	2004-09-19
//------------------------------------------------------------------------
void Delay10ms()
{

	unsigned int iSmall;
	unsigned char iBig;
	for(iBig = 0; iBig < 10; iBig++)
		for(iSmall = 0; iSmall < 0xFFFF; iSmall++);
}
//------------------------------------------------------------------------
//函数功能:定时器0,每250us进入一次
//
//入参:	无
//
//返回值:	无
//
//
//说明:    每隔250us进入一次,进入后将D1ms减一,减到0后重赋4;减到0时表示已经过了1ms,
//          再将D10ms减一,减到0后赋10,表示过了10ms,再将1s的减一.
//			该定时器的作用是在主程序中定时地去调用一些函数,实现某些需要定时的功能.
//		    该定时器实现各种定时的精度取决于将定时时间段分割的大小,比如,将1ms分成了4段,
//			最大的误差为250us,因为D1ms的某个数值(比如是4)持续的时间是250us,在主程序中,
//			在这250us里去检测该D1ms的植,得到的结果都为4.
//作者:	Mingtree
//
//注释:	Mingtree
//日期:	2004-09-19
//------------------------------------------------------------------------
void  timer0()  interrupt 1
{
	D10ms.count--;
	if(0==D10ms.count)
	{
		D10ms.arrived=TRUE;
		D10ms.count=10;
		D1s.count--;
		if(0==D1s.count)
		{
			D1s.count=100;
			D1s.arrived=TRUE;
		}

	}
	
	TH0=TIMEH1ms;
	TL0=TIMEL1ms;
	TR0=1;
}

//------------------------------------------------------------------------
//函数功能:初始化定时器,设置波特率
//
//入参:	无
//
//返回值:	无
//
//
//说明:    
//          		   
//作者:	Mingtree
//
//注释:	Mingtree
//日期:	2004-09-19
//------------------------------------------------------------------------
void init_Timer()
{
	IE=0x00;
    ET0=1;          // timer0 interrupt enable
    ES=1;           // RS-232 interrupt enable
    EA=1;           // all interrupt enable

	TMOD=0x21;		//定时器1用于波特率发生器,定时器0用于定时
	TH0=TIMEH1ms;
	TL0=TIMEL1ms;
	D10ms.arrived=FALSE;
	D1s.arrived=FALSE;
    D1s.count=100;
	D10ms.count=10;

	//启动定时器
	TR0=1;
}

//------------------------------------------------------------------------
//函数功能:设置PING的IP地址
//
//入参:	无
//
//返回值:	无
//
//作者:	Mingtree
//
//注释:	Mingtree
//日期:	2004-09-19
//------------------------------------------------------------------------
void SetPingIP(unsigned char xdata *pBuf)
{
	unsigned char i;
	for(i=0;i<4;i++)
		ping_ip_address.bytes[i]=pBuf[i];

}
//-------------------------------------------------------
//           -----------main program--------
//-------------------------------------------------------
void main()
{

	//定义命令数组
	static unsigned char code ComTable[MaxComNum][MaxLenCom+1]={"connect","ping","setsip","setlip",
		                          "setmac","ipconfig","setsport","setgate","wb05d000","tcpstate"};


	unsigned char data State=StatInputCom;		//状态
	unsigned char xdata ch;
	unsigned char xdata ComBuf[MaxLenComBuf+1];	/*store '\0'*/
	int i=-1;			/*ComBuf pointer*/
	int tem;			/*Temp variable*/
	int ComMatchFlag=0;		/*Command match flag*/

	WORDTABLE xdata WordTable;
	
	int Matched=0;	/*Match flag*/

	//各项初始化工作,包括定时器工作方式设定,8019初始化,串口初始化
	//---------------------------------
	InitSerial();
	InitSerialBuffer();

	init_Timer();


	//从5045里读各个参数
	ReadGateway();
	ReadLIP();
	ReadMAC();
	ReadServerIP();
	ReadServerPort();
	//设置未连接
	bConnect = FALSE;
	count_connect=0;
	bFirst = TRUE;
	//根本未开始请求
	IndexOfClient = 6;

	//初始化8019as
	init_8019();

	//初始化PING表
	InitPingTable();
	//初始化ARP表
	InitArpTable();
	//初始化tcp
	init_tcp();

    //调试用的,一闪一闪表示没死机
    P10=0;
	//主循环
	//申请一个套接字
	Disp_All();

	while(1)
	{
		if(query_8019())	//表示收到数据包
			maincycle();
	
	
		if(10==D10ms.count)	//10ms定时到
		{
			D10ms.arrived=FALSE;
			// 初始序列号加1.
			initial_sequence_nr += 1280;
			//防止溢出
			tcp_retransmit();
			if (initial_sequence_nr==0xFFFFFFFFL) initial_sequence_nr=1;
		}
		if(100==D1s.count&&D1s.arrived)	//1s定时到
		{
			//保证D1s=100的时候只进来一次
			D1s.arrived=FALSE;
			//tcp保活定时器
			tcp_inactivity();
			PingCycle();
			//更新ARP表的生存时间
			updatearptab();
			
			//测试用的
			P10=~P10;
			//如果已经发出SYN_SEND,则判断是否已连接,这里认为从发出SYN_SEND
			//到建立连接时间不超过1s,这个假定是合理的。如果在发出SYN_SEND
			//1s后还未建立连接,则认为是服务器端(上位机)没有在监听
			if(bFirst)
			{
				bFirst = FALSE;
				IndexOfClient = TCPSocket();
			}
			//找到空闲套接字
			
			//每隔1秒去连接一次,直到连上为止
			if(!bConnect)
			{
				if(IndexOfClient != ERR_SOCK_FULL)
				{
					TCPConnect(IndexOfClient,my_ServerIP,Server_PORT.word,OnReceive,OnClose,OnConnect);
				}
				count_connect++;
				if(count_connect>10)
				{
					//连接10次仍旧连不上,初始化芯片		
					//初始化PING表
					InitPingTable();
					//初始化ARP表
				//	InitArpTable();
					init_tcp();
					bFirst = TRUE;
					count_connect=0;
				}
			}
		}
		//处理通过串口发过来的命令
		switch(State)
		{
			case StatInputCom://开始收集命令
			{

				//搜集80个命令字符,MaxCmd=80
				if(Mygetch(&ch))
				{
					if(i<MaxCmd-2)
					{
						i=i+1;
						ComBuf[i]=ch;
					}
					else
					{
						//命令收集结束
						ComBuf[i+1]='\0';
						State=StatExeCom;
					}
					break;
				}
				else
				{
	//				maincycle();
					break;
				}
			}
			//开始处理命令
			case StatExeCom:
			{
				//检查命令还是数据
				if(ComBuf[0] == 0x00)
				{
					if(GetWord(ComBuf,&WordTable)==1)
					{
						Mystrlwr(WordTable.wt[0].Str);
						for(tem=0;tem<MaxComNum&&!ComMatchFlag;tem++)
						{
							if(strcmp(WordTable.wt[0].Str,ComTable[tem])==0)
								ComMatchFlag=1;
						}
						if(ComMatchFlag)
						{
							tem--;
							switch(tem)
							{
								//显示连接ok
								case 0:{PrintStr("connect ok");break;}
								case 1:{		//ping
										SetPingIP(WordTable.wt[1].Str);
										ping_request();
										break;
									   }
								case 2:{		//写要连接的服务器端IP
										WRiteServerIP(WordTable.wt[1].Str);
										PrintStr("Write ServerIP OK");
										break;
									   }
								case 3:{		//写本地IP
										WRiteLIP(WordTable.wt[1].Str);
										PrintStr("Write LocalIP OK");
										break;}
								case 4:{		//写mac
										WRiteMAC(WordTable.wt[1].Str);
										PrintStr("Write Mac OK");
										break;}
								case 5:{
										//显示所有配置数据
										DispConfig();
										break;}
								case 6:{		//写要连接的服务器端端口号
										WRiteServerPort(WordTable.wt[1].Str);
										PrintStr("Write ServerPort OK");
										break;}
								case 7:{
										WRiteGate(WordTable.wt[1].Str);
										PrintStr("Write GateIP OK");
										break;}
								case 8:{		
										break;}
								case 9:{
										DspTCPStat();
										break;}
							}
						}
						else
							PrintStr("Bad command!");
					}
				}
				else
				{
					//为数据
					if(ComBuf[0] == 0x01)
					{
						if(bConnect)
						{
							User_TCPSend(IndexOfClient,ComBuf+2,ComBuf[1]);
						}
					}
				}
				ComMatchFlag=0;
				State=StatInputCom;
				i=-1;
				break;
			}
			default:
			{
				//ShellEnd=1;
				PrintStr("System fatal error!");
			}
		}
	}
}


⌨️ 快捷键说明

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