搜索
bottom↓
回复: 27

W5500 TCP通信发送一个数组时,发送的都是最后一个字节

[复制链接]

出0入17汤圆

发表于 2017-9-23 11:58:17 | 显示全部楼层 |阅读模式
本帖最后由 HZKJ 于 2017-9-23 12:29 编辑

非常奇怪的问题:TCP每次发送一个字节没有问题,但是发送一个数据包时,网络助手接收到的都是数组的最后一个字节,
通信字节数量是对的。也就是软件接收20个字节都是相同的。    第一次使用W5500,请大家指点 赐教!!


while(1)   //W5500连续发送数据
{
                W5500_Socket_Set();//W5500端口初始化
                W5500_Interrupt_Process();//
                if((S0_Data & S_RECEIVE) == S_RECEIVE)// 接收并发送数据
                {
                        S0_Data&=~S_RECEIVE;
                        Process_Socket_Data(0);//W5500
                }
         for(a=0;a<20;a++)
        {
                  sd_buf1[a]=a;
         }
         Write_SOCK_Data_Buffer(0, &sd_buf1[a],20); // 发送20字节
         delay_ms(3000);
}

/*******************************************************************************
* 函数名  : Write_SOCK_Data_Buffer
* 描述    : 将数据写入W5500的数据发送缓冲区
* 输入    : s:端口号,*dat_ptr:数据保存缓冲区指针,size:待写入数据的长度
* 输出    : 无
* 返回值  : 无
* 说明    : 无
*******************************************************************************/
void Write_SOCK_Data_Buffer(SOCKET s, unsigned char *dat_ptr, unsigned short size)
{
        unsigned short offset,offset1;
        unsigned short i;

        //如果是UDP模式,可以在此设置目的主机的IP和端口号
        if((Read_W5500_SOCK_1Byte(s,Sn_MR)&0x0f) != SOCK_UDP)//如果Socket打开失败
        {               
                Write_W5500_SOCK_4Byte(s, Sn_DIPR, UDP_DIPR);//设置目的主机IP                 
                Write_W5500_SOCK_2Byte(s, Sn_DPORTR, UDP_DPORT[0]*256+UDP_DPORT[1]);//设置目的主机端口号                               
        }

        offset=Read_W5500_SOCK_2Byte(s,Sn_TX_WR);
        offset1=offset;
        offset&=(S_TX_SIZE-1);//计算实际的物理地址

        GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS为低电平

        SPI1_Send_Short(offset);//写16位地址
        SPI1_Send_Byte(VDM|RWB_WRITE|(s*0x20+0x10));//写控制字节,N个字节数据长度,写数据,选择端口s的寄存器

        if((offset+size)<S_TX_SIZE)//如果最大地址未超过W5500发送缓冲区寄存器的最大地址
        {
                for(i=0;i<size;i++)//循环写入size个字节数据
                {
                        SPI1_Send_Byte(*dat_ptr++);//写入一个字节的数据               
                }
        }
        else//如果最大地址超过W5500发送缓冲区寄存器的最大地址
        {
                offset=S_TX_SIZE-offset;
                for(i=0;i<offset;i++)//循环写入前offset个字节数据
                {
                        SPI1_Send_Byte(*dat_ptr++);//写入一个字节的数据
                }
                GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS为高电平

                GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS为低电平

                SPI1_Send_Short(0x00);//写16位地址
                SPI1_Send_Byte(VDM|RWB_WRITE|(s*0x20+0x10));//写控制字节,N个字节数据长度,写数据,选择端口s的寄存器

                for(;i<size;i++)//循环写入size-offset个字节数据
                {
                        SPI1_Send_Byte(*dat_ptr++);//写入一个字节的数据
                }
        }
        GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS为高电平

        offset1+=size;//更新实际物理地址,即下次写待发送数据到发送数据缓冲区的起始地址
        Write_W5500_SOCK_2Byte(s, Sn_TX_WR, offset1);
        Write_W5500_SOCK_1Byte(s, Sn_CR, SEND);//发送启动发送命令                               
}


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入17汤圆

 楼主| 发表于 2017-9-23 12:11:14 | 显示全部楼层
刚刚测试了,TCP 客户端接收时没有问题的。连续接收10个字节都是OK的。

出0入17汤圆

 楼主| 发表于 2017-9-23 12:35:51 | 显示全部楼层
W5500是客户端,PC是服务器端。

出0入17汤圆

 楼主| 发表于 2017-9-23 14:40:03 | 显示全部楼层
顶起,看来没有人遇到这么奇葩的问题哦

出0入10汤圆

发表于 2017-9-23 21:16:11 | 显示全部楼层

Write_SOCK_Data_Buffer(0, &sd_buf1[a],20); // 发送20字节
改成
Write_SOCK_Data_Buffer(0, &sd_buf1[0],20); // 发送20字节

试试。

出0入17汤圆

 楼主| 发表于 2017-9-23 21:26:42 | 显示全部楼层
mmiker 发表于 2017-9-23 21:16

Write_SOCK_Data_Buffer(0, &sd_buf1[a],20); // 发送20字节
改成

不行哦
Write_SOCK_Data_Buffer(0, &sd_buf1[0],20); // 发送20字节
Write_SOCK_Data_Buffer(0, sd_buf1,20); // 发送20字节
两种 数组的操作方式都试过,不是这里的问题。

出0入17汤圆

 楼主| 发表于 2017-9-23 23:58:07 | 显示全部楼层
我用串口监视发给SPI的数据  都是正常的。

出0入0汤圆

发表于 2017-9-24 11:08:11 来自手机 | 显示全部楼层
         for(a=0;a<20;a++)         {                   sd_buf1[a]=a;          }          Write_SOCK_Data_Buffer(0, &sd_buf1[a],20); // 发送20字节

出0入0汤圆

发表于 2017-9-24 11:10:53 来自手机 | 显示全部楼层
a最后等于20,你的&sd_buf1[20],不光不是取的数组第一个位置,而且还越界了。按前面有人说的方法改,或者把a换成0

出0入17汤圆

 楼主| 发表于 2017-9-24 16:41:35 | 显示全部楼层
sunny_82 发表于 2017-9-24 11:10
a最后等于20,你的&sd_buf1[20],不光不是取的数组第一个位置,而且还越界了。按前面有人说的方法改,或者 ...

你说的对,很详细。
Write_SOCK_Data_Buffer(0, &sd_buf1[0],20); // 发送20字节
Write_SOCK_Data_Buffer(0, sd_buf1,20); // 发送20字节
以上两种 数组的操作方式都试过, 都没有解决楼主的问题。

出0入0汤圆

发表于 2017-9-24 18:57:49 | 显示全部楼层
看起来像是你spi处理问题,数据前面的都没收,值收了最后一次spi的并且连着循环放到缓存,你应该差spi接收数组

出0入4汤圆

发表于 2017-9-24 20:17:24 来自手机 | 显示全部楼层
先看下spi 发出的数据对不对。

出0入17汤圆

 楼主| 发表于 2017-9-24 21:04:47 | 显示全部楼层
NJ8888 发表于 2017-9-24 18:57
看起来像是你spi处理问题,数据前面的都没收,值收了最后一次spi的并且连着循环放到缓存,你应该差spi接收 ...

谢谢 元老:
我通过串口监控发到SPI的数据,程序单步运行,串口数据是对的:不如我发送0123456789,
串口助手收到的的确是这样的数据,但是网络助手收到却是9999999999.
        if((offset+size)<S_TX_SIZE)//如果最大地址未超过W5500发送缓冲区寄存器的最大地址
        {
                for(i=0;i<size;i++)//循环写入size个字节数据
                {
                        SPI1_Send_Byte(*dat_ptr++);//写入一个字节的数据       
                        USART3_send(*dat_ptr);  //=====================================TEST=============
                }
        }

出0入17汤圆

 楼主| 发表于 2017-9-24 21:07:05 | 显示全部楼层
xiaoergao 发表于 2017-9-24 20:17
先看下spi 发出的数据对不对。

是的,只能用示波器或者逻辑分析仪看波形了。

出0入17汤圆

 楼主| 发表于 2017-9-24 21:08:33 | 显示全部楼层
难道是5500的某个寄存器设置不对,还没深入看看寄存器呢。。。

出0入17汤圆

 楼主| 发表于 2017-9-24 21:10:45 | 显示全部楼层
NJ8888 发表于 2017-9-24 18:57
看起来像是你spi处理问题,数据前面的都没收,值收了最后一次spi的并且连着循环放到缓存,你应该差spi接收 ...

对了,5500接收服务器端的数据,然后通过串口打印出来,是正常的。

出0入0汤圆

发表于 2017-9-24 21:23:35 | 显示全部楼层
我怀疑你spi字节写,因为我记得传数据一大串才一次片选,感觉你字节写一次一个片选,但你自己没更新新地址

出0入17汤圆

 楼主| 发表于 2017-9-24 21:43:19 | 显示全部楼层
NJ8888 发表于 2017-9-24 21:23
我怀疑你spi字节写,因为我记得传数据一大串才一次片选,感觉你字节写一次一个片选,但你自己没更新新地址 ...

麻烦你看看我1楼 的程序:void Write_SOCK_Data_Buffer(SOCKET s, unsigned char *dat_ptr, unsigned short size)
这里面也是只有一次片选啊。。。
先片选,然后写地址,最后SPI连续写数据包。

出0入0汤圆

发表于 2017-9-24 22:04:32 来自手机 | 显示全部楼层
buf的定义加个xdata试试

出0入17汤圆

 楼主| 发表于 2017-9-24 22:12:02 | 显示全部楼层
sunny_82 发表于 2017-9-24 22:04
buf的定义加个xdata试试

用的是STM32, 内寸够用。。。

出0入17汤圆

 楼主| 发表于 2017-9-25 00:01:01 | 显示全部楼层
调试SPI大家还有什么好的手段,除了示波器和逻辑分析仪。。。

出0入17汤圆

 楼主| 发表于 2017-9-25 09:41:34 | 显示全部楼层
前面5500的配置后都可以进行网络通信了,由此应该可以判断底层SPI程序应该是正常的。。。问题应该出在SOCKET通信方面。。。

出0入0汤圆

发表于 2017-9-25 11:34:32 | 显示全部楼层
例程都跑不通?最好先确定一个OK的版本,不论是硬件还是软件

出0入17汤圆

 楼主| 发表于 2017-9-25 12:28:41 | 显示全部楼层
xingkong911 发表于 2017-9-25 11:34
例程都跑不通?最好先确定一个OK的版本,不论是硬件还是软件

也是,你那里有OK的版本吧,麻烦你发上来一份。。。

出0入0汤圆

发表于 2017-9-23 11:58:18 | 显示全部楼层
HZKJ 发表于 2017-9-25 12:28
也是,你那里有OK的版本吧,麻烦你发上来一份。。。

我买了一个MSP430的Lauch开发板和ioShield-L的W5500开发板,可以用例程正常收发数据

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入17汤圆

 楼主| 发表于 2017-9-25 13:11:48 | 显示全部楼层
xingkong911 发表于 2017-9-25 13:07
我买了一个MSP430的Lauch开发板和ioShield-L的W5500开发板,可以用例程正常收发数据 ...

好的,多谢。我试试看

出0入0汤圆

发表于 2017-9-25 15:13:39 来自手机 | 显示全部楼层
为什么不用socket库来做,方便快捷,正点和野火都有例程

出0入17汤圆

 楼主| 发表于 2018-5-26 17:43:20 | 显示全部楼层
问题不能就这么糊里糊涂的过了,最近调试才发现真正的问题所在,端口数据缓存区要设置成1024的整倍数才保证通信数据正常。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-18 20:38

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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