C/C++语言windows读取串口数据

本文详细介绍了如何使用C/C++在Windows系统中通过CreateFile、WriteFile、ReadFile、CloseFile、SetCommState和GetCommState函数进行串口的读写操作,包括函数解释、示例代码和资源管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文使用C/C++语言,对windows下串口读写进行操作。

一、## 函数解释:

1.###CreateFile函数

CreateFile函数是Windows系统中的一个函数,用于创建或打开一个文件或设备。它可以在应用程序中使用,通过指定文件名、文件属性和访问权限来创建或打开文件。

CreateFile函数的语法如下:

HANDLE CreateFile(
LPCSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile
);

参数说明:

  • lpFileName: 文件名或设备名的字符串指针。
  • dwDesiredAccess: 文件或设备的访问权限,例如GENERIC_READ、GENERIC_WRITE等。
  • dwShareMode: 文件或设备的共享模式,例如FILE_SHARE_READ、FILE_SHARE_WRITE等。
  • lpSecurityAttributes: 指向SECURITY_ATTRIBUTES结构的指针,用于指定文件或设备的安全属性。
  • dwCreationDisposition: 指定创建新文件的方式,例如CREATE_ALWAYS、OPEN_EXISTING等。
  • dwFlagsAndAttributes: 指定文件或设备的属性和标志,例如FILE_ATTRIBUTE_NORMAL、FILE_FLAG_OVERLAPPED等。
  • hTemplateFile: 指定一个用于复制文件属性的句柄。

返回值:
如果函数执行成功,则返回一个有效的文件句柄;如果函数执行失败,则返回INVALID_HANDLE_VALUE。

通过使用CreateFile函数,我们可以创建或打开文件,并获取一个用于后续文件操作的句柄。句柄可以用于读取、写入、修改文件属性等操作。CreateFile函数是Windows系统中的一个函数,用于创建或打开一个文件或设备。它可以在应用程序中使用,通过指定文件名、文件属性和访问权限来创建或打开文件。

2.###WriteFile函数

WriteFile函数是Windows系统中的一个函数,它用于将数据写入打开的文件或设备。

WriteFile函数的语法如下:

BOOL WriteFile(
HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped
);

参数说明:

  • hFile: 文件或设备的句柄,通过CreateFile函数获取。
  • lpBuffer: 指向包含要写入文件的数据的缓冲区的指针。
  • nNumberOfBytesToWrite: 要写入文件的字节数。
  • lpNumberOfBytesWritten: 指向接收实际写入字节数的变量的指针。
  • lpOverlapped: 指向一个OVERLAPPED结构的指针,用于指定异步I/O操作的参数。如果不需要使用异步I/O,可以将该参数设置为NULL。

返回值:
如果函数执行成功,则返回非零值,表示写入操作成功;如果函数执行失败,则返回零。

通过使用WriteFile函数,我们可以将数据从缓冲区写入打开的文件或设备。可以指定要写入的字节数,同时也可以获取实际写入的字节数。这个函数通常与CreateFile函数一起使用,用于向已经打开的文件中写入数据。WriteFile函数是Windows系统中的一个函数,它用于将数据写入打开的文件或设备。

3.###ReadFile函数

ReadFile函数是Windows系统中的一个函数,用于从一个打开的文件或设备中读取数据。

ReadFile函数的语法如下:

BOOL ReadFile(
HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped
);

参数说明:

  • hFile: 文件或设备的句柄,通过CreateFile函数获取。
  • lpBuffer: 指向接收读取数据的缓冲区的指针。
  • nNumberOfBytesToRead: 要读取的字节数。
  • lpNumberOfBytesRead: 指向接收实际读取字节数的变量的指针。
  • lpOverlapped: 指向一个OVERLAPPED结构的指针,用于指定异步I/O操作的参数。如果不需要使用异步I/O,可以将该参数设置为NULL。

返回值:
如果函数执行成功,则返回非零值,表示读取操作成功;如果函数执行失败,则返回零。

通过使用ReadFile函数,我们可以从已经打开的文件或设备中读取指定字节数的数据。可以指定要读取的字节数,同时也可以获取实际读取的字节数。这个函数通常与CreateFile函数一起使用,用于从已经打开的文件中读取数据。ReadFile函数是Windows系统中的一个函数,用于从一个打开的文件或设备中读取数据。

4.###CloseFile函数

CloseFile函数是用来关闭已打开的文件的函数。在程序中,当我们打开一个文件进行读取或写入操作后,必须通过调用CloseFile函数来关闭文件,以释放文件资源。

CloseFile函数的定义可能会因编程语言和操作系统的不同而有所差异,但其基本功能是相同的:将文件指针指向的文件关闭,并释放相关资源。

在使用CloseFile函数时,需要将要关闭的文件的文件句柄作为参数传递给函数。文件句柄是一个用于标识文件的整数或指针。

关闭文件后,程序将不能再对该文件进行读写操作。因此,在调用CloseFile函数之前,必须确保已完成对文件的读写操作。

关闭文件是一个良好的编程习惯,可以避免文件资源的浪费和潜在的错误。CloseFile函数是用来关闭已打开的文件的函数。在程序中,当我们打开一个文件进行读取或写入操作后,必须通过调用CloseFile函数来关闭文件,以释放文件资源。

CloseFile函数的定义可能会因编程语言和操作系统的不同而有所差异,但其基本功能是相同的:将文件指针指向的文件关闭,并释放相关资源。

在使用CloseFile函数时,需要将要关闭的文件的文件句柄作为参数传递给函数。文件句柄是一个用于标识文件的整数或指针。

关闭文件后,程序将不能再对该文件进行读写操作。因此,在调用CloseFile函数之前,必须确保已完成对文件的读写操作。

关闭文件是一个良好的编程习惯,可以避免文件资源的浪费和潜在的错误。

5.###SetCommState函数

SetCommState函数是用于设置串口的状态参数的函数。在程序中,当我们需要使用串口进行数据通信时,需要设置串口的一些参数,如波特率、数据位数、停止位、奇偶校验等。

SetCommState函数的定义和使用可能会因编程语言和操作系统的不同而有所差异,但其基本功能是相同的:根据传入的参数设置串口的状态。

在使用SetCommState函数时,需要创建一个DCB(Device Control Block)结构体,并将需要设置的串口参数赋值给该结构体。然后,将该结构体作为参数传递给SetCommState函数。

SetCommState函数会根据传入的参数,将指定的串口的状态参数设置为所需的值。如果设置成功,函数将返回一个非零值;如果设置失败,函数将返回零。

使用SetCommState函数设置串口的状态参数是进行串口通信的关键步骤之一。正确设置串口参数可以确保数据的正常传输和接收。因此,在使用串口进行数据通信前,必须先调用SetCommState函数设置串口的状态参数。

6.###GetCommState函数

GetCommState函数用于获取串口的当前状态参数。在进行串口通信时,有时候需要获取串口的当前状态参数,以便进行一些判断或设置其他相关参数。

GetCommState函数的定义和使用可能会因编程语言和操作系统的不同而有所差异,但其基本功能是相同的:获取指定串口的当前状态参数。

在使用GetCommState函数时,需要创建一个DCB(Device Control Block)结构体,并将该结构体作为参数传递给GetCommState函数。

GetCommState函数会获取指定串口的当前状态参数,并将结果保存在传入的DCB结构体中。如果获取成功,函数将返回一个非零值;如果获取失败,函数将返回零。

通过GetCommState函数获取串口的当前状态参数,可以帮助我们了解串口的当前设置情况,以及对应的波特率、数据位数、停止位、奇偶校验等参数。这些参数可以用于判断当前串口的工作状态,或对其他相关参数进行设置。

7.###CloseHandle函数

CloseHandle函数用于关闭一个已打开的对象句柄。在Windows操作系统中,访问系统资源(例如文件、串口、线程等)需要通过句柄(Handle)来进行。当我们不再需要使用一个已打开的句柄时,应当调用CloseHandle函数来关闭该句柄,以释放系统资源。

CloseHandle函数的定义和使用可能会因编程语言和操作系统的不同而有所差异,但其基本功能是相同的:关闭指定的句柄。

在使用CloseHandle函数时,需要将需要关闭的句柄作为参数传递给CloseHandle函数。

CloseHandle函数会根据传入的句柄关闭对应的系统资源,并释放相关的内存和资源。如果关闭成功,函数将返回一个非零值;如果关闭失败,函数将返回零。

使用CloseHandle函数关闭一个已打开的对象句柄,可以帮助我们及时释放系统资源,避免资源泄漏和浪费。同时,关闭句柄还可以提高系统性能,减少系统资源的占用。因此,在不再需要使用一个句柄时,应当及时调用CloseHandle函数关闭该句柄。

二、## 示例代码

以下是使用C/C++语言,并使用CreateFile、WriteFile和ReadFile函数读写串口数据的示例代码:

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

int main()
{
    // 打开串口
    HANDLE 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 dcbSerialParams = { 0 };
    dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
    
    if (!GetCommState(hSerial, &dcbSerialParams))
    {
        printf("Failed to get serial port parameters\n");
        CloseHandle(hSerial);
        return 1;
    }
    
    dcbSerialParams.BaudRate = CBR_9600;  // 根据实际情况修改波特率
    dcbSerialParams.ByteSize = 8;
    dcbSerialParams.StopBits = ONESTOPBIT;
    dcbSerialParams.Parity = NOPARITY;
    
    if (!SetCommState(hSerial, &dcbSerialParams))
    {
        printf("Failed to set serial port parameters\n");
        CloseHandle(hSerial);
        return 1;
    }

    // 循环读写数据
    char buffer[100];
    DWORD bytesRead, bytesWritten;

    while (true)
    {
        // 写入串口
        char key;
        if (_kbhit())
        {
            key = _getch();
            WriteFile(hSerial, &key, 1, &bytesWritten, NULL);
        }

        // 读取串口数据
        if (ReadFile(hSerial, buffer, sizeof(buffer) - 1, &bytesRead, NULL))
        {
            if (bytesRead > 0)
            {
                buffer[bytesRead] = '\0';
                printf("Received: %s\n", buffer);
            }
        }
    }

    // 关闭串口
    CloseHandle(hSerial);

    return 0;
}

这段代码首先使用CreateFile函数打开串口,返回一个句柄hSerial,表示成功打开的串口。如果打开串口失败,则会返回INVALID_HANDLE_VALUE

然后,通过GetCommState函数获取串口的当前参数,并使用DCB结构体来设置波特率、数据位、停止位和校验位等参数。然后使用SetCommState函数将新的参数应用于串口。

接下来,在一个无限循环中,通过_kbhit_getch函数来检测键盘输入并写入串口,使用WriteFile函数进行写入。然后使用ReadFile函数从串口读取数据,并使用printf函数打印出来。

最后,在程序结束前需要使用CloseHandle函数关闭串口句柄。

请注意,以上代码中的COM1是一个示例串口号,你需要将其替换为实际连接设备的串口号。另外,为了能够使用 _kbhit_getch函数来实现键盘输入的检测和获取,需要包含conio.h头文件,并在编译时链接conio.lib库文件。

希望以上能帮助到您,感谢阅读!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

茶包不是trouble

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值