这年头碰到问题还得自己解决,发个帖都没人回.
问题终于解决了,下面说说问题在哪.
开始始终以为是始初化代码有问题,一直在那块找问题,废了好长时间.
计算机发送ARP数据包,可以响应.但板子接收数据不流畅,感觉接收有问题,
经过细细分析查找,终于发现问题在u16 enc28j60PacketReceive(u16 maxlen, u8* packet)函数中.
NextPacketPtr |= (enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0) << 8);
下面这个写法在MCC18中很有问题,改成如下写法:
temp = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
temp <<= 8;
NextPacketPtr |= temp;
还有
len |= (enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0) << 8);
rxstat |= (enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0) << 8);
也要改,板子数据接收流畅,没有问题.
(到这为止还以为MCC18不支持这种多步操作一行的写法)
ARP数据包可以发送出去,通过比较ARP和ICMP包响应函数发现,
void make_echo_reply_from_request(unsigned char* buf, unsigned int len)
函数中调用了make_ip(buf),而该函数中又调了checksum函数,然后把该函数中的多步操作一行的写法
改成如下:
unsigned int checksum(unsigned char* buf, unsigned int len, unsigned char type)
{
// type 0=ip
// 1=udp
// 2=tcp
unsigned long sum = 0;
unsigned int temp;
//if(type==0){
// // do not add anything
//}
if (type == 1)
{
sum += IP_PROTO_UDP_V; // protocol udp
// the length here is the length of udp (data+header len)
// =length given to this function - (IP.scr+IP.dst length)
sum += len;
sum -= 8; // = real tcp len
}
else if (type == 2)
{
sum += IP_PROTO_TCP_V;
// the length here is the length of tcp (data+header len)
// =length given to this function - (IP.scr+IP.dst length)
sum += len;
sum -= 8; // = real tcp len
}
// build the sum of 16bit words
while (len > 1)
{
temp = *buf;
temp <<= 8;
temp |= *(buf+1);
temp &= 0xFFFF;
sum += temp;
buf += 2;
len -= 2;
}
// if there is a byte left then add it (padded with zero)
if (len)
{
temp = *buf;
temp <<= 8;
sum += temp;
}
// now calculate the sum over the bytes in the sum
// until the result is only 16bit long
while (sum >> 16)
{
//sum = (sum & 0xFFFF) + (sum >> 16);
temp = sum >> 16;
sum &= 0xFFFF;
sum += temp;
}
// build 1's complement:
sum ^= 0xFFFF;
return((unsigned int) sum);
}
此时,ICMP包有响应,能PING通了, :)
再调UDP和TCP.
在调TCP的时候,发现下面这段
init_len_info(buf); //计算有效数据长度,存到info_data_len中
//可能无有效数据,只响应
dat_p = get_tcp_data_pointer();//在buf中找到有效数据的起始地址
if (dat_p == 0)//无有效数据
{
if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V)//ACK=1,FIN=1 发送方已经没有数据发送了,用来释放连接
{//客户端主动断开连接
// finack, answer with ack
make_tcp_ack_from_any(buf);
}
// just an ack with no data, wait for next packet
continue;
}
在TCP建立连接的时候,有一帧数据会进到这段,而有效数据长度(dat_p)应该为0,
实际测试发现建立连接的时候始终不为0,最后发现问题在init_len_info函数中,
temp = buf[IP_TOTLEN_H_P]<< 8;
改成
temp = buf[IP_TOTLEN_H_P];
temp <<= 8;
后,正常,至此终于发现MCC18中左移不能写成 a=b<<8;要写成a=b;a<<=8;
以上都是这个问题造成的,搞了好长时间,真是郁闷了好长时间.
在simpleserver.c中还有2个地方要改成如下:
if ( strncmpram2pgm((rom char *)"GET ", (char *)&buf[dat_p], 4) != 0 )
if (strncmpram2pgm((rom char *)"/ ", (char *) &(buf[dat_p + 4]), 2) == 0)
fill_tcp_data_p函数也要改:
unsigned int fill_tcp_data_p(unsigned char* buf, unsigned int pos,auto const rom char * progmem_s)
{
/* char c;
while( c = (char)*(progmem_s++) ) //#define pgm_read_byte(ptr) ((char)*(ptr))
{
buf[TCP_CHECKSUM_L_P + 3 + pos] = c;
pos++;
}*/
unsigned int len;
//char *strcpypgm2ram (auto char *s1, auto const MEM_MODEL rom char *s2);
strcpypgm2ram((char *)&buf[TCP_CHECKSUM_L_P + 3 + pos],progmem_s);
len = strlenpgm(progmem_s);
len += pos;
return(len);
}
问题解决了,我还是写出来给大家一个参考.如果大家发帖有问题解决了,也希望大家说说怎么解决的,
不要就只说句"问题解决了".
如果我的问题对你有帮助,请你顶一下. |