W5500 TCP通信发送一个数组时,发送的都是最后一个字节
本帖最后由 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;
}
Write_SOCK_Data_Buffer(0, &sd_buf1,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*256+UDP_DPORT);//设置目的主机端口号
}
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);//发送启动发送命令
}
刚刚测试了,TCP 客户端接收时没有问题的。连续接收10个字节都是OK的。 W5500是客户端,PC是服务器端。 顶起,看来没有人遇到这么奇葩的问题哦 把
Write_SOCK_Data_Buffer(0, &sd_buf1,20); // 发送20字节
改成
Write_SOCK_Data_Buffer(0, &sd_buf1,20); // 发送20字节
试试。 mmiker 发表于 2017-9-23 21:16
把
Write_SOCK_Data_Buffer(0, &sd_buf1,20); // 发送20字节
改成
不行哦
Write_SOCK_Data_Buffer(0, &sd_buf1,20); // 发送20字节
Write_SOCK_Data_Buffer(0, sd_buf1,20); // 发送20字节
两种 数组的操作方式都试过,不是这里的问题。 我用串口监视发给SPI的数据都是正常的。 for(a=0;a<20;a++) { sd_buf1=a; } Write_SOCK_Data_Buffer(0, &sd_buf1,20); // 发送20字节 a最后等于20,你的&sd_buf1,不光不是取的数组第一个位置,而且还越界了。按前面有人说的方法改,或者把a换成0 sunny_82 发表于 2017-9-24 11:10
a最后等于20,你的&sd_buf1,不光不是取的数组第一个位置,而且还越界了。按前面有人说的方法改,或者 ...
你说的对,很详细。
Write_SOCK_Data_Buffer(0, &sd_buf1,20); // 发送20字节
Write_SOCK_Data_Buffer(0, sd_buf1,20); // 发送20字节
以上两种 数组的操作方式都试过, 都没有解决楼主的问题。 看起来像是你spi处理问题,数据前面的都没收,值收了最后一次spi的并且连着循环放到缓存,你应该差spi接收数组 先看下spi 发出的数据对不对。 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=============
}
} xiaoergao 发表于 2017-9-24 20:17
先看下spi 发出的数据对不对。
是的,只能用示波器或者逻辑分析仪看波形了。
难道是5500的某个寄存器设置不对,还没深入看看寄存器呢。。。 NJ8888 发表于 2017-9-24 18:57
看起来像是你spi处理问题,数据前面的都没收,值收了最后一次spi的并且连着循环放到缓存,你应该差spi接收 ...
对了,5500接收服务器端的数据,然后通过串口打印出来,是正常的。 我怀疑你spi字节写,因为我记得传数据一大串才一次片选,感觉你字节写一次一个片选,但你自己没更新新地址 NJ8888 发表于 2017-9-24 21:23
我怀疑你spi字节写,因为我记得传数据一大串才一次片选,感觉你字节写一次一个片选,但你自己没更新新地址 ...
麻烦你看看我1楼 的程序:void Write_SOCK_Data_Buffer(SOCKET s, unsigned char *dat_ptr, unsigned short size)
这里面也是只有一次片选啊。。。
先片选,然后写地址,最后SPI连续写数据包。 buf的定义加个xdata试试 sunny_82 发表于 2017-9-24 22:04
buf的定义加个xdata试试
用的是STM32, 内寸够用。。。 调试SPI大家还有什么好的手段,除了示波器和逻辑分析仪。。。 前面5500的配置后都可以进行网络通信了,由此应该可以判断底层SPI程序应该是正常的。。。问题应该出在SOCKET通信方面。。。 例程都跑不通?最好先确定一个OK的版本,不论是硬件还是软件 xingkong911 发表于 2017-9-25 11:34
例程都跑不通?最好先确定一个OK的版本,不论是硬件还是软件
也是,你那里有OK的版本吧,麻烦你发上来一份。。。 HZKJ 发表于 2017-9-25 12:28
也是,你那里有OK的版本吧,麻烦你发上来一份。。。
我买了一个MSP430的Lauch开发板和ioShield-L的W5500开发板,可以用例程正常收发数据 xingkong911 发表于 2017-9-25 13:07
我买了一个MSP430的Lauch开发板和ioShield-L的W5500开发板,可以用例程正常收发数据 ...
好的,多谢。我试试看
为什么不用socket库来做,方便快捷,正点和野火都有例程 问题不能就这么糊里糊涂的过了,最近调试才发现真正的问题所在,端口数据缓存区要设置成1024的整倍数才保证通信数据正常。
页:
[1]