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

📄 main.c

📁 这是一个用单片机控制网卡传输的程序,集成了TCP/IP协议,使用硬件为89C51+RTL8019,另外传输另一端是计算机串口,可以方便的实现数据验证
💻 C
📖 第 1 页 / 共 4 页
字号:
//************************ 主程序**********************
//****************************************************
///////////////////////include files//////////////////////////////////////
#include <tcpip.h>
#include <stdio.h>
#include<reg51.h>
//IO操作使能与不使能定义
#define    IO_Y    p2_7 = 1;
#define    IO_N    p2_7 = 0;

sbit p2_7=P2^7;

////////////////////函数/////////////////////////////////////////
//extern unsigned char idata sec;//定时秒的个数,由用户主程序计算。
////////////////////File//////////////////////////////////
//NetCard8019as.c
///////////////////////////////////////////////////////////
 xdata union     netcard rxdnet;
 xdata union     netcard txdnet;
 xdata union     netcard txdnetbak;
 xdata union     netcard retransmit_buffer[rt_size];//最多5块重发缓冲区
 xdata union     ip_address_type my_ip_address; //本机的ip地址
 xdata union     ip_address_type gateway_ip_address;//网关的ip地址
 xdata union     ip_address_type temp_ip_address; //临时变量
 xdata union    ip_address_type mask_ip_address;//子网掩码
 xdata union     ip_address_type ping_ip_address;//用于ping命令
 xdata union    ethernet_address_type my_ethernet_address;  //本机的以太网地址
 xdata union    ethernet_address_type gateway_ethernet_address; //网关的以太网地址
 xdata union     ethernet_address_type ping_ethernet_address;//用来ping的以太网地址
 bit     txd_buffer_select;

//8019as基地址指针
char xdata * code R8019as_regbase    = 0x00300;

//8019as的物理地址
unsigned char code NetCardNode[6] = {0x52,0x54,0xAB,0x35,0x48,0x8A};//me
unsigned char code Myipaddr[4]={0x0a,0x0a,0x96,0xc2};//0x0A0A96C2   //202.198.150.194
unsigned char code MyNetgate[4]={0x0a,0x0a,0x96,0xfe};//0x0A0A96FE   //10.10.155.254
unsigned char code MyMaskip[4]={0xff,0xff,0xff,0x00);//0xFFFFFF00   //255.255.255.0

unsigned char idata  next_page;
unsigned char  bnry;
unsigned char  curr;

union    w    crctemp;
union     v     port;
union     u     rxdword;
#define rt_size 5
xdata     union     netcard rxdnet;//netcard包括各种协议报头数据
xdata     union     netcard txdnet;
xdata     union     netcard txdnetbak;    //???"txdnetbak用来做什么的"???
xdata     union     netcard retransmit_buffer[rt_size];//最多5块重发缓冲区
xdata     union     ip_address_type my_ip_address; //本机的ip地址
xdata     union     ip_address_type gateway_ip_address;//网关的ip地址
xdata     union     ip_address_type temp_ip_address; //临时变量
xdata     union    ip_address_type mask_ip_address;//子网掩码
xdata     union     ip_address_type ping_ip_address;//用于ping命令
xdata    union    ethernet_address_type my_ethernet_address;  //本机的以太网地址
xdata    union    ethernet_address_type gateway_ethernet_address; //网关的以太网地址
xdata    union     ethernet_address_type ping_ethernet_address;//用来ping的以太网地址
bit     txd_buffer_select    = 0;        //??"这三个位变量如何对应到硬件上"??
unsigned int    idata    frameindex=0;//IP包的序列号
unsigned char             rttime=5;//重发时间
unsigned char    idata     ping_ip_address_ttl=0;
unsigned char     idata     ping_count;//ping的次数
unsigned char     idata     udp_count;
unsigned char     idata     gateway_ip_address_ttl=0 ; //网关的ip地址的以太网地址生存时间 单位分钟
                                       //=0表示还没有解析
                                       //  <5分钟时需要刷新
                                       //  最大25分钟


///////////////////////////函数体///////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//1//
unsigned int    createipheadcrc()
{
    unsigned char i;
     crctemp.dwords = 0;
    for(i = 9; i < 19; i++)
    {
         crctemp.dwords = crctemp.dwords+txdnet.words.wordbuf[i];
    }
    while(crctemp.words.high > 0)
     {
        crctemp.dwords = (unsigned long)(crctemp.words.high + crctemp.words.low);
    }
    crctemp.words.low = 0xffff - crctemp.words.low;
    return(crctemp.words.low);
}

//2//
unsigned int checksum(unsigned int * 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)) );
}

//3//
unsigned char    verifyipheadcrc()//对ip头进行校验,错误返回0,正确返回1
{
    unsigned int crc;
    crc = checksum( &rxdnet.ippacket.ippacket[0], (rxdnet.ipframe.verandihl&0x0f)*4 );
    if(crc == 0)
     {
         return (1);
    }
     return(0);
}

/*//4//
unsigned char  verifytcpcrc()//对tcp头进行校验,错误返回0,正确返回1
{
    unsigned int crc;
    rxdnet.ipframe.ttl = 0;
     rxdnet.ipframe.crc = rxdnet.ipframe.totallength - ( rxdnet.ipframe.verandihl&0x0f )*4;
     crc = checksum(&rxdnet.ippacket.ippacket[4], rxdnet.ipframe.crc+12);
    if(crc == 0)
    {
        return (1);
    }
    return(0);
}
*/
//5//
unsigned int  createicmpcrc()
{
    unsigned char i;
     crctemp.dwords = 0;
    for( i = 19; i<39; i++)
    {
         crctemp.dwords=crctemp.dwords+txdnet.words.wordbuf[i];
    }
    while(crctemp.words.high>0)
    {
        crctemp.dwords = (unsigned long)(crctemp.words.high+crctemp.words.low);
    }
    crctemp.words.low = 0xffff-crctemp.words.low;
    return(crctemp.words.low);
}

/*//6//
unsigned int createtcpcrc()
{
    unsigned int crc;
    crc = checksum( &txdnet.ippacket.ippacket[4], txdnet.ipframe.crc + 12 );
    return (crc);
}
*/
//7//
void arp_answer()
{
    unsigned char i;
       if (rxdnet.arpframe.destip[0] == my_ip_address.words[0])
    {
           if (rxdnet.arpframe.destip[1] == my_ip_address.words[1])
           {//表示是向我这个ip地址的请求
               for(i = 16; i < 64; i++)
               {//复制arp到发送缓冲区
                   txdnet.bytes.bytebuf[i]=rxdnet.bytes.bytebuf[i];
               }
               for(i = 0; i < 3; i++)
               {//复制对方网卡地址或网关地址
                txdnet.etherframe.destnodeid[i] = rxdnet.etherframe.sourcenodeid[i];
                txdnet.arpframe.sourcenodeid[i] = txdnet.etherframe.sourcenodeid[i];
                txdnet.arpframe.destnodeid[i]   = rxdnet.arpframe.sourcenodeid[i];
               }
            for(i=0;i<2;i++)
            {
                txdnet.arpframe.destip[i]   = rxdnet.arpframe.sourceip[i];
                txdnet.arpframe.sourceip[i] = rxdnet.arpframe.destip[i];
            }
            txdnet.arpframe.operation = 0x0002;//应答代码
            //txdnet.arpframe.sourceip[1]=0x1020; //debug
            send_packet(60);
           }
    }
}

//8//
void arp_request(unsigned long ip_address)
{
    unsigned char i;
    txdnet.etherframe.protocal = 0x0806;//arp protocal
    for(i = 0; i < 3; i++)
       {//复制对方网卡地址或网关地址
        txdnet.etherframe.destnodeid[i] = 0xffff;
        txdnet.arpframe.sourcenodeid[i] = txdnet.etherframe.sourcenodeid[i];
        txdnet.arpframe.destnodeid[i]   = 0x0000;
    }
    for(i = 0 ;i < 2; i++)
    {
          txdnet.arpframe.sourceip[i] = my_ip_address.words[i];
    }
    txdnet.arpframe.destip[0]      = ip_address>>16;
    txdnet.arpframe.destip[1]      = ip_address&0xffff;
    txdnet.arpframe.harewaretype  = 0x0001;
    txdnet.arpframe.protocaltype = 0x0800;
    txdnet.arpframe.halength     = 0x06;
    txdnet.arpframe.palength     = 0x04;
     txdnet.arpframe.operation     = 0x0001;//应答代码
    for(i = 0x2e; i < (0x2e+18); i++)
    {
        txdnet.bytes.bytebuf[i] = 0x00;
    }
    //txdnet.arpframe.sourceip[1]=0x1020; //debug
    send_packet(60);
}

//9//
void gateway_arp_request()
{
    if(sec < 3)
        if(gateway_ip_address.bytes[0] != 0)
            if(gateway_ip_address_ttl < 5)
            {
                arp_request(gateway_ip_address.dwords);
            }
}

//10//
void arp_process()
{
    unsigned char i;
    if(rxdnet.arpframe.sourceip[0] == gateway_ip_address.words[0])
        if(rxdnet.arpframe.sourceip[1] == gateway_ip_address.words[1])
         {//表示是网关的ip地址的回答.
              for (i = 0; i < 3; i++)
            {
                gateway_ethernet_address.words[i] = rxdnet.arpframe.sourcenodeid[i];
            }
            gateway_ip_address_ttl=10;
        }

    if(rxdnet.arpframe.sourceip[0] == ping_ip_address.words[0])
        if(rxdnet.arpframe.sourceip[1] == ping_ip_address.words[1])
        {//表示是网关的ip地址的回答.
            for (i = 0; i < 3; i++)
            {
                ping_ethernet_address.words[i] = rxdnet.arpframe.sourcenodeid[i];
            }
               ping_ip_address_ttl=10;

        }
}

//11//
void ping_request()
{
    txdnet.etherframe.destnodeid[0] = ping_ethernet_address.words[0];
    txdnet.etherframe.destnodeid[1] = ping_ethernet_address.words[1];
    txdnet.etherframe.destnodeid[2] = ping_ethernet_address.words[2];
    txdnet.etherframe.protocal         = 0x0800;
    txdnet.ipframe.verandihl         = 0x45;
    txdnet.ipframe.typeofserver        = 0x00;
    txdnet.ipframe.totallength        = 60;
    txdnet.ipframe.ttl                = 0x80;
    txdnet.ipframe.frameindex        = frameindex;
    frameindex++;
    txdnet.ipframe.segment            = 0x0000;
    txdnet.ipframe.protocal            = 0x0001;//icmp
    txdnet.ipframe.crc                = 0;
    txdnet.ipframe.destip[0]        = ping_ip_address.words[0];
    txdnet.ipframe.destip[1]        = ping_ip_address.words[1];
    txdnet.ipframe.sourceip[0]        = my_ip_address.words[0];
    txdnet.ipframe.sourceip[1]        = my_ip_address.words[1];
    txdnet.ipframe.crc                = createipheadcrc();
    txdnet.icmpframe.type            = 0x08;// is icmp request;
    txdnet.icmpframe.crc            = 0;
    txdnet.icmpframe.id                = 0x0300;
    txdnet.icmpframe.seq            = frameindex;
    txdnet.icmpframe.crc            = createicmpcrc();

    send_packet(74);
}

//12//
void process_ping()
{
    if(ping_count>0)
    {
        ping_count--;
        if(ping_count > 0)
        {
              if(ping_ip_address_ttl>0)
            {//表示ip地址已经解析
                   send_string("\r\nSend Ping Request...");
                ping_request();
            }
            else
            { //解析ip地址
                   send_string("\r\nSend ARP Request...\r\n       ");
                arp_request(ping_ip_address.dwords);
            }
            if(ping_ip_address.dwords==my_ip_address.dwords)
             {//ping的是自己的ip地址
                 send_string(" Reply From IP=");
                 send_word(my_ip_address.words[0]);
                 send_word(my_ip_address.words[1]);
                 send_string(" TTL=80");
             }

        }
        if(ping_count==0)
        {
            send_string("\r\nPing Command Finished.\r\n");
               ping_ip_address_ttl=0;
        }
    }
}

//13//
void copy_to_retransmit_buffer()
{
    unsigned char i;
    unsigned int ii;
//    unsigned char xdata *txd=&txdnet;
//    unsigned char xdata *rt;
    unsigned char *txd = &txdnet;
    unsigned char *rt;

    for(i = 0; i < rt_size; i++)
    {
        if(retransmit_buffer[i].rtframe.status == 0)
          {
              rt = &retransmit_buffer[i].bytes.bytebuf;
              for(ii = 0; ii < retransmit_buffer[i].rtframe.length + 4; ii++)
              {
                 (*rt)=(*txd);
                  rt++;
                  txd++;
              }
            retransmit_buffer[i].rtframe.status  = 1;
            retransmit_buffer[i].rtframe.timeout = rttime;//重发时间 默认为1秒
              break;
        }
    }
}

void process_command()
{//处理用户从串口输入的命令
uchar temp;
uchar temp1;
uchar temp2;
uint vue;
uchar k;
uchar i;
uchar ip;
uchar j;

uint temp3;
uint temp4;
uint ip1;

while(comrxdread!=comrxdwrite)
  {
     temp=get_char();
      command_buffer[command_length]=temp;
     if((temp!=' ')&&(temp!=0x0d)) command_length++;//表示不是空格和回车
     if(command_length==command_buffer_size)command_length=0;

      if(temp==0x0d) //回车键
             {
          if(command_length>6) //一个ping命令的指令最少要10个字符
                      if(  string_compare("ping",4)!=0  )
                     //==========================以下为ping命令的解析和执行
                        {
                          #ifdef debug
                          send_string("\r\nCommand: ping");
                            #endif
                           ip=0;
                         //取得ip地址
                         for(i=4,j=0;i<command_length;i++)
                         {
                          if(command_buffer[i]!='.')
                            { command_buffer[i]=command_buffer[i]&0x0f;
                              ip=ip*10;
                              ip=ip+command_buffer[i];
                              }
                              else{
                                   ping_ip_address.bytes[j]=ip;
                                     j++;
                                    // if(j==4)break;//确保不存储ping_ip_address.bytes[4];
                                     ip=0;
                                   }
                              }

                           //命令执行
                          if(j==3){ ping_ip_address.bytes[j]=ip;
                                     // 表示命令正确
                                    send_string("\r\nPing IP=") ;
                                    send_word(ping_ip_address.words[0]);
                                    send_word(ping_ip_address.words[1]);
                                      ping_count=8;
                                     if((ping_ip_address.dwords&mask_ip_address.dwords)==(my_ip_address.dwords&mask_ip_address.dwords))
                                        {
                                       //表示位于同一子网.
                                        arp_request(ping_ip_address.dwords);

                                         }
                                             else{//表示属于不同的子网,需要通过网关.
                                             send_string("\r\nIn other Subnet");
                                           ping_ip_address_ttl=10;
                                           for(j=0;j<6;j++)
                                           {
                                           ping_ethernet_address.bytes[j]=gateway_ethernet_address.bytes[j];
                                           }
                                          if(gateway_ip_address_ttl==0)
                                             {
                                            send_string("\r\nGateWay Not Found!\r\nC:>");
                                            ping_count=0;

                                              }
                                              }


                            }
                            else{
                                  send_string("\r\nPing Command Error\r\nC:>");


                                }

⌨️ 快捷键说明

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