目录
使用 Windows API 开发一个具有字符串收发功能的串口助手
开发环境
串口设备相关的 API
步骤
实现代码
收发测试图
使用 Windows API 开发一个具有字符串收发功能的串口助手
开发环境
Visual Studio 2015
串口设备相关的 API
CreateFile
参数详情见:
SetCommState
参数详情见:
GetCommState
参数详情见:
ReadFile
参数详情见:
WriteFile
参数详情见:
PurgeComm
参数详情见:
CloseHandle
参数详情见:
- // 函数原型
- 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 表示出错, 会设置 GetLastError
- if (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");
- else
- break;
- } 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 串口上位机软件)
来源: http://www.bubuko.com/infodetail-3518242.html