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

📄 89c52ctr.c

📁 使用51单片机实现TCP/IP协议,模块化编程
💻 C
字号:
#include "GloblDef.h"
//#include "RTL8019.h"
#include  "AT89X52.h"
#include  "math.h"
extern byte MemAllocation(word size);
extern void FreePage(byte page);
extern byte xdata *MemPageToPoint(byte page);
extern byte WriteQueue(byte page,stuct queue xdata *pQueue);

byte xdata LocalMACAddr[6]={0x52,0x68,0x3a,0x1c,0x2b,0x56};
struct Queue xdata QueueNetPacketIn;
byte StartPageOfPacket;




/*接收头文件信息*/
struct RTLReceiveHeader
{
   byte ReceiveStatus;
	byte NextPacketStartPage;
	byte PacketSizeLow;
	byte PacketSizeHigh;
}Head;   
byte xdata Head[4];
byte LastSendStartPage;
sbit RTLResetPin = RTL_RESET_PIN;
                    

//读rtl寄存器端口
byte ReadReg(word port)
{
    byte xdata *p;
	 p=(byte xdata *)port;   //强制类型转换,为什么不是p=byte xdata port;
     
	 return *p;
}


void WriteReg(word port,byte value)
{
    byte xdata *p;
	 p=(byte xdata *)port;
	 *p=value;
}


//chose page
void RTLPage(byte Index)
{
         //set cr,cr_txp 7--6bit0 (1,resend)
   byte temp;
	temp=ReadReg(CR);
	temp=temp&0x3b;    //set 7-6 and 2 bit(TXP) to 0
   Index=Index<<6;      //把页码左移到ps1,ps0 实现选择 ^^;
	temp =temp | Index;
	WriteReg(CR,temp);
}


              //PRA为物理地址//
void RTLInitial()
{
     byte temp;
     int   i;

     /*硬件重启*/
	  RTLResetPin=1;
	  for(i=0;i<255;i++);               //延迟时间让高电平持续1us以上
	  RTLResetPin=0;                    //再给个低电平,从而复位RTL
	  /*若硬件重启延迟很大,rtl自我初始化*/
     for(i=0;i<DELAY_AFTER_HARDWARE_RESET;i++);   //复位过程需要一些时间推荐100ms

    /*写重启口*/
      temp=ReadReg(RESET_PORT);
	  WriteReg(RESET_PORT,temp);//软件复位通过写ResetPort达到复位,也就是给18~1F之间的任意一个寄存器写入任意一个数,就使得以太网口复位

	/*初始化rtl寄存器*/
     WriteReg(CR,(CR_PAGE0 | CR_ABORT_COMPLETE_DMA | CR_STOP_COMMAND));
	                    //选择page0,stop command

     WriteReg(PSTART_WPAGE0,RECEIVE_START_PAGE);
	  WriteReg(PSTOP_WPAGE0, RECEIVE_STOP_PAGE);
	  WriteReg(BNRY_WPAGE0, RECEIVE_START_PAGE);
	  WriteReg(TPSR_WPAGE0, SEND_START_PAGE0);//Pstart,Pstop,bnry,tpsr
	       
	  WriteReg(RCR_WPAGE0, 0XCE);
	  WriteReg(TCR_WPAGE0, 0XE0);
	  WriteReg(DCR_WPAGE0, 0XC8);      //RCR,TCR,DCR在头文件里定义

	  WriteReg(IMR_WPAGE0,0);         //RTL接收中断使能
	  WriteReg(ISR_WPAGE0, 0XFF);     //写ff清除所有中断标志

	  RTLPage(1);

	  WriteReg(CURR_WPAGE,RECEIVE_START_PAGE+1);
	                                   //MAR0
     WriteReg(0x08,0x00);
	  WriteReg(0x09,0x41);
	  WriteReg(0x0a,0x00);
	  WriteReg(0x0b,0x80);
     WriteReg(0x0c,0x00);
     WriteReg(0x0d,0x00);
     WriteReg(0x0e,0x00);
	  WriteReg(0x0f,0x00);
                                //设置物理地址
	  WriteReg(PRA0_WPAGE1,LocalMACAddr[0]);
	  WriteReg(PRA1_WPAGE1,LocalMACAddr[1]);
	  WriteReg(PRA2_WPAGE1,LocalMACAddr[2]);
	  WriteReg(PRA3_WPAGE1,LocalMACAddr[3]);
	  WriteReg(PRA4_WPAGE1,LocalMACAddr[4]);
	  WriteReg(PRA5_WPAGE1,LocalMACAddr[5]);
	                            //传输起始页
     LastSendStartPage=SEND_START_PAGE0;
	  StartPageOfPacket=RECEIVE_START_PAGE+1;
	                          //初始化结束
     WriteReg(CR,(CR_PAGE0|CR_ABORT_COMPLETE_DMA|CR_STOP_COMMAND));
}



//写buffer到rtl ram
void RTLWriteRam(word address,word size,byte xdata *buff)
{
     word i;
	  byte PrePage; //store page
	  Prepage=ReadReg(CR);
	  RTLPage(0);
	  WriteReg(RSARH_WPAGE0,(byte)((address>>8)&0x00ff));
	  WriteReg(RSARL_WPAGE0,(byte)address);
	  WriteReg(RBCRH_WPAGE0,(byte)((size>>8)&0x00ff));
	  WriteReg(RBCRL_WPAGE0,(byte)size);
	  WriteReg(CR,(0x00|CR_REMOTE_WRITE|CR_START_COMMAND));
	  for(i=0;i<size;i++)
	  {
	      WriteReg(REMOTE_DMA_PORT,buff[i]);
	  }
	                   //完成DMA
	 WriteReg(RBCRH_WPAGE0,0);
	 WriteReg(RBCRL_WPAGE0,0);
	 WriteReg(CR,((PrePage&0xc0)|CR_ABORT_COMPLETE|CR_STARAT_COMMAND));
}
                    

                    //读rtl ram 数据到 buffer
void  RTLReadRam(word address,word size,byte xdata *buff)
{
      word i;
		byte PrePage;

		PrePage=ReadReg(CR);
		RTLPage(0);
	  WriteReg(RSARH_WPAGE0,(byte)((address>>8)&0x00ff));
	  WriteReg(RSARL_WPAGE0,(byte)address);
	  WriteReg(RBCRH_WPAGE0,(byte)((size>>8)&0x00ff));
	  WriteReg(RBCRL_WPAGE0,(byte)size);
	  WriteReg(CR,(0x00|CR_REMOTE_READ|CR_START_COMMAND));
	  for (i=0;i<size;i++)
	  {
	       buff[i]=ReadReg(REMOTE_DMA_PORT);
	  }
	             //完成dma
	 WriteReg(RBCRH_WPAGE0,0);
	 WriteReg(RBCRL_WPAGE0,0);
	 WriteReg(CR,((PrePage&0xc0)|CR_ABORT_COMPLETE|CR_STARAT_COMMAND));
}


byte RTLSendPacket(byte xdata *buffer,word size)
{
     byte StartPage;
	  byte PrePage;
	  PrePage=ReadReg(CR);
                              //检测包大小
    if(size<MIN_PACKET_SIZE||size>MAX_PACKET_SIZE)
	    return FALSE;
		                         //写包到ram
    if(LastSendStartPage==SEND_START_PAGE0)
	 {
	 StartPage=SEND_START_PAGE1;
    LastSendStartPage==SEND_START_PAGE1;
	 }
	 else
	 {
	    StartPage==SEND_START_PAGE0;
       LastSendStartPage==SEND_START_PAGE0;
	 }
    RTLWriteRam(((word)StartPage)<<8,size,buffer);
	                   //等待上一次传输结束
   while ((ReadReg(CR)&CR_TXP)==CR_TXP);
	           //写传输起始页和大小
   RTLPage(0);
	WriteReg(TPSR_WPAGE0,StartPage);   //TPSR
	WriteReg(TBCRL_WPAGE0,(byte)size);   //LOW
	WriteReg(TBCRH_WPAGE0,(byte)((size>>8)&0XFF));   //HIGH
	WriteReg(CR,((PrePage&0xc0)|CR_ABORT_COMPLETE|CR_TXP|CR_START_COMMAND);
	return TRUE;
}



void RTLReceivePacket()
{
     byte curr,bnry;
	  word adrress;
	  word PacketSize;
	  byte MemPage;
	  struct MemHeader xdata *pMemHead;

	  RTLPage(1);
	  curr=ReadReg(CURR_RPAGE1);
	  RTLPage(0);
                         //在接收缓存中读所有包 
	  while(TRUE)
	  {            //检测起始页是否未知吃错误
	       if(StartPageOfPacket>=RECEIVE_STOP_PAGE||StartPageOfPacket<RECEIVE_START_PAGE)
			 {         //用curr作为startpageofpacket
			    StartPageOfPacket=curr;
				 break;
			 }
			           //检测是否有包读到
           if(StartPageOfPacket==curr)
			    break;
				 //读一个包

				 //读包头信息
			address=((wodr)StartPageOfPacket)<<8;
			RTLReadRam(address,4,Head);

			    //校验rsr
			if(Head[0]&RSR_RECEIVE_NO_ERRO)
			 {
			                //好包
								 //得到mac校验和
               PacketSize=((word)Head[3])*256+Head[2]-4;
					         //分配buffer,读包到buffer
				MemPage=MemAllocation(PacketSize);
				if(MemPage!=PAGE_NOT_FOUND)
				{
					  pMemHead=(struct MemHeader xdata*)MemPageToPoint(MemPage);
                 pMemHead->StartPos=(byte xdata *)pMemHead+sizeof(struct MemHeader);
					  pMemHead->StopPos=pMemhead->StopPos+PacketSize;
					                 //停止pos
                      address+=4;
                      if(StartPageOfPacket>Head[1]&&Head[1]!=RECEIVE_START_PAGE)
                       {
                         RTLReadRam(address,(((word)RECEIVE_STOP_PAGE)<<8)-address,pMemHead->StartPos);
                                          //read rtl
                         RTLReadRam(((word)RECEIVVE_START_PAGE)<<8,PacketSize-((((word)RECEIVE_STOP_PAGE)
                              <<8)-address),pMemHead->StartPos+((((word)RECEIVE_STOP_PAGE)<<8)-address));
                       }
                      else
                       {
                         RTLReadRam(address,PacketSize,pMemHead->StartPos);//read rtl 
                       }
                      if(WriteQueue(MemPage,&QueueNetPacketIn)==PAGE_NOT_FOUND)//写到队列
                       {    //队列满
                         #ifdef DEBUG
                         printf("\n----queue full----");
                         #endif
                         FreePage(MemPage);
                         break;
                       }
				}
                else
                {     //mem over
                   #ifdef DEBUG
                   printf("\n----queue over----");
                   #endif
						 break;
                }
			 }
			                  //得到下一包的起始页
			 StartPageOfPacket=Head[1];
	  }
	                        //重置bnry
     bnry=StartPageOfPacket-1;
	  if(bnry<RECEIVE_START_PAGE)
	     bnry=RECEIVE_STOP_PAGE-1;
		  WriteReg(BNRY_WPAGE0,bnry);
}


void Start8019()
{
     WriteReg(CR,CR_ABORT_COMPLETE_DMA|CR_START_COMMAND);
}

void Stop8019()
{
    WriteReg(CR,CR_ABORT_COMPLETE_DMA|CR_STOP_COMMAND);
}



void main(void)
{
     byte temp;
	  word port=1001;
	  LocalMACAddr[0]=0x52;
	  LocalMACAddr[1]=0x68;
	  LocalMACAddr[2]=0x3a;
	  LocalMACAddr[3]=0x1c;
	  LocalMACAddr[4]=0x2b;
	  LocalMACAddr[5]=0x56;
	  LocalIPAddress=0x0a8020d; //本地ip192.168.2.14
	  ServerIPAddress=0x0a8020e;//目的ip192.168.2.13

	                          //初始化
     SerialInitial();
	  MemInitial();
	  NetInInitial();
	  
	  RTLInitial();
	  Start8019();
	  InterruptInitial();


	                          //建立一个arp包
     p[0]=0xff;
	  p[1]=0xff;
	  p[2]=0xff;
	  p[3]=0xff;
	  p[4]=0xff;
	  p[5]=0xff;
	  p[6]=0x52;
	  p[7]=0x54;
	  p[8]=0x4c;
	  p[9]=0x30;
	  p[10]=0x2e;
	  p[11]=0x2f;
	  p[12]=0x08;
	  p[13]=0x06;
	  p[14]=0x00;
	  p[15]=0x01;
	  p[16]=0x08;
	  p[17]=0x00;
	  p[18]=0x06;
	  p[19]=0x04;
	  p[20]=0x00;
	  p[21]=0x01;
	                  //发送arp包
	  RTLSendPacket(p,60);
	  while(1);

	#ifdef DEBUG
	    printf("\n----bigine-----");
	#endif
	                    //处理
  TCPBind(port);
  if(TCPConnect(ServerIPAddress,1001)==TRUE)
  {
     while(UserFunc());
  }
                      //延迟
  for(temp;temp<255;temp++);
  #ifdef DEBUG
        printf("\n run over!");
	#endif
	                     //存储
   Stop8019();
	while(1);
}

⌨️ 快捷键说明

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