找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2644|回复: 1
打印 上一主题 下一主题
收起左侧

哈哈我成功了《TCP下的数据发送&接收》通过看手册搞定的

[复制链接]
跳转到指定楼层
楼主
ID:82781 发表于 2015-6-13 16:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  哈哈我今晚上终于搞定了网卡的TCP包的接收,我是星期一来上班的,师傅就给我一个网卡让我做个类似服务器性质终端,幸好去年我搞过一点ENC的ARP要不直接不会,每天都是看手册看手册看手册,程序也一点一点的建立起来,但是昨天和今天所有的路子都铺好了,就差包接收和发送了,发送的时候算法是自己搞的结果出了问题,今天又高接收,搞了一天,问题是我老是受到TCP数据后会出现乱码,后来反复实验发现这是溢出缓存造成的数据过冲,今晚上看了DATESHEET才发现人家有算法,把人家的算法编程后,哈哈爽啊!
下面是程序:(部分代码)乱了点却是原汁原味的
2012年2月9日于日照高科园
20:52
据我测试没有丢包
没有乱码
流程:
PC发送TCP数据流到路由器
路由器转发到网卡
网卡转发到MCU
MCU通过串口发到PC
形成一个环回数据流
估计今晚上睡不着了。。。。。。

   uchar flage;
               uint get_size; //接收的数据大小
              uint get_offset; //偏移地址
              uint get_start_address;//缓存的物理地址
              uint upper_size;//多余的字节
              //uint destination_addr;//中间地址
              uint left_size;//
             // uint destination_addr;
     /*******用来做接收计数使*********/
            uint  S0_RX_NUMB; //接收的数据字节总个数
   uchar S0_RX_NUMB_DAT1; //中间量用于16-8位转换
      /*******************
      
         要读接受的数据就要知道当前的物理地址
       而当前的物理地址就得要读这两个寄存器
       间接的计算出物理地址
       计算方法就是手册上的
      **************/
   uint  S0_RX_RD;//当前接收缓存地址
   uchar S0_RX_RD_DAT0,S0_RX_RD_DAT1; //中间量用于16-8位转换
            uint numb; //计数参照
   uint  S0_RX_START_ADDRESS;//接收缓存的实际物理地址
   uchar  a;
   /***************
     
   *************/
while(read_register(S0_SSR)!=0x17);//客户端:TCP连接成功转入了SOCKT_EASTABLISHED状态(可以进行数据收发)
/******************************************************
    判断是否接收导数据
****************************************************/
do
{
//SendOneByte(read_register(S0_IR));//
a=read_register(S0_IR);
a=a&0x04;
}
while(a!=0x04);//是否姐收到数据包是向下
write_register(S0_IR,0xFF);

               S0_RX_NUMB=read_register(S0_RX_RSR0);
                                 S0_RX_NUMB_DAT1=read_register(S0_RX_RSR1);
      
             S0_RX_NUMB<<=8;
             S0_RX_NUMB+=S0_RX_NUMB_DAT1;
              get_size=S0_RX_NUMB;
                  
                  S0_RX_RD=read_register(S0_RX_RD0);
                              S0_RX_RD_DAT1=read_register(S0_RX_RD1);
         
                  S0_RX_RD<<=8;
                  S0_RX_RD+=S0_RX_RD_DAT1;
              get_offset=(S0_RX_RD&gS0_RX_MASK);
              get_start_address=gS0_RX_BASE+get_offset;


              if((get_offset+get_size)>(gS0_RX_MASK+1))
              {
              
                upper_size=(gS0_RX_MASK+1)-get_offset;
             for(numb=0;numb<upper_size;numb++)
             {

                SendOneByte(read_register((get_start_address+numb)));

             }
                 
            
             for(numb=0;numb<left_size;numb++)
             {

                SendOneByte(read_register((gS0_RX_BASE+numb)));

             }
           
              
              }
              else
              {
              
                  for(numb=0;numb<get_size;numb++)
             {
               flage=read_register((get_start_address+numb));
                SendOneByte(read_register((get_start_address+numb)));
               if(flage==0x31)
             {
      
            bell=0;
             }
             if(flage==0x32)
             {
      
              bell=1;
              }
      
                }
            
              
              
              }
      
         S0_RX_RD+=get_size;
         S0_RX_RD_DAT1=S0_RX_RD;
        S0_RX_RD_DAT0=(S0_RX_RD>>8);
     write_register(S0_RX_RD0,S0_RX_RD_DAT0);  
     write_register(S0_RX_RD1, S0_RX_RD_DAT1);
      
         write_register(S0_CR,RECV);//
      

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:82781 发表于 2015-6-13 17:00 | 只看该作者
         哈哈原来就是这么简单,奥秘都在手册里呢!!!要什么有什么!中文手册真是不敢恭维,还是人家老外牛逼不服不行!!
发包程序:
/*********************

  发TCP送数据包
  完全根据DATESHEET做的
  2012年2月10日
  与日照
  王均伟
9::31
**********************/
void send_packet_tcp()
{
     uint  S0_TX_WR;//发送写指针
     uchar S0_TX_WR0_DAT0,S0_TX_WR0_DAT1;//中间变量
//     uint  S0_TX_START_ADDRESS;//发送缓存的实际物理地址
     uint numb;               
      
                        uint get_free_size;//发送区剩余空间
                     uint send_size;//发送字节数
                     uint get_offset;//偏移地址
                                             uint get_start_address;//缓存的物理地址
                     uint upper_size;
                     uint left_size;                 
                     
                     
                     while(read_register(S0_SSR)!=0x17);//客户端:TCP连接成功转入了SOCKT_EASTABLISHED状态(可以进行数据收发)   
                       send_size=30;//发送字节为10个
                    
                     //抓取剩余空间大小
                      get_free_size=read_register(S0_TX_FSR0);
                      get_free_size<<=8;
                      get_free_size+=read_register(S0_TX_FSR1);
                          //如果发送空间小于发送数据字节那么出错
                        if(get_free_size<send_size)
                     {
                     
                     //ERRO
                      while(1);
                     
                     }
                       
                     S0_TX_WR=read_register(S0_TX_WR0);
                     S0_TX_WR<<=8;
                     S0_TX_WR+=read_register(S0_TX_WR1);
                    
                     get_offset=S0_TX_WR&gS0_TX_MASK;//计算偏移
                     get_start_address=gS0_TX_BASE+get_offset;//计算物理地址
                     if((get_offset+send_size)>(gS0_TX_MASK+1))
                     {
                     
                      upper_size=(gS0_TX_MASK+1)-get_offset;
                     for(numb=0;numb<upper_size;numb++)
                     {
                       write_register(get_start_address+numb,0xcc);//发送数据
                     
                     }
                     
                       left_size=send_size-upper_size;
                     
                      for(numb=0;numb<left_size;numb++)
                      {
                     
                        write_register(gS0_TX_BASE+numb,0xcc);//发送数据
                     
                      }


                     }
                     else
                     {
                     
                     
                        for(numb=0;numb<send_size;numb++)
                       {
                       
                      write_register(get_start_address+numb,0xcc);//发送数据
                       }
                     
                     
                     }

                     S0_TX_WR+=send_size;
                            S0_TX_WR0_DAT1=S0_TX_WR;
                        S0_TX_WR0_DAT0=((S0_TX_WR>>8)&0x00ff);
                    write_register(S0_TX_WR0,S0_TX_WR0_DAT0);
                    write_register(S0_TX_WR1,S0_TX_WR0_DAT1);//写发送缓存区最开始字节从0x4000+(S0_TX_WR&0x07ff)

                      write_register(S0_CR,SEND);//发送

                  
                  
                             
// SendOneByte(read_register(S0_TX_FSR0));//串口发送发送缓冲的剩余空间
// SendOneByte(read_register(S0_TX_FSR1));//串口发送发送缓冲的剩余空间

//write_register(S0_TX_RD0,0x0);
   // write_register(S0_TX_RD1,0);//写发送缓存区最开始字节从0x4000+(S0_TX_WR&0x07ff)
  /*  S0_TX_WR0_DAT1=S0_TX_WR;
    S0_TX_WR0_DAT0=((S0_TX_WR>>8)&0x00ff);
write_register(S0_TX_WR0,S0_TX_WR0_DAT0);
write_register(S0_TX_WR1,S0_TX_WR0_DAT1);//写发送缓存区最开始字节从0x4000+(S0_TX_WR&0x07ff)
                               //带入得:0X4000+0=0X4000;这就是端口0的开始地址也是我要开始写数据的地址
   

      S0_TX_START_ADDRESS=(S0_TX_BASE+(S0_TX_WR&S0_TX_MASK));  
      
   for(numb=0;numb<1024;numb++)
     {     
     S0_TX_START_ADDRESS++;
                      //写缓存
write_register(S0_TX_START_ADDRESS,0xcc);//
      }
     */

   //发送数据后得把写指针原先的值加上数据长度在写入写指针,表示数据后移   
/* S0_TX_WR=S0_TX_WR+numb;
       S0_TX_WR0_DAT1=S0_TX_WR;
    S0_TX_WR0_DAT0=((S0_TX_WR>>8)&0x00ff);
write_register(S0_TX_WR0,S0_TX_WR0_DAT0);
write_register(S0_TX_WR1,S0_TX_WR0_DAT1);//写发送缓存区最开始字节从0x4000+(S0_TX_WR&0x07ff)

write_register(S0_CR,SEND);//发送
   while((read_register(S0_IR)&0x10)!=0x10);
write_register(S0_IR,0xff);//发送
SendOneByte(read_register(S0_SSR));//
SendOneByte(read_register(S0_IR));//
SendOneByte(read_register(S0_TX_RD0));//串口发送发送缓冲的剩余空间
SendOneByte(read_register(S0_TX_RD1));//串口发送发送缓冲的剩余空间
SendOneByte(read_register(S0_TX_WR0));//串口发送发送缓冲的剩余空间
SendOneByte(read_register(S0_TX_WR1));//串口发送发送缓冲的剩余空间
// SendOneByte(read_register(S0_TX_FSR0));//串口发送发送缓冲的剩余空间
// SendOneByte(read_register(S0_TX_FSR1));//串口发送发送缓冲的剩余空间

// SendOneByte(read_register(S0_TX_START_ADDRESS));//串口发送发送缓冲的剩余空间
// SendOneByte(read_register(S0_TX_START_ADDRESS-1));//串口发送发送缓冲的剩余空间
*/



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表