Windows串口编程
+ -

WaitCommEvent、SetCommMask方式串口收发数据

2023-06-15 79 0

以下是一个使用WaitCommEvent函数的简单的win32串口通信程序,该程序使用了Windows API中的CreateFile、SetCommTimeouts、SetCommState、.WriteFile和ReadFile等函数来进行串口通信。

#include <windows.h>
#include <stdio.h>

// 定义串口句柄
HANDLE hSerial;

// 定义接收线程函数
DWORD WINAPI receiveThread(LPVOID lpParameter)
{
    // 定义变量用于读取串口数据
    char buffer[1024];
    DWORD bytesRead;

    // 设置串口事件掩码
    SetCommMask(hSerial, EV_RXCHAR);

    // 等待串口事件
    while (true)
    {
        DWORD dwEventMask;
        if (WaitCommEvent(hSerial, &dwEventMask, NULL))
        {
            if (dwEventMask & EV_RXCHAR)
            {
                // 从串口读取数据
                if (ReadFile(hSerial, buffer, sizeof(buffer), &bytesRead, NULL))
                {
                    // 打印收到的数据
                    printf("Received data: %s\n", buffer);
                }
            }
        }
    }
}

int main()
{
    // 打开串口
    hSerial = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if (hSerial == INVALID_HANDLE_VALUE)
    {
        printf("Failed to open serial port!\n");
        return 1;
    }

    // 配置串口参数
    DCB serialParams = { 0 };
    serialParams.DCBlength = sizeof(serialParams);
    GetCommState(hSerial, &serialParams);
    serialParams.BaudRate = CBR_115200;
    serialParams.ByteSize = 8;
    serialParams.Parity = NOPARITY;
    serialParams.StopBits = TWOSTOPBITS;
    SetCommState(hSerial, &serialParams);

    // 配置串口超时时间
    COMMTIMEOUTS timeouts = { 0 };
    timeouts.ReadIntervalTimeout = 50;
    timeouts.ReadTotalTimeoutConstant = 50;
    timeouts.ReadTotalTimeoutMultiplier = 10;
    SetCommTimeouts(hSerial, &timeouts);

    // 创建线程用于接收串口数据
    HANDLE hThread = CreateThread(NULL, 0, receiveThread, NULL, 0, NULL);

    // 定时发送5个字符
    while (true)
    {
        char buffer[] = "Hello";
        DWORD bytesWritten;

        // 发送数据到串口
        if (WriteFile(hSerial, buffer, sizeof(buffer) - 1, &bytesWritten, NULL))
        {
            // 打印发送的数据
            printf("Sent data: %s\n", buffer);
        }

        // 暂停1秒钟
        Sleep(1000);
    }

    return 0;
}

上面的代码实现了一个简单的串口通信程序,主线程在每个1秒钟定时发送5个字符到串口,接收线程使用了WaitCommEvent函数,等待串口接收事件,如果有数据到达,则从缓冲区读取数据并打印。需要注意的是,由于串口通信时,可能存在不对称的数据发送与接收情况,因此需要对WaitCommEvent函数返回的事件类型进行有效判断,以保证程序的稳定性。

SetCommMask函数的第二个参数是一个掩码,用于指定等待的串口事件类型。其中,串口事件类型定义如下:

常量 描述
EV_RXCHAR 0x0001 接收到一个字符时发送
EV_RXFLAG 0x0002 接收到一个指定字符时发送
EV_TXEMPTY 0x0004 发送缓冲区为空时发送
EV_CTS 0x0008 CTS状态改变时发送
EV_DSR 0x0010 DSR状态改变时发送
EV_RLSD 0x0020 RLSD状态改变时发送
EV_BREAK 0x0040 BREAK状态改变时发送
EV_ERR 0x0080 发生错误时发送
EV_RING 0x0100 接收到一个RING信号时发送
EV_RX80FULL 0x0200 接收到大于10个字符或DC1字节时发送
EV_EVENT1 0x0400 事件1,用于扩展事件
EV_EVENT2 0x0800 事件2,用于扩展事件

在SetCommMask函数的第二个参数中,可以使用“位或”运算符(|)组合多个事件类型,例如:

DWORD dwMask = EV_RXCHAR | EV_TXEMPTY | EV_ERR;
SetCommMask(hSerial, dwMask);

上面的代码设置了等待串口接收字符事件、串口发送缓冲区为空事件和错误事件,可以根据需要设置不同的事件类型,以实现不同的串口通信功能。

0 篇笔记 写笔记

寒江独钓串口过滤驱动程序源代码
comcap_tst.c////// @file comcap_tst.c/// @author crazy_chu/// @date 2008-6-20/// #ifndef _COMCAP_TST_HEADER_#define _COMCAP_......
串口过滤驱动调试过程蓝屏NO_MORE_IRP_STACK_LOCATIONS(35)问题分析
最近在搞一个串口的过滤驱动程序,在调度过程中报了一个蓝屏问题。NO_MORE_IRP_STACK_LOCATIONS (35)A higher level driver has attempted to call a lower level driver throughthe IoCallDr......
Windows串口编程的IOCTL和函数
下面是常见的IOCTL及对应的Win32 API函数列表,包括COM端口和USB设备的操作。IOCTRL的宏定义位于文件:C:Program Files (x86)Windows Kits10Include10.0.18362.0shared tddser.h中IOCTL......
同步方式串口收发数据
以下是一个简单的win32串口通信程序,该程序使用了Windows API中的CreateFile、SetCommTimeouts、SetCommState、WriteFile和ReadFile等函数来进行串口通信。#include #include
以下是一个简单的win32串口异步通信程序,该程序使用了Windows API中的CreateIoCompletionPort、CreateFile、SetCommTimeouts、SetCommState、WriteFile和ReadFileEx等函数来进行串口通信。相较于同步通信,异步通信更加灵......
以下是一个使用WaitCommEvent函数的简单的win32串口通信程序,该程序使用了Windows API中的CreateFile、SetCommTimeouts、SetCommState、.WriteFile和ReadFile等函数来进行串口通信。#include
在Windows系统中,IOCTL_SERIAL_PURGE 是指清空串口设备的读写缓冲区的 IOCTL 码。使用该 IOCTL 命令可以清空串口设备的读写缓冲区并丢弃其中的所有数据。该 IOCTL 命令可以用于以下情况:丢弃全部的写缓冲数据,以确保不会发送任何未完成的数据。丢弃全部的读缓冲数......
在 Windows 操作系统下,IOCTL_SERIAL_INTERNAL_CANCEL_WAIT_WAKE 是指撤销等待唤醒(Wait-Wake)操作的内部标识(ioctl command code)。Wait-Wake 操作是指,在计算机系统待机时,通过唤醒设备的方式,让设备执行某些操作。当设......
在 Win32 API 中,用于操作串口通讯的函数主要包括:CreateFile该函数用于打开一个串口通讯接口,返回的句柄可以用于读写串口。在调用 CreateFile 函数时需要指定串口通讯接口的名称和一些访问权限等参数,详见 MSDN 文档:HANDLE CreateFile( LP......
作者信息
我爱内核
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!