【问题标题】:serial port reads incorrect data on windows串口在windows上读取不正确的数据
【发布时间】:2014-12-24 18:58:52
【问题描述】:

这个程序是通过串口接收然后发送数据。

设置serial后,从serial中读取一个byte(我用的是putty这个工具来发送chars),如果是'a',从文件中读取16byte然后发送到serial,然后读取a 'b',然后继续字母'p'。总共 16 个循环。

但是现在,我可以让前两个循环工作,当涉及到第三个循环时,在 readfile() 之后,readBuff 是 50h,而它是从串行读取的前 2 个循环,例如“a”、“b”。 它总是在第三个循环失败。

很奇怪,有人知道吗?

hSerial = CreateFile("COM1",                            
        GENERIC_READ | GENERIC_WRITE,       
        0,
        0,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        0
        );

if(hSerial==INVALID_HANDLE_VALUE){
    if(GetLastError()==ERROR_FILE_NOT_FOUND){
        printf("create serial handle file failed!-1");
        return 0;
    }
    printf("create serial handle file failed!-2");
    return 0;
}
DCB dcbSerialParams = {0};
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
dcbSerialParams.fBinary = TRUE;
dcbSerialParams.BaudRate = CBR_9600;
dcbSerialParams.ByteSize   = 8;
dcbSerialParams.StopBits   = ONESTOPBIT;
dcbSerialParams.Parity       = NOPARITY;
if(!SetCommState(hSerial, &dcbSerialParams)){
    printf("set serial state failed");
    return 0;
}
    COMMTIMEOUTS cmt;

cmt.ReadIntervalTimeout = 1;
cmt.ReadTotalTimeoutMultiplier = 100000000;
cmt.ReadTotalTimeoutConstant = 100000000;
cmt.WriteTotalTimeoutConstant = 10;
cmt.WriteTotalTimeoutConstant = 10;

if(!SetCommTimeouts(hSerial, &cmt)){
    printf("set timeout failed");
    return 0;
}
char readBuff; //read 1 byte from serial which indicate the send loop
DWORD dwBytesRead; //number of bytes read from binary
char writeBuff[16]; /*read 16bytes from spd binary to write to serial */
DWORD dwBytesWrite; /*stores actual number of bytes writen*/
for(int i = 0; i<=15; i++){
    //initial the variables to 0 incase some weird behavior
    readBuff = 0; 
    dwBytesRead = 0;
    dwBytesWrite = 0;
    for(int j=0; j<=15; j++)
        writeBuff[j] = 0;

    if(!ReadFile(hSerial, &readBuff, 1 , &dwBytesRead, NULL)){
        if(dwBytesRead != 1){
            printf("read failed, please check!\n");
            return 0;
        }
    }
//when it comes to the 3rd loop, readfile() reads a 50h, even if i didn't send anything to serial line.
    if(readBuff != ('a' + i)){
        printf("failed the %dth loop\n", i);
        return 0;
    }
    else{
        //read spd binary then puts to serial

        if(fread(writeBuff, 1, 16, file) != 16){
            printf("read binary failed, please check!\n");
            return 0;
        }
        //send to serial
        if(!WriteFile(hSerial, writeBuff, 16, &dwBytesWrite, NULL)){
            if(dwBytesWrite != 16){
                printf("write to serial failed, please check!\n");
                return 0;
            }
        }
        printf("%c", readBuff);

    }
}//end of for loop

【问题讨论】:

    标签: c windows winapi serial-port


    【解决方案1】:

    如果 ReadFile 失败,您需要再次读取,直到找到一些有效数据。但是,您检查 dwBytesRead 并根据该变量中的内容决定继续。当 ReadFile 失败时,我不相信 dwBytesRead 包含有效值。假设 UART 读取 1 个字节但出现溢出/帧错误?

    把程序改成

       while(!ReadFile(...))
         ;
    

    【讨论】:

    • 非常感谢@Lundin,我已经尝试过您的建议,确实解决了问题,我将程序更改为连续读取,直到它读取预期的内容,例如,'c' 在那里50 小时后。虽然它仍然收到 50h,但现在它可以按预期工作了。
    • @svenwang 在 ReadFile 返回 true 之前,您根本无法信任输入缓冲区的内容。
    • 虽然对我来说并不重要,但 50h 仍然出现在第三个循环中。这对我来说真的很奇怪,也许我需要更多关于 Windows 串行端口如何工作的知识才能弄清楚。
    • @svenwang 嗯,如果符号之间出现垃圾,则可能存在配置错误或硬件错误。如果您可以使用示波器,请查看数据并确保它具有正确的速度并且没有噪音。还要确保信号地相互连接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    • 2022-12-15
    • 2011-01-22
    • 2011-08-01
    • 1970-01-01
    相关资源
    最近更新 更多