繁体   English   中英

正确读取或编写串口Windows API

[英]correctly reading or writing serial port Windows API

我已经阅读了很多串口读写问题。 到目前为止,没有人帮我弄清楚我的代码缺失了什么。 c ++的msdn示例有未定义的变量和缺少括号,所以虽然我可以添加括号但它仍然不起作用。 这就是我现在所拥有的。 看来我可以打开端口并进行配置,但我无法读取数据的字节/字符。 我真的只想要一个简单的异步串行读/写,以便程序从Arduino读取。

class MY_SERIAL
{

HANDLE serialinstance;

DWORD      dwStoredFlags;
DWORD      dwRes;
DWORD      dwCommEvent;
OVERLAPPED osStatus = {0};
BOOL       fWaitingOnStat;
//dwStoredFlags = EV_BREAK | EV_CTS   | EV_DSR | EV_ERR | EV_RING | EV_RLSD | EV_RXCHAR |      EV_RXFLAG | EV_TXEMPTY ;


DCB dcb;
COMMTIMEOUTS timeouts;

COMMCONFIG serialconfig;



public:
char inBuffer[1000];
char outBuffer[100];

PDWORD noBytes;

void close_serial()
{
    CloseHandle(serialinstance);
}
//----------------------------------------------------
bool open_serial(LPCSTR portNumber)   // serial port name use this format  "\\\\.\\COM10"
{

    serialinstance = CreateFile(portNumber, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
    if(serialinstance == INVALID_HANDLE_VALUE)
    {
        int error = GetLastError();
        printf("ERROR opening serial port  %s\r\n", portNumber);
        if(error == 0x2){printf("ERROR_FILE_NOT_FOUND\r\n");}
        if(error == 0x5){printf("ERROR_ACCESS_DENIED\r\n");}
        if(error == 0xC){printf("ERROR_INVALID_ACCESS\r\n");}
        if(error == 0x6){printf("ERROR_INVALID_HANDLE\r\n");}
        printf("error code %d\r\n", error);
        return false;
    }
    if(GetCommState(serialinstance, &dcb)!= true)
    {
        printf("ERROR getting current state of COM   %d \r\n", GetLastError());
        return false;
    }
    else{printf("debug   read current comstate\r\n");}


    FillMemory(&dcb, sizeof(dcb), 0); //zero initialize the structure
    dcb.DCBlength = sizeof(dcb);      //fill in length

    dcb.BaudRate = CBR_115200;     //  baud rate
    dcb.ByteSize = 8;             //  data size, xmit and rcv
    dcb.Parity   = NOPARITY;      //  parity bit
    dcb.StopBits = ONESTOPBIT;

    if(SetCommState(serialinstance, &dcb) != true)
    {
        printf("ERROR setting new state of COM   %d \r\n", GetLastError());
        return false;
    }
    else{printf("debug   set new comstate\r\n");}
    /*
    if (!BuildCommDCB("115200,n,8,1", &dcb)) //fills in basic async details
    {
        printf("ERROR getting port comstate\r\n");
        return FALSE;
    }
    */
    if (!SetCommMask(serialinstance, EV_RXCHAR))
    {
        printf("ERROR setting new COM MASK   %d \r\n", GetLastError());
        return false;
    }
    else{printf("debug   commmask set\r\n");}
    timeouts.ReadIntervalTimeout = MAXDWORD;
    timeouts.ReadTotalTimeoutMultiplier = 20;
    timeouts.ReadTotalTimeoutConstant = 0;
    timeouts.WriteTotalTimeoutMultiplier = 0;
    timeouts.WriteTotalTimeoutConstant = 0;

    if (!SetCommTimeouts(serialinstance, &timeouts))
    {
        printf("ERROR setting timeout parameters\r\n");
        return false;
    }
    else{printf("debug   timeouts set\r\n");}
    osStatus.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (osStatus.hEvent == NULL)
    {// error creating event; abort
        printf("ERROR creating Serial EVENT\r\n");
        return false;
    }
    else{printf("debug   event created set\r\n");}
    osStatus.Internal = 0;
    osStatus.InternalHigh = 0;
    osStatus.Offset = 0;
    osStatus.OffsetHigh = 0;
    assert(osStatus.hEvent);
    printf("debug   com port setting complete\r\n");






    return true;
}
//---------------------------------------------------------

bool read_serial_simple()
{
    char m[1000];
    LPDWORD bytesRead;



    if (WaitCommEvent(serialinstance, &dwCommEvent, &osStatus))
    {
        if(dwCommEvent & EV_RXCHAR)
        {
            ReadFile(serialinstance, &m, 1, bytesRead, &osStatus);
            printf("data read =   %d,       number bytes read =     %d  \r\n", m, bytesRead);
            return true;
        }
        else
        {
            int error = GetLastError();
            if(error == ERROR_IO_PENDING){printf(" waiting on incomplete IO\r\n");}
            else{printf("ERROR %d\r\n", error);}
            return false;
        }
    }
    return false;
}

};

所以我删除了读取功能。 我现在得到一个char,它报告读取1个字节,但char的值不正确。 我得到一系列48,13,10,偶尔为该字节的50值。 然而,Arduino正在发送一个0系列,然后是TerraTerm验证的128系列。 我还需要什么呢?

bool read_serial_simple()
{
    unsigned char m = 0;
    DWORD bytesRead;
    if(ReadFile(serialinstance, &m, 1, &bytesRead, &osStatus) == true)
    {
        printf("data read =   %d,       number bytes read =     %d  \r\n", m, bytesRead);
        return true;
    }
    else{
        int error = GetLastError();
        if(error == ERROR_IO_PENDING){printf(" waiting on incomplete IO\r\n");}
        else{printf("ERROR %d\r\n", error);}
        return false;
    }

}

所以现在我可以读取一个字节的数据,但我不能写一个字节或更多的字节到端口。 我刚收到ERROR_IO_PENDING。 也有人可以帮忙解决这个问题。 写下我班级的功能。

bool write(DWORD noBytesToWrite)
{
    if(WriteFile(serialinstance, outBuffer, noBytesToWrite, NULL, &osStatus) == true)
    {
        printf("message sent\r\n");
        return true;
    }
    else
    {
        int error = GetLastError();
        if(error != ERROR_IO_PENDING){LastError();}
        return false;
    }
}

我正在调用main中的两个函数,如下所示

myserial.open_serial(COM12);
myserial.outBuffer[0] = 'H';
myserial.outBuffer[1] = 'e';
myserial.outBuffer[2] = 'L';
myserial.outBuffer[3] = 'l';
myserial.outBuffer[4] = 'O';
for(int n=0; n<5; n++){printf("%c", myserial.outBuffer[n]);}
printf("\r\n");

while(1)
{
    myserial.read();
    myserial.write(5);
    //system("PAUSE");
}

目前,arduino设置为读入字节并重复它们返回到pc。 它在arduino IDE串行监视器上做得很好,所以现在我只需要让这个pc程序写出来。

您的bytesRead变量是一个未初始化的指针。 您正在将无效地址传递给ReadFile()以进行写入。

LPDWORD bytesRead替换为DWORD bytesRead ,然后使用&bytesRead将其传递给ReadFile()

编辑:还消除FILE_FLAG_OVERLAPPED 您没有正确处理它,如果您在阅读之前使用WaitForSingleObject() ,则没有必要使用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM