使用Windows API实现一个简单的串口助手

使用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
);

步骤

  1. 创建一个设备句柄
  2. 创建一个设备文件
  3. 配置串口参数
  4. 创建读写线程
  5. 对设备文件进行读写
  6. 退出线程后关闭设备文件

实现代码


#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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/736459.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何提高内存和cpu使用率呢?-Linux类资源

最近公司项目上线时&#xff0c;红蓝线巡检时&#xff0c;部分服务器因配置高但使用率低而需要降级。 为了避免降级&#xff0c;如何增加内存和CPU使用率&#xff1f; 这可以通过脚本来实现。 当前服务器操作系统版本&#xff1a;-7_5。 连接服务器后&#xff0c;登录账号。 …

如何安装和激活Fl Studio21.2.3.4004破解补丁(附激活教程)

盼望着盼望着&#xff0c;FL Studio21带这它的版本号2.3.4004来了&#xff0c;是最新版Fl Studio21.2.3.4004 FL Studio v21.2.3.4004 中文破解版链接: 百度网盘-链接不存在 提取码: hpa2 FL Studio 21 Win-安装包&#xff1a;https://souurl.cn/r0j6ET FL Studio 21 Mac-安装包…

Leo赠书活动-19期 《Elasticsearch 通过索引阻塞实现数据保护深入解析》

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 赠书活动专栏 ✨特色专栏&#xff1a;…

Docker进阶:深入理解 Dockerfile

Docker进阶&#xff1a;深入理解 Dockerfile 一、Dockerfile 概述二、为什么要学习Dockerfile三、Dockerfile 编写规则四、Dockerfile 中常用的指令1、FROM2、LABEL3、RUN4、CMD5、ENTRYPOINT6、COPY7、ADD8、WORKDIR9、 ENV10、EXPOSE11、VOLUME12、USER13、注释14、ONBUILD 命…

面试官:Spring Boot中如何使用Async异步调用方法

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:springboot中如何使用Async异步调用方法 在Spring Boot中使用@Async注解可以实现异步调用方法,提高系统的并发性能和响应速度。通过在方法上添加…

并发修改同一条数据的处理办法

1.不用锁, 旧值判断重试机制 /* * 不用锁, 旧值判断重试机制, 其实也是变相的行级锁。这种方案会遇到一个ABA问题&#xff0c;加个时间戳或版本号字段即可解决&#xff0c;主要是这个思路。 * 优点:所有请求不用排队,并发修改同一个id的请求保证都能成功&#xff0c;这种方案适…

TimescaleDB 开源时序数据库

文章目录 1.TimescaleDB介绍2.Hypertable 和 chunk3.Hypertable4.Hypertable操作 开源中间件 # TimescaleDBhttps://iothub.org.cn/docs/middleware/ https://iothub.org.cn/docs/middleware/timescale/timescale-summary/1.TimescaleDB介绍 TimescaleDB是基于PostgreSQL数据…

java-新手笔记-(Lambda表达式, 匿名内部类,作用域,闭包)

Lambda表达式 定义:可以看作是一种没有名称&#xff08;即匿名&#xff09;的函数。Lambda表达式主要用于表示那些只有一个抽象方法的接口&#xff08;即函数式接口&#xff09;的实例. 这边可以用接口定义抽象的方法,再用lambda继续完善方法,注意的是 接口是只支持单一函数l…

Excel生成 chart 混合图表

在开发中有这样一个需求&#xff0c;邮件预警的时候&#xff0c;要求邮件主体内容是一个Chart 图表&#xff08;生成后的img&#xff09;&#xff0c;邮件需要有附件&#xff0c;且附件是Excel列表加图表&#xff0c;图表类型是混合图。 回顾&#xff1a;在之前一篇讲到如何使用…

LLM Saturation与多模态AI的崛起

LLM Saturation与多模态AI的崛起 近年来&#xff0c;大型语言模型&#xff08;LLM&#xff09;在语言理解和生成能力上取得了显著进步&#xff0c;如GPT-4和LLaMA-2等。然而&#xff0c;我们可能正接近LLM范式的极限。本文探讨LLM性能天花板、局限性&#xff0c;以及多模态AI为…

SQL 多表查询

文章目录 多表查询的分类等值连接非等值连接自连接非自连接内连接外连接左外连接右外连接满外连接 SQL连接 JOINSQL99 语法新特性 自然连接 NATURAL JOIN & USING 多表查询的分类 等值连接 VS 非等值连接自连接 VS 非自连接内连接 VS 外连接 等值连接 关联的表有连接字段…

【c语言 】 函数入门

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;C语言 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步&…

Java常见数据结构“ 栈与队列 ”学完就去编程!!!

一、栈&#xff08;Stack&#xff09;&#xff1a; 栈是一种后进先出&#xff08;LIFO&#xff0c;Last In First Out&#xff09;的数据结构&#xff0c;类似于现实生活中的一叠盘子&#xff0c;最后放入的盘子最先被取出。 主要方法和特点&#xff1a; push(E e): 将元素推…

突破编程_C++_设计模式(模板方法模式)

1 模板方法模式的基本概念 C 模板方法模式是一种行为设计模式&#xff0c;它在一个操作中定义算法的骨架&#xff0c;而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下重新定义算法的某些特定步骤。在C中&#xff0c;模板方法模式通常通过使用虚函数和…

MySQl基础入门⑦

上一章知识内容 分析数据且区分数据类型 看下表分析数据的特征&#xff0c;根据其特征确定相应的数据类型。 分析以上表格特征&#xff0c;确定数据类型&#xff0c;并对数据进行分类。分析数据后按固定长度字符串、可变长度字符串、整数、固定精度小数和日期时间数据类型对数…

【树】-Lc101-对称二叉树(一棵树是否是另一棵树的子树的变形)

写在前面 最近想复习一下数据结构与算法相关的内容&#xff0c;找一些题来做一做。如有更好思路&#xff0c;欢迎指正。 目录 写在前面一、场景描述二、具体步骤1.环境说明2.代码 写在后面 一、场景描述 对称二叉树。给给定一个二叉树&#xff0c;检查它是否是镜像对称的。 例…

spring-data-elasticsearch官方文档解读(部分)

Spring Data Elasticsearch 这里主要学习的是4.4.16版本的文档 1. 版本 下表显示了 Spring Data 发行版系列使用的 Elasticsearch 版本和其中包含的 Spring Data Elasticsearch 版本&#xff0c;以及引用该特定 Spring Data 发行版系列的 Spring Boot 版本。给出的 Elastics…

keepalived原理以及lvs、nginx跟keeplived的运用

keepalived基础 keepalived的原理是根据vrrp协议&#xff08;主备模式&#xff09;去设定的 vrrp技术相关原理 状态机&#xff1b; 优先级0~255 心跳线1秒 vrrp工作模式 双主双备模式 VRRP负载分担过程 vrrp安全认证&#xff1a;使用共享密匙 keepalived工具介绍 keepal…

Qt 绘制中的视口(setViewport)和窗口(setWindow)

重点 &#xff1a; 1.绘制&#xff08;QPainter&#xff09;可以设置视口&#xff0c;视口下设置窗口&#xff0c;而绘制的构件是以窗口为坐标系进行绘画。 2.先根据绘图设备的物理坐标系的矩形位置&#xff0c;设置视图视口setViewport&#xff0c;然后在以视口为区域去设置…

【Leetcode刷题】1360. 日期之间隔几天

1360. 日期之间隔几天 简单 请你编写一个程序来计算两个日期之间隔了多少天。 日期以字符串形式给出&#xff0c;格式为 YYYY-MM-DD&#xff0c;如示例所示。 示例 1&#xff1a; 输入&#xff1a;date1 “2019-06-29”, date2 “2019-06-30” 输出&#xff1a;1 示例 2…