如何使用 win32 api 从串行端口以正确的顺序读取两个字节?

发布于 2024-10-13 11:17:58 字数 3022 浏览 2 评论 0原文


我正在使用win32 api,Visual Studio 2008。我能够从串行端口读取字节,但不是我想要的方式,我以x,y格式从arduino传递数据。但我下面的代码有时先读 y,然后读 x。我怎样才能以正确的顺序读取数据,我的意思是按x,y顺序。如果有人感兴趣,坐标将被传递到另一个函数,并且鼠标光标将相应移动。这是我的代码:

int _tmain( int argc, TCHAR *argv[] )

{   
    HANDLE hComm;
    DWORD bytesRead = 0;
    POINT mouseCoords;  /*structur to hold mouse coordinates*/
    DCB dcb = {0};      /*Device Control Block, used to configure serial port settings
                          here we initialize dcb structure to zero. Good practice!*/
    COMMTIMEOUTS ct;

    int loop = 1;
    int counter = 10;

    /*get handle to serial port*/
    hComm = CreateFile(g_pcCommPort, 
                       GENERIC_WRITE | GENERIC_READ,
                       0,                           /* must be opened with exclusive-access */
                       NULL,                        /* default security attributes*/
                       OPEN_EXISTING,               /*  must use OPEN_EXISTING for serial ports*/
                       0,                           /*non overlapped I/O, blocking*/
                       NULL );                      /*hTemplate must be NULL for comm devices*/

    /*Make sure that serial port is successfuly opened*/
    if ( hComm == INVALID_HANDLE_VALUE ) {
            errMsg(TEXT("Cannot access serial port!"));
        return 0;   
    }

    ASSERT("Serial port access successful!");

    /*get serial port status i.e default settings and make
      sure we can access them*/
    if ( !(GetCommState(hComm, &dcb))) {
        errMsg(TEXT("Cannot access current DCB settings!"));
        return 0;
    }

    ASSERT("DCB settings access successful!");

    /*print dcb settings so that we can get an idea of default settings*/
    printCommSettings(dcb);


    /*Since we were successful in accessing the com port
      we can go ahead and set it manually to our desired
      settings*/
    if ( !(setupSerialPort(&dcb))) {
        errMsg(TEXT("Cannot setup serial port!"));
        return 0;
    }

    ASSERT("DCB config successful!");


    /*lets print configuration after setting up the
      serial port just to make sure everything is ok*/
    printCommSettings(dcb);

    ct.ReadIntervalTimeout = 50;
    ct.ReadTotalTimeoutConstant = 50;
    ct.ReadTotalTimeoutMultiplier = 10;
    ct.WriteTotalTimeoutConstant = 50;
    ct.WriteTotalTimeoutMultiplier = 10;

    if(SetCommTimeouts(hComm, &ct) == 0) {
         errMsg(TEXT("Cannot setup comm timout!"));
    }

while (loop) 
{
  if ( !(ReadFile(hComm,g_buffer,5,&bytesRead,NULL)) ) {    loop = 0; }
    printf("Message Read: %s==%d\r", g_buffer, bytesRead);

} /*while loop*/


    if ( !(CloseHandle(hComm))) {
        errMsg(TEXT("Serial port handle error!"));
    }

    NEWLINE;

    return 0;
}

编辑: 这些是串行端口设置: “9600,N,8,1”

我传入 10,12,这就是我得到的: 输出:
消息已读: ,12
留言已读:10,12
消息已读:12
消息已读:0,12
已读消息:2
消息已读: ,12
留言已读:10,12
消息已读:12
消息已读:0,12
已读消息:2
消息已读: ,12
消息阅读:10,12

I am using using win32 api, visual studio 2008. i am able to read bytes from serial port but not the way i intend it to be, I am passing in data from arduino in x,y format. But my code below sometimes read y first then x. How can i read data in the correct order, i mean in x,y order. in case anyone is interested coordinates will be passed to another function and mouse cursor will be move accordingly. Here is my code:

int _tmain( int argc, TCHAR *argv[] )

{   
    HANDLE hComm;
    DWORD bytesRead = 0;
    POINT mouseCoords;  /*structur to hold mouse coordinates*/
    DCB dcb = {0};      /*Device Control Block, used to configure serial port settings
                          here we initialize dcb structure to zero. Good practice!*/
    COMMTIMEOUTS ct;

    int loop = 1;
    int counter = 10;

    /*get handle to serial port*/
    hComm = CreateFile(g_pcCommPort, 
                       GENERIC_WRITE | GENERIC_READ,
                       0,                           /* must be opened with exclusive-access */
                       NULL,                        /* default security attributes*/
                       OPEN_EXISTING,               /*  must use OPEN_EXISTING for serial ports*/
                       0,                           /*non overlapped I/O, blocking*/
                       NULL );                      /*hTemplate must be NULL for comm devices*/

    /*Make sure that serial port is successfuly opened*/
    if ( hComm == INVALID_HANDLE_VALUE ) {
            errMsg(TEXT("Cannot access serial port!"));
        return 0;   
    }

    ASSERT("Serial port access successful!");

    /*get serial port status i.e default settings and make
      sure we can access them*/
    if ( !(GetCommState(hComm, &dcb))) {
        errMsg(TEXT("Cannot access current DCB settings!"));
        return 0;
    }

    ASSERT("DCB settings access successful!");

    /*print dcb settings so that we can get an idea of default settings*/
    printCommSettings(dcb);


    /*Since we were successful in accessing the com port
      we can go ahead and set it manually to our desired
      settings*/
    if ( !(setupSerialPort(&dcb))) {
        errMsg(TEXT("Cannot setup serial port!"));
        return 0;
    }

    ASSERT("DCB config successful!");


    /*lets print configuration after setting up the
      serial port just to make sure everything is ok*/
    printCommSettings(dcb);

    ct.ReadIntervalTimeout = 50;
    ct.ReadTotalTimeoutConstant = 50;
    ct.ReadTotalTimeoutMultiplier = 10;
    ct.WriteTotalTimeoutConstant = 50;
    ct.WriteTotalTimeoutMultiplier = 10;

    if(SetCommTimeouts(hComm, &ct) == 0) {
         errMsg(TEXT("Cannot setup comm timout!"));
    }

while (loop) 
{
  if ( !(ReadFile(hComm,g_buffer,5,&bytesRead,NULL)) ) {    loop = 0; }
    printf("Message Read: %s==%d\r", g_buffer, bytesRead);

} /*while loop*/


    if ( !(CloseHandle(hComm))) {
        errMsg(TEXT("Serial port handle error!"));
    }

    NEWLINE;

    return 0;
}

EDIT:
these are serial port settings:
"9600,N,8,1"

I am passing in 10,12 and this is what i am getting:
OUTPUT:
Message Read: ,12
Message Read: 10,12
Message Read: 12
Message Read: 0,12
Message Read: 2
Message Read: ,12
Message Read: 10,12
Message Read: 12
Message Read: 0,12
Message Read: 2
Message Read: ,12
Message Read: 10,12

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

毁梦 2024-10-20 11:17:58

看起来您发现您没有通过串行端口传递两个字节,但实际上您正在发送 ASCII。根据您的示例输出,我没有看到 Y 在 X 之前出现(这将显示为 12,10 而不是 10,12

实际上是什么发生的情况是,读取并不总是在您期望的时候完成,您在一次读取中获得了部分消息,而在下一次读取中获得了下一部分,

您需要将传输与某些未找到的字符同步 。例如,如果您发送了 (10,12) 那么您就会知道 ( 是您的数字的开头,而 )( 后跟一个 ) 然后解析它们之间的字符,并丢弃该部分。以 ) 字符结尾的缓冲区。

It looks like you figured out that you're not passing two bytes across the serial port, but in fact you're sending ASCII. And based on your sample output, I don't see the Y coming in before the X (that would show up as 12,10 instead of 10,12.

What's actually happening is that the reads are not always completing when you expect them to. You get part of the message in one read and the next part in the next read.

What you need to do is synchronize the transmission with some character(s) not found in your message text. For example, if you sent (10,12) then you would know that the ( was the start of your numbers and ) was the end. That way you could read enough characters in your buffer until you had a ( followed by a ) then parse the characters between them, and discard the part of the buffer ending in the ) character.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文