Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

使用 RS232及 Hyper Terminal 與 PC 傳送檔案?

89 views
Skip to first unread message

化外一野夫

unread,
Feb 5, 2007, 10:53:00 PM2/5/07
to
各位先進,
工作辛苦了,我有實作RS232及 Hyper Terminal 與 PC 傳送檔案? 由 PC 下傳時,使用 Xmodem-1K/CRC16
的協定,運作是OK的.但我使用相同的 Xmodem-1K/CRC16 方式,上傳檔案.卻一直被 Hyper Terminal 判定 CRC 錯誤.在重送
Packet Number 1 , 10 次後.Hyper Terminal回傳'CAN'指令後 Abort.
相關的程式片斷如下,有請先進前輩指正一下. 而另我一直吶悶的是,上傳下載都使用同樣的 CRC 演算法,卻得到上傳 CRC
錯誤.(但是同樣的CRC演算法,下傳檢查時卻是相符的.)其中必有文章,有請各位先進前輩,給與適當的指點.也感謝您們的協助.讓我能豁然開朗.

後進晚輩:化外一野夫 有請先進前輩 給與指正.

OS: Windows 2000 / HyperTerminal
COM setting : COM1:115200 , 8,n,1,n with XModem-1k/CRC16

int xmodemOut(unsigned int Outbuffer,unsigned int *fileSize)
{
unsigned char ch,Qcrc;
unsigned char packetNo=1;
int i,j;
int startPacket;
unsigned short crc,crc1,error=0;
unsigned long int checksum=0;
// unsigned short crcWord;
int status;
int delayCnt;
int oldDelay;
int count;

startPacket=1;
packetNo=1;
delayCnt=0;
oldDelay=0;
Qcrc=0;
count=(*fileSize);
uprintf("Wait Receiver(%XH Bytes from %08XH) ready to putchar
'C'...\n\n",count,Outbuffer);
calctable();

do
{
if( ukbhit() )
{
ch=ugetchar();
if('C'==ch) Qcrc='C'; break;// else Qcrc=('X');
if( NAK==ch) Qcrc='K'; break;
}
}while(1); // wait Receiver ready to putchar 'C'

delayCnt=0;
oldDelay=0;
packetNo=0x01;
error=0;
count=(*fileSize);
while(count>0x00)
{
if( delayCnt > XMODEM_TIMEOUT_VALUE)
{
status=X_STIMEOUT; uputchar(CANCEL); uputchar(CANCEL);
uputchar(CANCEL); uputchar(CANCEL); uputchar(CANCEL);
uprintf("UpLoad X_STIMEOUT:%c(%2X)",Qcrc,Qcrc); break;
}

#ifdef XMODEM1K
uputchar(STX);
#else
uputchar(SOH);
#endif
uputchar(packetNo);
uputchar((unsigned char)(~packetNo)); //(ch+packetNo)==0xFF
crc=0; crc1=0; checksum=0;
#define readb(addr) (*(unsigned char volatile *)(addr))
#ifdef XMODEM1K
for(i=0;i<1024;i++)
#else
for(i=0;i<128;i++)
#endif
{
if(count>0x00) ch=readb(Outbuffer+i);
else ch=((unsigned char)0x1A); // EOF =0x1A
uputchar(ch);
count--;
checksum+=ch;
j = (crc >> 8) ^ ch;
crc = (crc << 8) ^ crcTable[j];
}
if('C'== Qcrc )
{
ch=(unsigned char)((crc/0x100)&0x00FF);
uputchar(ch); // High First , but PC Host is Big-Endian => So by Low First
ch=(unsigned char)(crc&0x00FF);
uputchar(ch);
}
else { uputchar((unsigned char)(checksum%0x100)); }
do
{
// ch=NAK;
if( ukbhit() ) { ch=ugetchar(); break; } // wait revicer respones
// if(delayCnt++>=0x80000000) break;
}while(1); // wait Receiver ready to putchar 'C'

if(ch==ACK)
{
packetNo++;
#ifdef XMODEM1K
Outbuffer+=1024;
#else
Outbuffer+=128;
#endif
delayCnt=0;
oldDelay=0;
error=0;
}
else if(ch==NAK)
{

#ifdef XMODEM1K
count+=1024;
#else
count+=128;
#endif
delayCnt =(oldDelay+10000);
oldDelay=delayCnt;
error++;
if(error>0x06) if(Qcrc == 'C') Qcrc = 'X'; // igones 'C' and transfer by
CheckSum;
}
else if(ch==CANCEL)
{
error+=10;
#ifdef XMODEM1K
count+=1024;
#else
count+=128;
#endif
if(Qcrc == 'C') Qcrc = 'X'; // igones 'C' and transfer by CheckSum;
else
{ error+=10;
if((error%100)>60)
{
status=X_SUSERCANCEL;
uprintf("\ncancel:Send %dth Packet %2dth
NG:%c(%2X),Count=0x%X/0x%X",packetNo,error,Qcrc,Qcrc,count,(*fileSize));
break;
}
}
}
else //
{
// uputchar(ch);
#ifdef XMODEM1K
count+=1024;
#else
count+=128;
#endif
error+=100;
delayCnt =(oldDelay+10000); oldDelay=delayCnt;
// uprintf("\nch=%c,Count=0x%X:CRC=%c:(%02XH) Ready UpLoad...%dth
error",ch,count,Qcrc,Qcrc,error);
//do{
if( ukbhit() )
{
ch=ugetchar();
if('C'==ch) Qcrc='C'; //break;
if( NAK==ch) Qcrc='K'; //break;
}
//}while(1); // wait Receiver ready to putchar 'C'
} // unknow ch ???
}; // while(count>0x00)

uputchar(EOT);
delayCnt=0;
while( !ukbhit() ); // { if(delayCnt++>=0x80000000) break; };
// status=X_SUSERCANCEL;
// if( ukbhit() )
// {
if( ACK==ugetchar())
{
uputchar(ETB);
delayCnt=0;
while( !ukbhit() ); // { if(delayCnt++>=0x80000000) break; };
if( ukbhit() ) { if(ACK==ugetchar()) status=X_SSUCCESS; }
}
// }
else
{
status=X_SUSERCANCEL;
uputchar(CANCEL);
uputchar(CANCEL);
}
return status;
}

#define CCITT 0x1021
unsigned short _crc(unsigned short n)
{
unsigned short i, acc;

for (n<<=8, acc=0, i=8; i > 0; i--, n<<=1)
acc = ((n^acc) & 0x8000) ? ((acc<<1) ^ CCITT) : (acc<<1);
return (acc);
}

void calctable ()
{
static unsigned char crcTableBuilt=0;
unsigned short i;

if (! crcTableBuilt)
{
crcTableBuilt = 1;
for (i=0; i < 256; i++)
crcTable[i] = _crc (i);
}
}

0 new messages