C 校验和与串口通信

C 校验和与串口通信,c,string,serial-port,checksum,C,String,Serial Port,Checksum,我正在尝试从USB到串行端口转换器发送一条带有校验和的消息,然后再发送回来。 但我不能让它工作,因为某些原因,甚至艰难,我已经尝试了一个洞一天。我开始觉得硬件有问题,但我想在放弃之前问问你们是个好主意。。。我正在使用cygwin在windows计算机上执行和编译程序 我本想在程序运行时附上终端的图片,但您的声誉必须大于10,而我不是:(.因此,我将不得不描述它。。。。。 当我尝试发送“a”时,我从终端获得以下信息 输入消息:a 要发送的邮件的校验和为:97 您要发送的消息是:a a@ 收到消息的

我正在尝试从USB到串行端口转换器发送一条带有校验和的消息,然后再发送回来。 但我不能让它工作,因为某些原因,甚至艰难,我已经尝试了一个洞一天。我开始觉得硬件有问题,但我想在放弃之前问问你们是个好主意。。。我正在使用cygwin在windows计算机上执行和编译程序

我本想在程序运行时附上终端的图片,但您的声誉必须大于10,而我不是:(.因此,我将不得不描述它。。。。。 当我尝试发送“a”时,我从终端获得以下信息

输入消息:a
要发送的邮件的校验和为:97
您要发送的消息是:a
a@
收到消息的校验和为:97
消息未被正确接收!
您收到以下消息:a
a@

我收到了发送的内容,但“a”的校验和应该是“a”,对吗?因此应该发送的字符串是“aa”而不是“a
或者我在这里完全迷路了

我已经附上了下面代码的相关部分(printWhite()等。更改文本的颜色,仅此而已)

void main(){
常客();
regularReceive();
}
void regularSend(){
char-buff2s[20];
计算的无符号字符数;
printf(“输入消息:”);
fgets(buff2s,15,stdin);//从键盘输入字符串
calculatedCS=校验和(buff2s,strlen(buff2s));
printf(“要发送的邮件的校验和为:%i\n”,calculatedCS);
buff2s[strlen(buff2s)]=calculatedCS;//添加校验和
buff2s[strlen(buff2s)]='\0';//添加新的字符串终止符
printf(“您要发送的消息是:%s\n”,buff2s);
字节写入=写入(fd、buff2s、strlen(buff2s));
睡眠(1);
}
void regularReceive(){
无符号字符buffer[20];
无符号字符rCS;
字节_read=read(fd,buffer,sizeof(buffer)-1);
if(strlen(buffer)
坏的:-(

仅仅因为你的字符串有一个空终止符并不意味着它是空的。你的第一个“strlen”告诉你当前的结束符在哪里。你用校验和覆盖它,但是“新终止符”可能在任何地方。改为这样做

 int len = strlen(buff2s);
 buff2s[len]=calculatedCS; //adds a checksum
 buff2s[len+1]='\0'; //adds a new string terminator

(理想情况下,还要检查缓冲区溢出…

正如@Roddy指出的,代码不好,因为它用校验和覆盖字符串的
\0
,然后尝试在可能未终止的字符串的下一行中查找字符串长度

buff2s[strlen(buff2s)]=calculatedCS; //adds a checksum
buff2s[strlen(buff2s)]='\0'; //adds a new string terminator
建议:

size_t len = strlen(buff2s);
calculatedCS = checkSum(buff2s, len);
buff2s[len] = calculatedCS; //adds a checksum
buff2s[++len] = '\0'; //adds a new string terminator
bytes_written=write(fd, buff2s, len + 1);  
由于使用字符串,请更改校验和生成器和检查器,以确保它不会创建
“\0”

unsigned char checkSum(char buff[], size_t nbrOfBytes){
    size_t ic;
    unsigned int t_cSum = 0;
    for (ic=0; ic<nbrOfBytes-1; ic++){
        t_cSum += buff[ic];
    }
    return (unsigned char) (t_cSum % 255 + 1);
}

意见:如果要添加校验码,考虑32位CRC,而不是简单的校验和。在256个校验和错误中,字节校验和不能表示一次错误。我更喜欢1的40亿的失败率。CRC还检查更广泛的错误类型,如添加/丢失<代码> \ 0 < /代码>。
size_t len = strlen(buff2s);
calculatedCS = checkSum(buff2s, len);
buff2s[len] = calculatedCS; //adds a checksum
buff2s[++len] = '\0'; //adds a new string terminator
bytes_written=write(fd, buff2s, len + 1);  
unsigned char checkSum(char buff[], size_t nbrOfBytes){
    size_t ic;
    unsigned int t_cSum = 0;
    for (ic=0; ic<nbrOfBytes-1; ic++){
        t_cSum += buff[ic];
    }
    return (unsigned char) (t_cSum % 255 + 1);
}
bytes_read = read(fd, buffR, sizeof(buffR)-1);
if(strlen(buffR)<1){