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

📄 global.c

📁 51单片机上实现tcp/ip的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
//============================================
********************************************************/
  Reg00=0x21;   //使芯片处于停止模式,这时进行寄存器设置

  Delay_MS(10); //延时10毫秒,确保芯片进入停止模式
  page(0);
  Reg0a=0x00;   //清rbcr0
  Reg0b=0x00;   //清rbcr1
  Reg0c= 0xe0;  //RCR,监视模式,不接收数据包
  Reg0d= 0xe2;  //TCR,loop back模式

  Reg01=0x4c;
  Reg02=0x80;
  Reg03=0x4c;
  Reg04=0x40;  //TPSR,发送起始页寄存器
  Reg07=0xff;  //清除所有中断标志位,中断状态寄存器
  Reg0f=0x00;  //中断屏蔽寄存器清0,禁止中断

  Reg0e=0xc8;  // 数据配置寄存器,8位dma方式
  page(1);
  Reg07=0x4d;
  Reg08=0x00;
  Reg09=0x00;
  Reg0a=0x00;
  Reg0b=0x00;
  Reg0c=0x00;
  Reg0d=0x00;
  Reg0e=0x00;
  Reg0f=0x00;
  Reg00=0x22;  //这时让芯片开始工作

  SetMacID();  //将芯片物理地址写入到MAR寄存器

  page(0);
  Reg0c=0xcc;  //将芯片设置成正常模式,跟外部网络连接
  Reg0d=0xe0;
  Reg00=0x22;  //启动芯片开始工作
  Reg07=0xff;  //清除所有中断标志位

}

/**********************************************************************
**函数原型:   void  Timer0_Init( )
**入口参数:   无
**出口参数:   无
**返 回 值:  无              
**说    明:  初始化定时器0
************************************************************************/
void Timer0_Init()
{
  tmod=tmod&0xf0;
  tmod=tmod|0x01;
  th0 = 0;
  tl0 = 0;
  tr0 = 1;
}

/**********************************************************************
**函数原型:   void     Serial_Init( )
**入口参数:   无
**出口参数:   无
**返 回 值:  无              
**说    明:  初始化串口
************************************************************************/
void Serial_Init()
{
//====设置波特率===================
  tmod = tmod & 0x0f;
  tmod = tmod | 0x20;
  th1  = 0xfa;
  tr1  = 1;
  pcon = pcon | 0x80;     
//=======================
//工作方式为8位数据
  sm0 = 0; 
  sm1 = 1; 
  sm2 = 0;
  tr1 = 1;          
//==========================
  ren = 1;               //允许接收
  ti  = 1;
}

/**********************************************************************
**函数原型:   void     Interrupt_Init(void)
**入口参数:   无
**出口参数:   无
**返 回 值:   无              
**说    明:   初始化中断
************************************************************************/
void Interrupt_Init(void)
{
  //定时器0允许中断
  et0 = 1; 
  ea  = 1; 
//======================    
  et1 = 0;    //禁止定时器1中断
//======================
  ps0 = 1;        //设置串行口高优先级
//==============================
  es0 = 1;
  ea  = 1;    //允许串口中断
}

/**********************************************************************
**函数原型:   unsigned int CheckSum(unsigned int xdata *check,unsigned int length)
**入口参数:   check    :    被校验数据起始地址
              length   :    被校验数据长度,单位字
**出口参数:   无
**返 回 值:   ~((sum)&0xffff))               
**说    明:   计算校验和 
************************************************************************/
unsigned int CheckSum(unsigned int xdata *check,unsigned int length)
{
  unsigned long sum=0;
  unsigned int i;

  for (i=0;i<(length)/2;i++)
  {
      sum += *check++;
  }
  if(length&0x01)                         //长度为奇数个时,要进行该操作
  {
      sum = sum + ((*check)&0xff00);
  }
  sum = (sum&0xffff) + ((sum>>16)&0xffff);//高16位和低16位相加
  if(sum & 0xffff0000)
  {//表示有进位
      sum++;
  }
  return ( (unsigned int)(~((sum)&0xffff))  );
}

/**********************************************************************
**函数原型:   unsigned char  VerifyIpHeadCrc()
**入口参数:   无
**出口参数:   无
**返 回 值:  0   :    校验错误
**            1   :    校验正确       
**说    明:  对IP头进行校验 
************************************************************************/
unsigned char  VerifyIpHeadCrc()
{
  unsigned int crc;

  crc = CheckSum(&RxdNetBuff.IpPacket.IpPacket[0],(RxdNetBuff.IpFrame.VerandIphLen&0x0f)*4);
        //1位代表1字节
  if(crc == 0)
  {
      return (1);
  }
  return(0);
}

/**********************************************************************
**函数原型:   unsigned char  VerifyTcpCrc()
**入口参数:   无
**出口参数:   无
**返 回 值:   0   : 校验错误
**            1   : 校验正确       
**说    明:   对TCP头进行校验 
************************************************************************/
unsigned char  VerifyTcpCrc()
{
  unsigned int crc;

  RxdNetBuff.IpFrame.ttl=0;
  RxdNetBuff.IpFrame.Crc=RxdNetBuff.IpFrame.TotalLen-(RxdNetBuff.IpFrame.VerandIphLen&0x0f)*4;
  crc = CheckSum(&RxdNetBuff.IpPacket.IpPacket[4],RxdNetBuff.IpFrame.Crc+12);
  if(crc == 0)
  {
      return (1);
  }
  return(0);
}

/**********************************************************************
**函数原型:   void     CreateIpHeadCrc()
**入口参数:   无
**出口参数:   无
**返 回 值:   crc :  16位的校验和        
**说    明:   产生IP首部的校验和 
************************************************************************/
uint  CreateIpHeadCrc()
{
  uchar i;

  CrcTemp.dwords = 0;
  for(i=9;i<19;i++)                              //IP首部共20字节
  {
      CrcTemp.dwords = CrcTemp.dwords + TxdNetBuff.words.wordbuf[i];
  }
  while(CrcTemp.words.high>0) 
  {
      CrcTemp.dwords = (ulong)(CrcTemp.words.high + CrcTemp.words.low);
  }
  CrcTemp.words.low = 0xffff - CrcTemp.words.low;  //取反
  return(CrcTemp.words.low);
}

/**********************************************************************
**函数原型:   void     CreateIcmpCrc( )
**入口参数:   无
**出口参数:   无
**返 回 值:  crc :  16位的校验和        
**说    明:  产生ICMP数据段的校验和 
************************************************************************/
uint  CreateIcmpCrc()//
{
  uchar i;

  CrcTemp.dwords=0;
  for(i=19;i<39;i++)                //用于查询的ICMP报文共40字节
  {
      CrcTemp.dwords = CrcTemp.dwords + TxdNetBuff.words.wordbuf[i];
  }
  while(CrcTemp.words.high>0) 
  {
      CrcTemp.dwords = (ulong)(CrcTemp.words.high+CrcTemp.words.low);
  }
  CrcTemp.words.low = 0xffff - CrcTemp.words.low;
  return(CrcTemp.words.low);
}

/**********************************************************************
**函数原型:   unsigned char  VerifyUdpCrc()
**入口参数:   无
**出口参数:   无
**返 回 值:  0   :  校验错误
**            1   :    校验正确       
**说    明:  对UDP头进行校验 
************************************************************************/
unsigned char  VerifyUdpCrc()
{
  unsigned int crc;

  RxdNetBuff.IpFrame.ttl = 0;
  RxdNetBuff.IpFrame.Crc = RxdNetBuff.IpFrame.TotalLen - (RxdNetBuff.IpFrame.VerandIphLen&0x0f)*4;
  crc = CheckSum(&RxdNetBuff.IpPacket.IpPacket[4],RxdNetBuff.IpFrame.Crc+12);
  if(crc==0)
  {
     return (1);
  }
  return(0);
}

/**********************************************************************
**函数原型:    void     CreateTcpCrc()
**入口参数:    无
**出口参数:    无
**返 回 值:    crc :  16位的校验和       
**说    明:    产生TCP数据段的校验和 
************************************************************************/
uint CreateTcpCrc()
{
  uint crc;

  crc = CheckSum(&TxdNetBuff.IpPacket.IpPacket[4],TxdNetBuff.IpFrame.Crc+12);
  return (crc);
}

/**********************************************************************
**函数原型:   void        Copy_To_Resend_Buff( )
**入口参数:   无
**出口参数:   无
**返 回 值:   无
**说    明:   将tcp包复制到重发缓冲区
************************************************************************/
void Copy_To_Resend_Buff()
{
  uint ii;
  uchar xdata *txd = &TxdNetBuff;
  uchar xdata *rt;
 
  if(Resend_Buff.ResendFrame.RtStatus==0)
  {
      rt = &Resend_Buff.bytes.bytebuf;
      for(ii=0;ii<Resend_Buff.ResendFrame.length+4;ii++)
      {
         (*rt)=(*txd);
          rt++;
          txd++;
      }
      Resend_Buff.ResendFrame.RtStatus = 1;        //状态1缓冲区数据有效,准备重发数据
      Resend_Buff.ResendFrame.timeout  = RtTime;    //重发次数
  }
}

/**********************************************************************
**函数原型:   void         Create_Ip_Frame(uint length,uint IPH,uint IPL,uchar NextProtocal)
**入口参数:   length       : TCP包的长度
**            IPH          : IP地址的高16位
**            IPL          : IP地址的低16位
**            NextProtocal : 下一层协议,例如TCP协议或UDP协议
**出口参数:   无
**返 回 值:  无
**说    明:  产生一个ip头,并启动发送
************************************************************************/
void Create_Ip_Frame(uint length,uint IPH,uint IPL,uchar NextProtocal)
{ 
    TxdNetBuff.IpFrame.VerandIphLen=0x45;            //IP版本和头长度
    TxdNetBuff.IpFrame.ttl=128;                      //TTL
    TxdNetBuff.IpFrame.ServerType=0x00;              //服务类型为0
    TxdNetBuff.IpFrame.Crc=0;
    TxdNetBuff.IpFrame.FrameIndex=FrameIndex++;
    TxdNetBuff.IpFrame.Segment=0x4000;             //无分段
    length=length+20;
    TxdNetBuff.IpFrame.TotalLen=length;            //IP数据报总长度
    TxdNetBuff.IpFrame.NextProtocal=NextProtocal;  //下层协议
    TxdNetBuff.IpFrame.DestId[0]=IPH;              //填充目的IP地址
    TxdNetBuff.IpFrame.DestId[1]=IPL;
    TxdNetBuff.IpFrame.SourceIp[0]=My_Ip_Address.words[0];    //填充源IP地址
    TxdNetBuff.IpFrame.SourceIp[1]=My_Ip_Address.words[1];
    TxdNetBuff.IpFrame.Crc=CreateIpHeadCrc();//产生IP头的检验和
    length=length+14;//6+6+2                 //加以太网协议的14字节数据,得到发送数据的长度
    Send_Packet(&TxdNetBuff,length);
    TxdNetBuff.EtherFrame.length=length;
    if(NextProtocal==6)                      //如果协议为TCP,则要考虑重发问题 
        if(TxdNetBuff.TcpFrame.control&(TCP_SYN|TCP_FIN|TCP_PSH|TCP_URG))
            {Copy_To_Resend_Buff();}         //复制TCP数据到重发缓冲区
}

/**********************************************************************
**函数原型:   union Ip_Address_Type *IP_Str2Hex(unsigned char *Str)
**入口参数:   unsigned char *Str    :指向字符串的指针
**出口参数:        &(ip.bytes[0])   :指向IP联合类型的指针
**返 回 值:   IP联合类型的首地址

⌨️ 快捷键说明

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