Windows串口编程
+ -

异步方式串口收发数据

2023-06-15 27 0

以下是一个简单的win32串口异步通信程序,该程序使用了Windows API中的CreateIoCompletionPort、CreateFile、SetCommTimeouts、SetCommState、WriteFile和ReadFileEx等函数来进行串口通信。相较于同步通信,异步通信更加灵活高效。

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

// 定义串口句柄和IO完成端口句柄
HANDLE hSerial;
HANDLE hIOCP;

// 定义OVERLAPPED结构体
OVERLAPPED overlappedRead;
OVERLAPPED overlappedWrite;

// 定义接收缓冲区和读取缓冲区的大小
char readBuffer[1024];
char writeBuffer[] = "Hello";

// ASCII转换函数
void asciiToHex(char* in, char* out, int length)
{
    for (int i = 0; i < length; ++i)
    {
        out[i] = in[i] & 0x0F;
        out[i] += (out[i] < 10 ? '0' : 'A' - 10);
    }
}

// 串口接收完成回调函数
VOID CALLBACK readCompletionRoutine(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
{
    // 指向OVERLAPPED结构体
    OVERLAPPED* overlapped = (OVERLAPPED*)lpOverlapped;

    // 读取串口数据
    if (dwNumberOfBytesTransfered > 0)
    {
        // 将数据转换成十六进制字符串
        char hexBuffer[1024];
        asciiToHex(readBuffer, hexBuffer, dwNumberOfBytesTransfered);

        // 打印收到的数据
        printf("Received data: %s\n", hexBuffer);
    }

    // 继续读取串口数据
    ReadFileEx(hSerial, readBuffer, sizeof(readBuffer), &overlappedRead, readCompletionRoutine);
}

int main()
{
    // 创建IO完成端口
    hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);

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

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

    // 将串口绑定到IO完成端口
    CreateIoCompletionPort(hSerial, hIOCP, (DWORD_PTR)hSerial, 0);

    // 配置串口参数
    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);

    // 配置异步读取
    memset(&overlappedRead, 0, sizeof(overlappedRead));
    overlappedRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    ReadFileEx(hSerial, readBuffer, sizeof(readBuffer), &overlappedRead, readCompletionRoutine);

    // 定时发送5个字符
    while (true)
    {
        // 发送数据到串口
        if (WriteFileEx(hSerial, writeBuffer, sizeof(writeBuffer) - 1, &overlappedWrite, NULL))
        {
            // 打印发送的数据
            printf("Sent data: %s\n", writeBuffer);
        }

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

    return 0;
}

上面的代码实现了一个简单的串口异步通信程序,主线程在每个1秒钟定时发送5个字符到串口,接收线程使用了异步读取方式,使用IO完成端口来通知程序串口接收数据完成,并且在回调函数中进行数据处理。异步通信的优点是可以利用操作系统

的资源进行处理,不占用太多CPU资源,能够提高程序的效率和稳定性。需要注意的是,在程序中使用异步通信时,需要使用OVERLAPPED结构体来传递异步操作参数,同时需要使用IOCMP完成端口来管理异步操作和回调函数。回调函数一般都需要在主线程中进行数据处理,因为回调函数是在IOCP线程池中的线程中被调用的,不建议在该线程中直接进行数据处理操作,以免影响程序的响应速度,所以需要在主线程中进行数据处理。

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驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

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

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