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

📄 global.c

📁 51单片机上实现tcp/ip的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*********************************************************************
 *            Copright(c) 2004,张会福 湖南科技大学计算机学院 
 *                        All rights reserved.
 *
 *文件名称:    global.c
 *文件标识: 
 *摘    要: 定义全局变量,网络底层驱动程序,校验和计算,处理器相关设定
 *
 *当前版本: V1.0
 *作    者: 张会福
 *完成日期: 2004.4.10
 *
 *********************************************************************/

/*********************************************************************
 *                            公共变量定义
 *
 ********************************************************************/
//#include "uart.c"
#define  GLOBAL_GLOBALS
#include "net_cfg.h"


/****************************************************************/
uchar   Ping_Count;         //ping的次数,决定本地回显次数
uchar   Ping_IP_TTL=0;      //ping的主机的物理地址生存时间,单位分钟,为0表示IP地址没有解析
uchar   Gateway_IP_TTL=0 ;  //网关IP地址的物理地址生存时间,单位分钟
                            //=0表示还没有解析,<5分钟时需要更新
            
uchar   Udp_Count;
uchar   Msec=0;             //10毫秒
uchar   Sec=0;              //秒钟
uchar   Min=0;              //分钟
uchar   i=0;
uchar   bnry;               //读芯片RAM指针
uchar   curr;               //写芯片RAM指针
uchar   RtTime=20;          //重发时间
uchar   Tcp_Drop_Count=0;   //用于关闭tcp连接的计数
uint    FrameIndex=0;       //IP包的序列号
uint    ComRxdRead=0;       //串口接收读指针
uint    ComTxdRead=0;       //串口发送读指针
uint    ComRxdWrite=0;      //串口接收写指针
uint    ComTxdWrite=0;      //串口发送写指针

bit     ComTxdBufempty=0;   //串口发送缓冲区数据空的标志
bit     Tx_Buff_Sel=0;      //芯片的发送缓冲区选择
bit     BiSecond;           //两秒时,该标志置1
bit     Tcp_Timeout=0;      //TCP超时标志,定时器0中断中将该标志置位
bit     TcpConnected=0;     //TCP连接建立标志

uchar   code    MacID[6]=MY_MAC_ID;//将RTL8019的物理地址存储在程序空间中
uchar   code    HexTable[]={"0123456789ABCDEF"}; //为ascii->hex的转换表
xdata   uchar   Command_Buf[COMMAND_BUFF_SIZE];  //命令缓冲区
xdata   uchar   IpStr[16]; 
xdata   uchar   PortStr[5];
xdata   struct  Socket_Type TCP1024;

xdata   uchar   ComRxdBuf[COM_RXD_BUFF_SIZE];    //串口的接收缓冲区
xdata   uchar   ComTxdBuf[COM_TXD_BUFF_SIZE];    //串口的发送缓冲区

xdata   union   Netcard  RxdNetBuff;             //数据接收缓冲区
xdata   union   Netcard  TxdNetBuff;             //数据发送缓冲区
xdata   union   Netcard  Resend_Buff;

xdata   union   Ethernet_Address_Type My_MAC  ;      //本机的物理地址
xdata   union   Ethernet_Address_Type Gateway_MAC;   //网关的物理地址
xdata   union   Ethernet_Address_Type Ping_MAC;      //PING的物理地址

xdata   union   Ip_Address_Type My_Ip_Address ;      //本机IP地址
xdata   union   Ip_Address_Type Gateway_Ip_Address;  //网关IP地址
xdata   union   Ip_Address_Type Mask_Ip_Address;     //子网掩码
xdata   union   Ip_Address_Type Ping_Ip_Address;     //保存PING命令的目的主机的物理地址

union   u     RemotePort;
union   w     CrcTemp;
/**********************************************************************
**函数原型:    void   delay_ms(uint ms_number)
**入口参数:    ms_number: 延时的毫秒数
**出口参数:    无
**返 回 值:   无      
**说    明:   延时预定的时间,延时时间与特定的处理器有关
************************************************************************/
void Delay_MS(uint ms_number)
{
  uint  i;
  uint  j;
  for(j = 0;j < ms_number;j++)
  for(i = 0;i < 229;i++);
}

/**********************************************************************
**函数原型:   void  page(uchar pagenumber)
**入口参数:   uchar pagenumber: 要切换的页
**出口参数:   无
**返 回 值:  无      
**说    明:  选择页,可选择0,1,2三页,第四页ne000兼容芯片保留 
************************************************************************/
void page(uchar pagenumber)
{
  uchar data temp;
  temp=Reg00;      //command register
  //temp=temp&0x3f;
  temp=temp&0x3B ; //注意txp位不能要
  pagenumber=pagenumber <<6;
  temp=temp | pagenumber;
  Reg00=temp;
}

/**********************************************************************
**函数原型:   void SetMacID()
**入口参数:   无
**出口参数:   无
**返 回 值:  无            
**说    明:  设置芯片物理地址,物理地址已经存储在程序空间内 
************************************************************************/
void SetMacID()
{
  My_MAC.bytes[0] = MacID[0];  //取出物理地址,填充到
  My_MAC.bytes[1] = MacID[1];
  My_MAC.bytes[2] = MacID[2];
  My_MAC.bytes[3] = MacID[3];
  My_MAC.bytes[4] = MacID[4];
  My_MAC.bytes[5] = MacID[5];
  page(1);
  Reg01 = My_MAC.bytes[0];
  Reg02 = My_MAC.bytes[1];
  Reg03 = My_MAC.bytes[2];
  Reg04 = My_MAC.bytes[3];
  Reg05 = My_MAC.bytes[4];
  Reg06 = My_MAC.bytes[5];
  page(0);
}

/**********************************************************************
**函数原型:   void  Send_Packet(union Netcard *TxdNetBuff,uint length)
**入口参数:   union Netcard *TxdNetBuff    :指向发送缓冲区
**            uint length                  :发送数据包的长度
**出口参数:   无
**返 回 值:  无              
**说    明:  发送数据包,以太网底层驱动程序,所有的数据发送都要通过该程序
************************************************************************/
void Send_Packet(union Netcard *TxdNetBuff,uint length)
{
  uchar i;
  uint ii;
  page(0);                   //切换至第0页
  if(length<60)
      length=60;             //如果数据长度<60字节,设置长度为60字节
  for(i=0;i<3;i++)           //设置源物理地址
  {
      TxdNetBuff->EtherFrame.SourceMacId[i]=My_MAC.words[i];
  }
  Tx_Buff_Sel=!Tx_Buff_Sel;  //设置两个发缓区,提高发送效率
  if(Tx_Buff_Sel)
      Reg09=0x40 ;           //设置发送页地址
  else
      Reg09=0x46 ;           //设置发送页地址
  
  Reg08=0x00;                //read page address low
  Reg0b=length>>8;           //read count high
  Reg0a=length&0xff;         //read count low;
  Reg00=0x12;                //write dma, page0

  for(ii=4;ii<length+4;ii++)
  {
     Reg10=TxdNetBuff->bytes.bytebuf[ii];
  }
/***************************************/
//以下为终止DMA操作
  Reg0b=0x00; 
  Reg0a=0x00;
  Reg00=0x22;            //结束或放弃DMA操作
/***************************************/

  for(i=0;i<6;i++)       //最多重发6次
  {
      for(ii=0;ii<1000;ii++)
      {//检查CR寄存器的txp位是否为低,为1说明正在发送,为0说明发完或出错放弃
          if((Reg00&0x04)==0)  
              { break; }
      }
      if((Reg04&0x01)!=0)//表示发送成功,判断发送状态寄存器TSR,决定是否出错
          {break;};
      Reg00=0x3e;
  }

  Reg07=0xff;
  if(Tx_Buff_Sel)
  {
      Reg04=0x40;   //txd packet start;
  }
  else
  {
      Reg04=0x46;   //txd packet start;
  }
  Reg06=length>>8;  //high byte counter
  Reg05=length&0xff;//low byte counter
  Reg07=0xff;
  Reg00=0x3e;       //to sendpacket;

}

/**********************************************************************
**函数原型:   bit        Rec_NewPacket()
**入口参数:   无
**出口参数:   无
**返 回 值:  0          没有新数据包
**            1          接收到新数据包
**说    明:  查询是否有新数据包并接收进缓冲区
************************************************************************/
bit Rec_NewPacket()
{
  uchar i;
  uint ii;

  page(0);
  bnry=Reg03;        //bnry page have read 读页指针
  page(1);
  curr=Reg07;        //curr writepoint 8019写页指针
  page(0);
  if((curr==0)) return(0);    //读的过程出错
  bnry=bnry++;
  if(bnry>0x7f) bnry=0x4c;
  if(bnry!=curr)    //此时表示有新的数据包在缓冲区里
  {                 //在任何操作都最好返回page0
     page(0);
     //=======================================
     Reg09=bnry;    //读页地址的高字节
     Reg08=0x00;    //读页地址的低字节
     Reg0b=0x00;    //读取字节计数高字节
     Reg0a=18;      //读取字节计数高字节
     Reg00=0x0a;    //启动Remote DMA读操作
     
     for(i=0;i<18;i++)//读取一包的前18个字节:4字节的8019头部,6字节目的地址,6字节原地址,2字节协议
     {
         RxdNetBuff.bytes.bytebuf[i]=Reg10;
     }
 //=======================================中止DMA操作
     Reg0b=0x00;    //
     Reg0a=0x00;    //
     Reg00=0x22;    //结束或放弃DMA操作
 //=======================================
     i=RxdNetBuff.bytes.bytebuf[3];
     RxdNetBuff.bytes.bytebuf[3]=RxdNetBuff.bytes.bytebuf[2];
     RxdNetBuff.bytes.bytebuf[2]=i; //将长度字段的高低字节掉转
     RxdNetBuff.EtherFrame.length=RxdNetBuff.EtherFrame.length-4;//去掉4个字节的CRC

//=====================以上各步操作表示读入的数据包有效

     if(((RxdNetBuff.bytes.bytebuf[0]&0x01)==0)||(RxdNetBuff.bytes.bytebuf[1]>0x7f)
       ||(RxdNetBuff.bytes.bytebuf[1]<0x4c)||(RxdNetBuff.bytes.bytebuf[2]>0x06))
     {//接收状态错误或下一数据包的起始页地址错误或接收的数据包长度>1500字节
         page(1);
         curr=Reg07;     //page1
         page(0);        //切换回page0
         bnry = curr -1;
         if(bnry < 0x4c) 
             bnry =0x7f;
         Reg03=bnry;     //write to bnry
       
         Reg07=0xff;
         return(0);
     }//接收状态错误或下一数据包的起始页地址错误或接收的数据包长度>1500字节
//=============================================
            
     else//表示数据包是完好的.读取剩下的数据
     {
         if((RxdNetBuff.EtherFrame.NextProtocal==0x0800)||(RxdNetBuff.EtherFrame.NextProtocal==0x0806))
         { //协议为IP或ARP才接收
             Reg09=bnry;                   //read page address high
             Reg08=4;                      //read page address low
             Reg0b=RxdNetBuff.EtherFrame.length>>8;  //read count high
             Reg0a=RxdNetBuff.EtherFrame.length&0xff;//read count low;
             Reg00=0x0a;                             //read dma
             for(ii=4;ii<RxdNetBuff.EtherFrame.length+4;ii++)
                {RxdNetBuff.bytes.bytebuf[ii]=Reg10;}
             //================终止DMA操作
             Reg0b=0x00;            //read count high   
             Reg0a=0x00;            //read count low;
             Reg00=0x22;            //结束或放弃DMA
             //============================
         }
         //=========================================
         bnry=RxdNetBuff.bytes.bytebuf[1]-1;
         if(bnry<0x4c)
             {bnry=0x7f;}
         Reg03=bnry;      //write to bnry
         Reg07=0xff;
         if((TCP1024.State==TCP_STATE_ESTABLISHED)&&(RxdNetBuff.IpFrame.NextProtocal==6))
             if(RxdNetBuff.IpFrame.SourceIp[0]!=TxdNetBuff.IpFrame.DestId[0])
                 if(RxdNetBuff.IpFrame.SourceIp[1]!=TxdNetBuff.IpFrame.DestId[1])//目标IP地址是否本机
                     return(0);
         return(1);   //have new packet
     }//表示数据包是完好的.读取剩下的数据
  }//if(bnry!=curr)//此时表示有新的数据包在缓冲区里
  return(0);
}

/**********************************************************************
**函数原型:   void     InitNic()
**入口参数:   无
**出口参数:   无
**返 回 值:   无              
**说    明:   对芯片的工作寄存器进行设置,各个寄存器的用法可参考文档和
**            络芯片的数据手册
************************************************************************/
void InitNic()
{
  Delay_MS(10);
/**********************************************************************

1.Reg00命令寄存器: CR,命令寄存器,地址偏移量00H,为一个字节
  位:  7   6   5   4   3   2   1   0 
名字: PS1 PS0 RD2 RD1 RD0 TXP STA STP 
//============================================
2.
RD2,RD1,RD0: 这3个位代表要执行的功能。
 0   0   1 : 读网卡内存
 0   1   0 : 写网卡内存
 0   1   1 : 发送网卡数据包
 1   *   * : 完成或结束DMA的读写操作
//============================================
3.TXP位置1时发送数据包,发完自动清零
//============================================
4.
STA,STP:    这两个位用来启动命令或停止命令
 1   0         启动命令
 0   1         停止命令

⌨️ 快捷键说明

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