<br />遵循xmodem协议给PC发数据,超级终端接收时,每次都要重试2次才能收到数据,不知道该测试代码哪里有问题,望指教!谢谢!<br /><br /><br />/***************************************************************<br />*<br />* xmodem 发送函数<br />*<br />1.程序开始时,会循环等待NAK的到来,只要收到的不是NAK,<br />就会一直等待下去,直到收到了NAK,才开始数据的发送;<br />2.上一轮如果发送的是一组数据,则收到CAN,程序就中止;<br />收到ACK,就发送下一组数据;收到NAK,就发送上一组数据;<br />如果收到的不是上面三种,程序就返回,直到出现三个中的某一个;<br />3.上一轮如果发送的是EOT,收到CAN就中止;收到ACK,就结束程序;<br />收到NAK,就再发送EOT;收到的是其他数据就返回,直到出现三个中的某一个。<br />***************************************************************/<br /><br />#define filesize 512<br /><br />U8 Filesend[filesize]={1,2,1,2,1,2,5,2,5,4,5,8,5,5,2,4,5}; //要发送的数据<br />U8 Datasend[132]; //数据包结构。分别为SOH、包序号、序号补码、5字节数据、校验码<br /><br />U8 seq =1 ; //数据包序号<br />U8 seqrev ; //数据包的反码<br />U8 sum = 0; //累加效验码<br />U8 flag_pc; //接收标志<br />U8 k = 0; //指向FileSend的标号,从中取数据时使用,初值为0<br />U8 j = 0; //指向DataSend的标号,发送数据时使用,初值为0<br />U8 fin_flag = 0; //数据取完的标志,为1时表示FileSend中的数据已经取完 <br />U8 eot_flag = 0; //发送完成的标志,为1时表示430已经发送过了EOT标志<br /><br />void dely1(U32 tt)<br />{<br /> U32 i;<br /> for(;tt>0;tt--)<br /> {<br /> for(i=0;i<1000000;i++){}<br /> }<br />}<br /><br /><br />void Xmodemsend()<br />{<br /> flag_pc = Uart_get();<br /> <br /> puts("*********Xmodemsend********************
");<br /><br /> if(flag_pc == CAN)<br /> { <br /> rGPFDAT = rGPFDAT & 0xffffffdf; /*led 2*/<br /> rGPFDAT = rGPFDAT | 0x000000d0;<br /> dely1(10); <br /> puts("传输结束
");<br /> return;<br /> }<br /> <br /> if(k == 0) /*判断是否是第一次接收*/<br /> {<br /> if(NAK == flag_pc) /*收到NAK则开始发送第一组数据,收到的不是NAK则返回继续等待NAK*/<br /> { <br /> seqrev = 0xff - seq; /*取反码*/<br /> for(; k<128; k++)<br /> sum += Filesend[k] ; /*计算累加和*/<br />/*取数据包*/<br /> Datasend[0] = SOH ;<br /> Datasend[1] = seq ;<br /> Datasend[2] = seqrev; <br /> for(k=0; k<128; k++)<br /> Datasend[3+k] = Filesend[k];<br /> Datasend[131] = sum;<br /><br />/*发数据包*/ <br /> while(j<132)<br /> {<br /> Uart_send(Datasend[j]);<br /> j++;<br /> }<br /> // k = k + 128; /*指向下一组数据*/<br /> seq++; /*数据包序号加1*/<br /> j=0;<br /> sum=0;<br /> return;/*返回,下面语句不执行*/<br /> }<br /> }<br /><br /> if(k !=0) /*k!=0,表示已经发送过了数据包,接收到的是PC对数据包的确认命令*/<br /> { <br /> if(NAK == flag_pc) /* PC发回NAK,则把刚才发送的数据包重新发送一遍*/<br /> {<br /> if(eot_flag == 1) /*如果刚才发送的不是数据,而是EOT,则再将EOT重新发*/<br /> {<br /> Uart_send(EOT);<br /> eot_flag=1;<br /> return;<br /> }<br />/*重新发数据包*/ <br /> while(j<132)<br /> {<br /> Uart_send(Datasend[j]);<br /> j++;<br /> } <br /> j =0;<br /> }<br /> if(ACK == flag_pc)<br /> {<br /> if(eot_flag==1) /*表明刚才发送的是EOT,此时PC发回的ACK是对刚才发送的EOT的确认,程序完*/<br /> {puts("END
");<br /> return;<br /> }<br /> else if(fin_flag == 1)/*表明刚才发送的是最后一个数据包<br /> //此时PC发回的ACK是对刚才发送的最后一个数据包的确认<br /> //数据发送完成,发送EOT,返回等待确认*/<br /> {Uart_send(EOT);<br /> eot_flag =1 ;<br /> }<br /> else /*发下一包数据*/<br /> {<br /> seqrev = 0xFF - seq ;<br /> <br /> for(; k<k+128; k++)<br /> sum+=Filesend[k];<br /> k=k-128;<br />/*取数据包*/<br /> Datasend[0] = SOH ;<br /> Datasend[1] = seq ;<br /> Datasend[2] = seqrev; <br /> for(; k<k+128; k++)<br /> Datasend[3+k] = Filesend[k];<br /> Datasend[131] = sum; <br />/*发数据包*/ <br /> while(j<132)<br /> {<br /> Uart_send(Datasend[j]);<br /> j++;<br /> }<br /> seq++;<br /> j=0;<br /> sum=0;<br /> if(k==512){<br /> fin_flag =1;<br /> puts("发送完成
"); <br /> }<br /> <br /> <br /> <br /> }<br /> }<br /> <br /> <br /> }<br /><br /> <br />}<br /><br /><br /> |
|