• C++_串口编程_官方示例:监视通信事件


    这是微软官方的一个例子,这个例子中,如果不做修改,那么他是可以异步运行的,会出现一个错误:官方也说了一下,但是不太好懂,我拷贝过来放在这里,作为参考。

    如果无法立即完成重叠的操作,则函数返回 FALSE , GetLastError 函数返回 ERROR_IO_PENDING,指示操作正在后台执行。 发生这种情况时,系统会在 WaitCommEvent 返回之前将 OVERLAPPED 结构的 hEvent 成员设置为非信号状态,然后在发生指定事件或错误之一时将其设置为信号状态。 调用过程可以使用其中一个 等待函数 来确定事件对象的状态,然后使用 GetOverlappedResult 函数来确定 WaitCommEvent 操作的结果。 GetOverlappedResult 报告操作的成功或失败,并将 lpEvtMask 参数指向的变量设置为指示发生的事件。

    总之异步在后台运行的那种,目前是出错,我把它修改为不是异步的方式,修改一下CreateFile()函数就可以了。修改后,这个程序就是同步的模式了,就是会一直处于等待状态,虽然不实用,但是好歹是能用了。下面说说是怎么修改的,具体的一看源代码就懂了。

    首先,需要修改一下事件的类型:

    1. // fSuccess = SetCommMask(hCom, EV_CTS | EV_DSR); //MS code
    2. fSuccess = SetCommMask(hCom, EV_RXCHAR);//改为 EV_RXCHAR事件

    改为比较好懂的:EV_RXCHAR,表示接收到了一个字符并将其放入了输入缓冲区。

    其次,就是修改了CreatFile()函数:

     hCom = CreateFile(TEXT("\\\\.\\COM1"),
            GENERIC_READ | GENERIC_WRITE,
            0,    // exclusive access 
            NULL, // default security attributes 
            OPEN_EXISTING,
            0,//FILE_FLAG_OVERLAPPED,此处修改过,改为了0,具体看文档吧,这个太多内容了。0就是同步的方式了。
            NULL
        );

    再次,添加了一些cout 输出字符串的语句。

    事件代码的具体含义如下:

    含义
    EV_BREAK在输入上检测到一个中断。
    EV_CTSCTS (明送) 信号更改状态。
    EV_DSRDSR (数据集就绪) 信号更改状态。
    EV_ERR发生行状态错误。 行状态错误 CE_FRAME、 CE_OVERRUN和 CE_RXPARITY
    EV_RING检测到振铃指示。
    EV_RLSDRLSD (接收线信号检测) 信号更改状态。
    EV_RXCHAR接收到了一个字符并将其放入了输入缓冲区。
    EV_RXFLAG已接收事件字符并将其放置在输入缓冲区中。 事件字符在设备的 DCB 结构中指定,该结构使用 SetCommState 函数应用于串行端口。
    EV_TXEMPTY输出缓冲区中的最后一个字符已发送。

    完整的源代码如下:

    1. // WatchCommunicationEventTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
    2. //
    3. #include <iostream>
    4. #include <windows.h>
    5. #include <tchar.h>
    6. #include <assert.h>
    7. #include <stdio.h>
    8. int main()
    9. {
    10. // std::cout << "Hello World!\n";
    11. HANDLE hCom;
    12. OVERLAPPED o;
    13. BOOL fSuccess;
    14. DWORD dwEvtMask;
    15. hCom = CreateFile(TEXT("\\\\.\\COM1"),
    16. GENERIC_READ | GENERIC_WRITE,
    17. 0, // exclusive access
    18. NULL, // default security attributes
    19. OPEN_EXISTING,
    20. 0,//FILE_FLAG_OVERLAPPED,此处修改过,改为了0,具体看文档吧,这个太多内容了。0就是同步的方式了。
    21. NULL
    22. );
    23. if (hCom == INVALID_HANDLE_VALUE)
    24. {
    25. // Handle the error.
    26. printf("CreateFile failed with error %d.\n", GetLastError());
    27. return 2;
    28. }
    29. // Set the event mask.
    30. //此处修改过
    31. // fSuccess = SetCommMask(hCom, EV_CTS | EV_DSR); //MS code
    32. fSuccess = SetCommMask(hCom, EV_RXCHAR);//改为 EV_RXCHAR事件
    33. if (!fSuccess)
    34. {
    35. // Handle the error.
    36. printf("SetCommMask failed with error %d.\n", GetLastError());
    37. return 1;
    38. }
    39. // Create an event object for use by WaitCommEvent.
    40. o.hEvent = CreateEvent(
    41. NULL, // default security attributes
    42. TRUE, // manual-reset event
    43. FALSE, // not signaled
    44. NULL // no name
    45. );
    46. // Initialize the rest of the OVERLAPPED structure to zero.
    47. o.Internal = 0;
    48. o.InternalHigh = 0;
    49. o.Offset = 0;
    50. o.OffsetHigh = 0;
    51. assert(o.hEvent);
    52. //下面的cout 也是博主自己加的,看到输出字符就是成功了
    53. if (WaitCommEvent(hCom, &dwEvtMask, &o))
    54. {
    55. if (dwEvtMask & EV_DSR)
    56. {
    57. std::cout << "EV_DSR event is happening";
    58. }
    59. if (dwEvtMask & EV_CTS)
    60. {
    61. std::cout << "EV_CTS event is happening";
    62. }
    63. if(dwEvtMask & EV_RXCHAR)
    64. {
    65. std::cout << "EV_RXCHAR event is happening";
    66. }
    67. }
    68. else
    69. {
    70. DWORD dwRet = GetLastError();
    71. if (ERROR_IO_PENDING == dwRet)
    72. {
    73. printf("I/O is pending...\n");
    74. // To do.
    75. }
    76. else
    77. printf("Wait failed with error %d.\n", GetLastError());
    78. }
    79. return 0;
    80. }

     运行程序:首先是出现一个命令行窗口,啥也没有

     用VSPD 和 XCOM V2.6 创建虚拟的COM串口后,可以用XCOM 创建一个 从COM2 发送文本到COM1的操作,之后就有输出了,这个EV_RXCHAR事件发生了。

    后续还可以多研究研究,作为一个最权威,最基本的例子,这个作为入门我觉得很不错,推荐给大家。

  • 相关阅读:
    软件测试常用的8种功能测试类型有哪些?
    站长号动态:手机端个人签名同步显示
    工程制造领域:企业IT架构
    无涯教程-JavaScript - IMLOG10函数
    java中获取主机信息InetAddress类的两种方法
    阿里图标库在旧有的iconfont中添加新的图标
    哪款蓝牙耳机听歌音质好?蓝牙耳机音质排行榜
    docker的再定义镜像和上传阿里云
    使用vue-cli来搭建vue项目
    十大经典排序算法——java语言
  • 原文地址:https://blog.csdn.net/superfreak/article/details/128067547