使用Windows API实现一个简单的串口助手
目录
- 使用window API开发一个具有字符串收发功能的串口助手
- 开发环境
- 串口设备相关的API
- 步骤
- 实现代码
- 收发测试图
使用window API开发一个具有字符串收发功能的串口助手
开发环境
- Visual Studio 2015
串口设备相关的API
-
CreateFile
参数详情见:CreateFileA function (fileapi.h) - Win32 apps | Microsoft Learn -
SetCommState
参数详情见:SetCommState function (winbase.h) - Win32 apps | Microsoft Learn -
GetCommState
参数详情见:GetCommState function (winbase.h) - Win32 apps | Microsoft Learn -
ReadFile
参数详情见:ReadFile (Compact 2013) | Microsoft Learn -
WriteFile
参数详情见:WriteFile (Compact 2013) | Microsoft Learn -
PurgeComm
参数详情见:PurgeComm (Compact 2013) | Microsoft Learn -
CloseHandle
参数详情见:CloseHandle (Compact 2013) | Microsoft Learn
// 函数原型
HANDLE WINAPI CreateFile(_In_ LPCTSTR lpFileName,_In_ DWORD dwDesiredAccess,_In_ DWORD dwShareMode,_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,_In_ DWORD dwCreationDisposition,_In_ DWORD dwFlagsAndAttributes,_In_opt_ HANDLE hTemplateFile
);BOOL WINAPI SetCommState(_In_ HANDLE hFile,_In_ LPDCB lpDCB
);BOOL WINAPI GetCommState(_In_ HANDLE hFile,_Inout_ LPDCB lpDCB
);BOOL ReadFile(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped
);BOOL WriteFile( HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped
);BOOL PurgeComm(HANDLE hFile,DWORD dwFlags
);BOOL CloseHandle(HANDLE hObject
);
步骤
- 创建一个设备句柄
- 创建一个设备文件
- 配置串口参数
- 创建读写线程
- 对设备文件进行读写
- 退出线程后关闭设备文件
实现代码
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <stdio.h>HANDLE hCom; // 句柄,用于初始化串口DWORD WINAPI ThreadWrite(LPVOID lpParameter)
{char outputData[100] = { 0x00 }; // 输出数据缓存if (hCom == INVALID_HANDLE_VALUE){puts("打开串口失败");return 0;}DWORD strLength = 0;while (1){for (int i = 0; i < 100; i++){outputData[i] = 0;}fgets(outputData, 100, stdin); // 从控制台输入字符串strLength = strlen(outputData);printf("发送了%d个字节\r\n", strLength); // 打印字符串长度WriteFile(hCom, outputData, strLength, &strLength, NULL); // 串口发送字符串fflush(stdout);PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR); // 清空缓冲区Sleep(100);}return 0;
}DWORD WINAPI ThreadRead(LPVOID lpParameter)
{// INVALID_HANDLE_VALUE表示出错,会设置GetLastErrorif (hCom == INVALID_HANDLE_VALUE) {puts("打开串口失败");return 0;}char getputData[100] = { 0x00 }; // 输入数据缓存// 利用错误信息来获取进入串口缓冲区数据的字节数DWORD dwErrors; // 错误信息COMSTAT Rcs; // COMSTAT结构通信设备的当前信息int Len = 0;DWORD length = 100; //用来接收读取的字节数while (1){for (int i = 0; i < 100; i++){getputData[i] = 0;}ClearCommError(hCom, &dwErrors, &Rcs); // 获取读缓冲区数据长度Len = Rcs.cbInQue;ReadFile(hCom, getputData, Len, &length, NULL); // 获取字符串PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR); // 清空缓冲区if (Len > 0){printf("接收的数据为:%s\r\n", getputData);fflush(stdout);}Sleep(100);}return 0;
}int main()
{// 初始化串口TCHAR *com_name = (TCHAR *)malloc(10 * sizeof(TCHAR));do{printf("请输入需要打开的串口号(示例:COM2):");scanf("%s",com_name);getchar();hCom = CreateFile(com_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (hCom == INVALID_HANDLE_VALUE)printf("串口号不存在,请重新输入!\n");elsebreak;} while (1);free(com_name);// 获取和设置串口参数DCB myDCB;myDCB.BaudRate = 115200; // 波特率myDCB.Parity = NOPARITY; // 校验位myDCB.ByteSize = 8; // 数据位myDCB.StopBits = ONESTOPBIT; // 停止位SetCommState(hCom, &myDCB); // 设置串口参数printf("baud rate is %d\n", (int)myDCB.BaudRate);// 线程创建HANDLE HRead, HWrite;HWrite = CreateThread(NULL, 0, ThreadWrite, NULL, 0, NULL);HRead = CreateThread(NULL, 0, ThreadRead, NULL, 0, NULL);while (1);CloseHandle(HRead);CloseHandle(HWrite);CloseHandle(hCom);return 0;
}
收发测试图
- 备注(左边为自己开发的串口软件,右边为正点原子团队开发的XCOM V2.0串口上位机软件)
Posted By veis