本帖最后由 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位丢弃,语句中再加入与运算有什么好处呢?
|