dontium 发表于 2019-7-13 08:48

W5500例程的不严谨造成的网络不正常通讯的问题。

本帖最后由 dontium 于 2019-7-13 08:53 编辑

W5500使用简单、方便,对资源要求低,非常喜欢。刚开始用它,在www.w5500.cn网站下载了例程,-------不知道这个网站是不是官网。

在使用TCP服务器程序时,遇到了问题:W5500接收多数情况正常,发送少数情况正常。




因为是刚接触此芯片,所以就找自己的原因,开始怀疑SPI的相位不正确,
又怀疑SPI的速度太快,又怀疑硬件电路有问题,……。搞了几天也不知道问题所在。
后来长时间监视发送接收,发现,接收的数据的正确与错误有一定规律,即有周期性。
这时想到的是,寄存器的读写问题,是不是地址修改不正确造成对2048的存储器从头至尾来回读写?
但检查程序,又认真地学习芯片手册,并没有发现问题,后来想想,是不是程序问题 ----一般不这样怀疑的
因为经询问是“反复实验正常”的程序。但还是要检查的,或者是自己在修改什么参数时不小心动到哪儿了?

检查到收发函数时,突然觉得好象有点问题。
原程序是这样的:
void send_data_processing(SOCKET s, uint8 *data, uint16 len)
{
uint16 ptr =0;
uint32 addrbsb =0;
if(len == 0)
{
    printf(" CH: %d Unexpected1 length 0\r\n", s);
    return;
}
   
ptr = IINCHIP_READ( Sn_TX_WR0(s) );
ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_TX_WR1(s));

addrbsb = (uint32)(ptr<<8) + (s<<5) + 0x10;
wiz_write_buf(addrbsb, data, len);

ptr += len;
IINCHIP_WRITE( Sn_TX_WR0(s) ,(uint8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE( Sn_TX_WR1(s),(uint8)(ptr & 0x00ff));
}

这里的:
         addrbsb = (uint32)(ptr<<8) + (s<<5) + 0x10;
中的ptr为16位,而在左移8位后再强制转换成32位,
这样在轮换前它的高8位就被移出去了,丢失了。再强制转换成32位就没有意义了。


将它改一下:
      addrbsb = ((uint32)ptr<<8) + (s<<5) + 0x10;
   并对其它相似的地方作同样修改。
烧写后程序运行正常!


另外,我有个疑问:
         IINCHIP_WRITE( Sn_TX_WR0(s) ,(uint8)((ptr & 0xff00) >> 8));
这句中的,(uint8)((ptr & 0xff00) >> 8),对于ptr,先将低8位屏蔽掉再移出,
与直接移出低8位,在结果上有什么区别?如果没有区别,多加这个不是给程序带来负担吗?
相同的如(uint8)(ptr & 0x00ff),如果编译器有强制类型转换功能,就会把高8位丢弃,语句中再加入与运算有什么好处呢?

hjl2832 发表于 2019-8-9 12:34

不错不错,好经验分享。

ic12580 发表于 2019-8-12 11:00

你那个明显不是官网,例程还是找原厂或者代理那边索取,随便下的,就只能折腾自己了

3htech 发表于 2019-11-25 15:59

我也有你那个原厂程序,不过,已经更新成你说的这样了。

3htech 发表于 2019-11-25 16:05

另外,请教楼主几个问题,能否给说明一下socket n的发送过程。主要是TX_WR是怎么变化的。
如果TX_WR大于他分配给他的空间(例如2k-4k是分给他的地址范围),这个变量是变成2k,还是变成0?

tianxj01 发表于 2019-11-26 09:27

这一般是由编程习惯造成。
如果纯粹屏蔽的和移动位数一样,而且是被移出去的,则完全可以不需要这个屏蔽命令。
页: [1]
查看完整版本: W5500例程的不严谨造成的网络不正常通讯的问题。