在标准的C语言库(如ANSI C)中,并没有一个叫做 WriteComm 的函数。

(图片来源网络,侵删)
WriteComm 是一个在 Windows 平台下,用于串口通信的函数,它通常不是直接由Windows API提供,而是由许多第三方串口通信库(如C++的SerialPort类封装)或者是一些老旧的、特定框架中定义的函数名,其底层实现最终还是调用了Windows的API函数。
当你在C语言中看到 WriteComm 时,可以理解为它是一个自定义函数或库函数,其目的是封装Windows的串口写入操作,使其使用起来更简单。
WriteComm 的核心功能
WriteComm 函数的核心功能是:向一个已经打开的串口设备发送数据。
它的原型通常类似于这样:

(图片来源网络,侵删)
// 这是一个常见的自定义函数原型 int WriteComm(HANDLE hComm, const char* lpBuffer, DWORD dwNumberOfBytesToWrite);
参数解释:
hComm: 一个句柄,代表一个已经打开的串口,这个句柄通常由另一个打开串口的函数(比如自定义的OpenComm或直接调用Windows的CreateFile)返回。lpBuffer: 一个指向字符缓冲区的指针,缓冲区中包含了你想要发送的数据。dwNumberOfBytesToWrite: 你想要发送的字节数。
返回值:
- 成功时,通常返回实际写入的字节数。
- 失败时,通常会返回
-1或0,你可以通过调用GetLastError()获取具体的错误码。
如何在C语言中使用 WriteComm(模拟实现)
既然 WriteComm 不是标准函数,我们无法直接使用,要实现它,最直接的方法是调用Windows的底层API函数 WriteFile。WriteFile 是Windows中用于向文件、设备(包括串口)写入数据的通用函数。
下面我们通过一个完整的例子来展示如何自定义一个 WriteComm 函数,并使用它来向串口发送 "Hello, Serial Port!" 字符串。

(图片来源网络,侵删)
完整代码示例
#include <windows.h> // Windows API头文件
#include <stdio.h> // 标准输入输出
// 自定义的 WriteComm 函数
// 封装了 Windows API 的 WriteFile
int WriteComm(HANDLE hComm, const char* lpBuffer, DWORD dwNumberOfBytesToWrite) {
if (hComm == INVALID_HANDLE_VALUE) {
printf("错误:无效的串口句柄,\n");
return -1;
}
DWORD dwBytesWritten; // 用于存储实际写入的字节数
BOOL bResult = WriteFile(
hComm, // 串口句柄
lpBuffer, // 数据缓冲区
dwNumberOfBytesToWrite, // 要写入的字节数
&dwBytesWritten, // 用于接收实际写入的字节数
NULL // 同步操作,不使用异步结构体
);
if (bResult && dwBytesWritten == dwNumberOfBytesToWrite) {
// 成功写入所有字节
return dwBytesWritten;
} else {
// 写入失败
printf("写入失败!错误码: %lu\n", GetLastError());
return -1;
}
}
int main() {
// 1. 打开串口
// COM3 是一个常见的串口号,请根据你的实际情况修改
HANDLE hSerial = CreateFile(
"COM3", // 串口设备名
GENERIC_WRITE, // 指定写访问
0, // 不共享设备
NULL, // 默认安全属性
OPEN_EXISTING, // 打开已存在的设备
0, // 默认属性
NULL // 不使用模板文件
);
if (hSerial == INVALID_HANDLE_VALUE) {
printf("无法打开串口 COM3,请检查串口号和设备管理器,\n");
printf("错误码: %lu\n", GetLastError());
return 1;
}
printf("串口 COM3 打开成功,\n");
// 2. 配置串口参数(非常重要!)
DCB dcbSerialParams = { 0 };
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (!GetCommState(hSerial, &dcbSerialParams)) {
printf("获取串口状态失败,\n");
CloseHandle(hSerial);
return 1;
}
// 配置波特率、数据位、停止位、校验位
// 9600 bps, 8 data bits, no parity, 1 stop bit (8N1)
dcbSerialParams.BaudRate = CBR_9600;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if (!SetCommState(hSerial, &dcbSerialParams)) {
printf("设置串口状态失败,\n");
CloseHandle(hSerial);
return 1;
}
printf("串口参数设置成功 (9600, 8, N, 1),\n");
// 3. 使用自定义的 WriteComm 函数发送数据
char dataToSend[] = "Hello, Serial Port!\r\n"; // \r\n 是回车换行,很多设备需要
DWORD dataSize = strlen(dataToSend);
int bytesWritten = WriteComm(hSerial, dataToSend, dataSize);
if (bytesWritten > 0) {
printf("成功发送了 %d 字节的数据: \"%s\"\n", bytesWritten, dataToSend);
} else {
printf("数据发送失败,\n");
}
// 4. 关闭串口
CloseHandle(hSerial);
printf("串口已关闭,\n");
return 0;
}
代码步骤解析
- 包含头文件:
#include <windows.h>是必须的,它包含了所有Windows API的定义。 - 定义
WriteComm函数:- 它接收串口句柄
hComm、数据缓冲区lpBuffer和要发送的字节数dwNumberOfBytesToWrite。 - 内部调用
WriteFile来执行实际的写入操作。 WriteFile是一个同步函数,会阻塞程序直到数据被写入或发生错误。- 检查
WriteFile的返回值和dwBytesWritten,确保所有请求的字节都已成功发送。
- 它接收串口句柄
main函数:CreateFile: 打开串口,获取一个句柄hSerial。GENERIC_WRITE表示我们只需要写入权限。GetCommState和SetCommState: 这是串口通信的关键步骤,必须先获取当前的配置,然后修改为你需要的参数(如波特率9600、8位数据位等),再设置回去,如果参数不匹配,通信会失败。- 调用
WriteComm: 准备好要发送的数据字符串,然后调用我们自定义的函数发送。 CloseHandle: 操作完成后,必须关闭串口句柄,释放系统资源。
跨平台问题
WriteComm 的实现是平台相关的。
- Windows: 使用
CreateFile,WriteFile,SetCommState等 API。 - Linux / macOS: 串口被当作普通的文件设备,操作方式与文件I/O完全相同。
- 打开:
open("/dev/ttyS0", O_WRONLY)(注意是O_WRONLY或O_RDWR) - 写入:
write() - 配置: 使用
termios.h库中的函数来设置波特率等参数(cfsetispeed,cfsetospeed,tcsetattr)。 - 关闭:
close()
- 打开:
如果你编写的程序需要跨平台,就不能依赖 WriteComm 这样的Windows特定函数,你需要使用跨平台的库,
- Boost.Asio: C++的跨平台网络和串口库。
- libserial: 一个专门为C++设计的跨平台串口库。
- Poco Library: 另一个功能强大的C++跨平台库。
| 特性 | 说明 |
|---|---|
| 函数性质 | 非标准C函数,是Windows平台下的自定义或库函数。 |
| 核心功能 | 向已打开的串口发送数据。 |
| 底层实现 | 在Windows上,它通常是对 WriteFile API的封装。 |
| 使用前提 | 必须先成功打开串口并配置好参数(波特率、数据位等)。 |
| 关键API | CreateFile, WriteFile, SetCommState, CloseHandle。 |
| 跨平台 | 否,在Linux/macOS上需要使用 open, write, termios.h 等不同的API。 |
希望这个详细的解释能帮助你完全理解 WriteComm 在C语言中的作用和实现方式!
