【问题标题】:Serial communication not working. Readfile goes wrong串行通信不起作用。读取文件出错
【发布时间】:2012-04-24 23:05:32
【问题描述】:

经过数小时的浏览和阅读,我仍然无法弄清楚为什么我的代码无法正常工作。我在不同的网站上看到了类似的代码 sn-ps,但我似乎无法让它工作。写作部分正常,但阅读出错。每个“真实字符”后跟三个空终止符。写一个 19 个字符的字符串是可行的,我使用的 FPGA 在显示屏上给出了正确的数据。 FPGA 应该反转输入并将这个包发送到串行端口。在超级终端中,这可以正常工作。

有人可以指出我的错误并告诉我我做错了什么吗?

提前致谢 =)

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include    <commdlg.h>
//#include  <windef.h>
#define    BUFFERLENGTH 19

void writeToSerial(char *line, HANDLE hSerial, DWORD dwBytesWritten);
void printBuffer(char * buffRead, DWORD dwBytesRead);


int main(){
    HANDLE hSerial;
    COMMTIMEOUTS timeouts;
    COMMCONFIG dcbSerialParams;
    char *line, *buffWrite, *buffRead;
    DWORD dwBytesWritten, dwBytesRead;
    /* Create a handle to the serial port */    
    hSerial = CreateFile("COM3",
                            GENERIC_READ | GENERIC_WRITE,
                            0,
                            NULL,
                            OPEN_EXISTING,
                            FILE_ATTRIBUTE_NORMAL,
                            NULL);
    /* Check if the handle is valid */                        
    if(hSerial == INVALID_HANDLE_VALUE){
       if(GetLastError() == ERROR_FILE_NOT_FOUND){
          printf("Serial port does not exist \n");
       }else{
          printf("Port occupied. Please close terminals!\n");
       }
    }else{
       printf("Handle created\n");    
       /* Check the state of the comm port */
       if(!GetCommState(hSerial, &dcbSerialParams.dcb)){
          printf("Error getting state \n");
       }else{
          printf("Port available\n"); 
          /* Configure the settings of the port */
          dcbSerialParams.dcb.DCBlength = sizeof(dcbSerialParams.dcb);
          /* Basic settings */    
          dcbSerialParams.dcb.BaudRate = CBR_57600;
          dcbSerialParams.dcb.ByteSize = 8;
          dcbSerialParams.dcb.StopBits = ONESTOPBIT;
          dcbSerialParams.dcb.Parity = NOPARITY;
          /* Misc settings */
          dcbSerialParams.dcb.fBinary = TRUE;
          dcbSerialParams.dcb.fDtrControl = DTR_CONTROL_DISABLE;
          dcbSerialParams.dcb.fRtsControl = RTS_CONTROL_DISABLE;
          dcbSerialParams.dcb.fOutxCtsFlow = FALSE;
          dcbSerialParams.dcb.fOutxDsrFlow = FALSE;
          dcbSerialParams.dcb.fDsrSensitivity= FALSE;
          dcbSerialParams.dcb.fAbortOnError = TRUE;
          /* Apply the settings */
          if(!SetCommState(hSerial, &dcbSerialParams.dcb)){
            printf("Error setting serial port state \n");
          }else{
            printf("Settings applied\n");  
            GetCommTimeouts(hSerial,&timeouts);
              //COMMTIMEOUTS timeouts = {0};
            timeouts.ReadIntervalTimeout = 50;
            timeouts.ReadTotalTimeoutConstant = 50;
            timeouts.ReadTotalTimeoutMultiplier = 10;
            timeouts.WriteTotalTimeoutConstant = 50;
            timeouts.WriteTotalTimeoutMultiplier= 10;

            if(!SetCommTimeouts(hSerial, &timeouts)){
                  printf("Error setting port state \n");
            }else{
                /* Ready for communication */
                line = "Something else\r";
                //****************Write Operation*********************//
                writeToSerial(line, hSerial, dwBytesWritten);
                //***************Read Operation******************//
                if(ReadFile(hSerial, buffRead, BUFFERLENGTH, &dwBytesRead, NULL)){
                   printBuffer(buffRead, dwBytesRead);                     
                }
             }          
          }
       }
    }
    CloseHandle(hSerial);
    system("PAUSE");
    return 0;

}
void printBuffer(char * buffRead, DWORD dwBytesRead){
     int j;
     for(j = 0; j < dwBytesRead; j++){
         if(buffRead[j] != '\0'){    
           printf("%d: %c\n", j, buffRead[j]);
         }
     }   
}

void writeToSerial(char *line, HANDLE hSerial, DWORD dwBytesWritten){
    WriteFile(hSerial, line, 19, &dwBytesWritten,NULL);
    if(dwBytesWritten){
       printf("Writing success, you wrote '%s'\n", line);
    }else{
       printf("Writing went wrong =[\n");      
    }
}

【问题讨论】:

    标签: c winapi serial-port readfile fpga


    【解决方案1】:

    超级终端可能不显示空字符,因此您的 fpga 可能实际上正在发送它们。

    您可以尝试在十六进制模式下使用 Br@y 终端对其进行测试,或者使用示波器查看线路。

    【讨论】:

    • 在 Br@y 终端中,我确实看到了 3 个空字符,它们没有出现在超级终端中。由于我使用的是 USB 电缆,因此我无法查看哪个示波器。我猜我在 FPGA 上的 echo 程序当时不能正常工作,所以我应该先修复它,然后才能让它在 C 中工作..
    【解决方案2】:

    在这一行:

    if(ReadFile(hSerial, buffRead, BUFFERLENGTH, &dwBytesRead, NULL))
    

    buffRead 参数是一个未初始化的指针。将声明更改为:

    char *line, *buffWrite, buffRead [BUFFERLENGTH+1];
    

    【讨论】:

    • 感谢您的回复。我现在预先分配内存。 char line[BUFFERLENGTH]; char buffWrite[BUFFERLENGTH]; char buffRead[BUFFERLENGTH+1]; 但这并没有改变任何东西。问题是我只为串行的输出分配了 BUFFERLENGTH+1。由于它在每个“真实”字符之后包含“\0\0\0”,因此长度为 19 的输入不适合长度为 19+1 的缓冲区。我认为它需要 (BUFFERLENGTH*4)-4 字符,但这太大了。之后我想通过忽略“\0”将“脏缓冲区”清理为新字符串来纠正空字符,但这似乎不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-29
    • 1970-01-01
    • 2012-11-25
    • 2013-10-02
    • 1970-01-01
    • 2014-11-17
    相关资源
    最近更新 更多