虚拟串口调试(Windows)

在单片机和嵌入式设备开发过程中,我们有时需要对程序的串口进行调试,但是身边又恰好没有硬件设备,此时,我们可以通过虚拟串口来实现模拟本地端口,方便调试。

软件安装

VSPD虚拟串口工具

  • 下载VSPD软件:百度网盘VSPD分享
  • 解压后,选择vspd.exe文件,安装在本地
  • 破解:将解压后,将Cracked目录下的文件复制到安装路径下,替换原安装路径下的同名文件即可

串口调试工具

根据自己的喜好选择合适的串口调试工具即可。

这里推荐BruceOu的串口调试工具:BruceOu串口调试工具官网

虚拟串口

虚拟串口工具

  • 添加虚拟串口:为了模拟串口之间的通讯,在添加虚拟串口时,会模拟产生两个相连的串口,在这两个串口之间可以进行通讯。

串口调试(工具)

由于虚拟串口是模拟的两个串口之间的通讯,打开两个串口调试工具界面。选择一组相连的串口,即可通过调试工具进行测试(若是在串口调试工具中搜索不到相关串口,尝试重启相关串口调试工具重新搜索)。
串口调试

C语言程序调试串口(Windows)

在Windows上通过串口发送数据,可以使用Win32 API串口通讯函数。

通过Win32 API打开VSPD虚拟串口工具名如COM1COM2的串口时,由于VPSD的驱动符号设置的问题,直接访问COM1无法连接到虚拟串口,需要将串口修改为\\\\.\\COM1即可正常访问。

串口发送数据

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

// 修改为对应串口
#define SERIAL_NAME "\\\\.\\COM1"
// 修改为对应波特率
#define BAUD_RATE CBR_9600


/**
 * 初始化串口配置信息
 * @param hSerial
 * @return
 */
int serialInit(HANDLE *hSerial) {
    // 打开串口
    *hSerial = CreateFile(SERIAL_NAME,
                          GENERIC_READ | GENERIC_WRITE,
                          0,
                          0,
                          OPEN_EXISTING,
                          FILE_ATTRIBUTE_NORMAL,
                          0);

    if (*hSerial == INVALID_HANDLE_VALUE) {
        printf("Error opening serial port!\n");
        return 0;
    }

    // 设置串口配置
    DCB dcbSerialParams = {0};
    dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
    GetCommState(*hSerial, &dcbSerialParams);
    dcbSerialParams.BaudRate = BAUD_RATE;
    dcbSerialParams.ByteSize = 8;
    dcbSerialParams.StopBits = ONESTOPBIT;
    dcbSerialParams.Parity = NOPARITY;
    SetCommState(*hSerial, &dcbSerialParams);

    // 清空串口
    PurgeComm(*hSerial, PURGE_RXCLEAR | PURGE_TXCLEAR);

    // 设置超时
    COMMTIMEOUTS timeouts = {0};
    timeouts.ReadIntervalTimeout = 1000;
    timeouts.ReadTotalTimeoutMultiplier = 1000;
    timeouts.ReadTotalTimeoutConstant = 1000;
    timeouts.WriteTotalTimeoutMultiplier = 1000;
    timeouts.WriteTotalTimeoutConstant = 1000;
    SetCommTimeouts(*hSerial, &timeouts);
    return 1;
}

/**
 * 发送数据到串口设置中
 * @param hSerial 
 * @param data 
 * @return 
 */
int sendData2Serial(HANDLE hSerial, const char *data) {
    if (!WriteFile(hSerial, (void *) data, strlen(data), 0, 0)) {
        printf("Error in WriteFile()\n");
        return 0;
    } else {
        return 1;
    }
}

int main() {
    HANDLE hSerial;

    serialInit(&hSerial);

    const char *str = "focus1024.com\0";

    sendData2Serial(hSerial, str);

    // 关闭串口
    CloseHandle(hSerial);

    return 0;
}

程序发送数据

串口读取数据

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

// 修改为对应串口
#define SERIAL_NAME "\\\\.\\COM1"
// 修改为对应波特率
#define BAUD_RATE CBR_9600
#define BUF_SIZE 1024


/**
 * 初始化串口配置信息
 * @param hSerial
 * @return
 */
int serialInit(HANDLE *hSerial) {
    // 打开串口
    *hSerial = CreateFile(SERIAL_NAME,
                          GENERIC_READ | GENERIC_WRITE,
                          0,
                          0,
                          OPEN_EXISTING,
                          FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
                          0);

    if (*hSerial == INVALID_HANDLE_VALUE) {
        printf("Error opening serial port!\n");
        return 0;
    }

    // 设置串口配置
    DCB dcbSerialParams = {0};
    dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
    GetCommState(*hSerial, &dcbSerialParams);
    dcbSerialParams.BaudRate = BAUD_RATE;
    dcbSerialParams.ByteSize = 8;
    dcbSerialParams.StopBits = ONESTOPBIT;
    dcbSerialParams.Parity = NOPARITY;
    SetCommState(*hSerial, &dcbSerialParams);

    // 清空串口
    PurgeComm(*hSerial, PURGE_RXCLEAR | PURGE_TXCLEAR);

    // 设置超时
    COMMTIMEOUTS timeouts = {0};
    timeouts.ReadIntervalTimeout = 1000;
    timeouts.ReadTotalTimeoutMultiplier = 1000;
    timeouts.ReadTotalTimeoutConstant = 1000;
    timeouts.WriteTotalTimeoutMultiplier = 1000;
    timeouts.WriteTotalTimeoutConstant = 1000;
    SetCommTimeouts(*hSerial, &timeouts);
    return 1;
}

int main() {
    HANDLE hSerial;

    serialInit(&hSerial);

    char buf[BUF_SIZE];

    OVERLAPPED oRead;
    oRead.Offset = 0;
    oRead.OffsetHigh = 0;
    oRead.hEvent = CreateEvent(0, 1, 0, 0);

    BOOL fRead;
    DWORD dwRead;

    if (hSerial != INVALID_HANDLE_VALUE) {
        fRead = ReadFile(hSerial, buf, BUF_SIZE, &dwRead, &oRead);
        if (!fRead && GetLastError() == ERROR_IO_PENDING) {
            // 等待异步操作完成
            WaitForSingleObject(oRead.hEvent, INFINITE);
            if (GetOverlappedResult(hSerial, &oRead, &dwRead, FALSE)) {
                // 处理读取到的数据
                buf[dwRead] = '\0'; // 确保字符串以null结尾
                printf("Read %lu bytes: %s\n", dwRead, buf);
            }
        }
    }

    // 关闭串口
    CloseHandle(oRead.hEvent);
    CloseHandle(hSerial);

    return 0;
}

程序读取串口数据

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

django和vue开发的前后端分离网站怎么部署到服务器上,django和vue前后端分离网站怎么通过宝塔部署

提示&#xff1a;如果看完全部教程后仍然部署不成功&#xff0c;可以联系作者 一、提前准备 想要把django vue 前后端分离网站部署到服务器上&#xff0c;有一些提前准备的东西 1、备案域名&#xff08;域名必须备案&#xff09; 这里需要解析两个域名&#xff0c;一个前端&…

【数据结构|C语言版】栈和队列

前言1. 栈1.1 栈的概念和性质1.2 顺序栈1.3 链栈1.4 共享栈 2. 队列2.1 队列的概念和性质2.2 循环队列2.3 链式队列2.4 双端队列 3. 例题精选3.1 有效的括号3.2 用队列实现栈2.4 用栈实现队列3.4 设计循环队列3.5 参考答案 结语 #include<GUIQU.h> int main { 上期回顾: …

浏览器控制台console常用命令小结

chrome调试工具的Console对象相信很多人使用过&#xff0c;熟练的Web开发人员会经常使用 console.log() 在其代码中打印消息和调试问题&#xff0c;实际上还有很多很有用的功能和技巧&#xff0c;善用之可以极大提高Web开发&#xff0c;网站调优的效率&#xff01; 这里我们总结…

Ansible---Playbook剧本

文章目录 Playbook案例1 Playbook剧本基本用法案例2 Playbook剧本定义、引用变量案例3.when条件判断迭代剧本Roles 模块 Playbook Tasks&#xff1a;任务是 Playbooks 的核心&#xff0c;它们是 Playbook 中的一项指令&#xff0c;告诉 Ansible 在远程主机上执行什么操作。每个…

kubectl_进阶_安全

安全 在前面的学习中&#xff0c;我们知道对于资源对象的操作都是通过 APIServer 进行的&#xff0c;那么集群是怎样知道我们的请求就是合法的请求呢&#xff1f; 这就涉及到k8s的安全相关的知识了。 1. API对象 Kubernetes有一个很基本的特性就是它的所有资源对象都是模型…

pdf2htmlEX:pdf 转 html,医学指南精细化处理第一步

pdf2htmlEX&#xff1a;pdf 转 html&#xff0c;医学指南精细化处理第一步 单文件转换多文件转换 代码&#xff1a;https://github.com/coolwanglu/pdf2htmlEX 拉取pdf2htmlEX 的 Docker&#xff1a; docker pull bwits/pdf2htmlex # 拉取 bwits/pdf2htmlex不用进入容器&…

统信UOS 1070桌面操作系统如何备份及恢复全盘数据

原文链接&#xff1a;统信UOS 1070桌面操作系统如何备份及恢复全盘数据 Hello&#xff0c;大家好啊&#xff01;数据备份和还原对于保护我们的重要信息至关重要&#xff0c;尤其是当系统遭遇意外时&#xff0c;能够快速恢复到正常状态。今天&#xff0c;我将介绍如何在统信UOS …

树莓派配置双网卡分别为AD HOC和AP模式

树莓派配置双网卡分别为AD HOC和AP模式 需求说明&#xff1a;为了实现分级网络管理&#xff0c;将多个无人机分簇&#xff0c;簇间使用AD HOC进行无中心自组织的网络&#xff0c;簇内使用AP-AC模式进行中心化网络。因此&#xff0c;需要配置一台设备&#xff0c;同时完成AD HOC…

设计模式——行为型模式——策略模式(含实际业务使用示例、可拷贝直接运行)

目录 策略模式 定义 组成和UML图 代码示例 实际业务场景下策略模式的使用 策略模式优缺点 使用场景 JDK中使用策略模式示例 参考文档 策略模式 定义 策略模式定义了一系列算法&#xff0c;并将每个算法封装起来&#xff0c;使它们可以相互替换&#xff0c;且算法的变化…

【微信小程序开发】微信小程序、大前端之flex布局方式详细解析

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

液晶高抗干扰驱动LCD段码屏驱动芯片VK2C22抗干扰系列瓦斯表段码LCD液晶驱动芯片

VK2C22是一个点阵式存储映射的LCD驱动器&#xff0c;可支持最大176点&#xff08;44SEGx4COM&#xff09;的LCD屏。单片机可通过I2C接口配置显示参数和读写显示数据&#xff0c;也可通过指令进入省电模式。其高抗干扰&#xff0c;低功耗的特性适用于水电气表以及工控仪表类产品…

简单几步解决Windows 10播放视频提示安装HEVC扩展

相信有不少人都遇到过以下的问题&#xff0c;废话不多说&#xff0c;直接上干货&#xff01; 1.下载插件 免费地址链接: 点击下载 2.安装插件 如图所示&#xff0c;在下载的目录路径里&#xff0c; 1.按住键盘 SHIFT&#xff0c;点击鼠标右键&#xff0c;选择在此处打开Powe…

4WRPH系列比例阀外置放大器

控制4WRPH6或4WRPH10比例伺服阀放大器适用于驱动带非线性曲线的直动式比例伺服电磁阀&#xff0c;模拟量控制电器放大器模块式的放大器用于安装在机柜内35mm卡轨架上&#xff0c;输出级带电气反馈用于闭环控制。使能输入功能可控制放大器输出开或关&#xff0c;带斜坡时间发生器…

const成员函数、cout/cin和重载运算符<<、>>、

目录 一、为什么cout&#xff0c;cin可以自动识别类型&#xff1f; 二、留提取运算符重载&#xff08;<<&#xff09; 三、留插入运算符重载&#xff08;>>&#xff09; 四、对上述的总结&#xff1a; 五、const成员 成员函数原则&#xff1a; 六、默认成员函…

Object类

Object类 概念&#xff1a;Object类是所有类的父类&#xff0c;也就是说任何一个类在定义时候如果没有明确的指定继承一个父类的话&#xff0c;那么它就都默认继承Object类&#xff0c;因此Object类被称为所有类的父类&#xff0c;也叫做基类/超类。 常用方法 方法类型描述eq…

Python实战开发及案例分析(12)—— 模拟退火算法

模拟退火算法&#xff08;Simulated Annealing&#xff09;是一种概率搜索算法&#xff0c;源自于金属退火过程。在金属退火中&#xff0c;通过缓慢降低温度&#xff0c;金属内部的原子能够从高能态逐步达到较低能态。模拟退火算法利用类似的原理&#xff0c;通过随机搜索和概率…

Samtec连接器应用科普 | 连接智能工厂中的AI

【摘要/前言】 本文是系列的第一部分&#xff0c;我们将探讨人工智能在工业领域的作用。 人工智能&#xff08;AI&#xff09;的话题最近成为头条新闻&#xff0c;因为最新一代基于云的人工智能工具有望为机器的力量带来重大飞跃。在所有关于人工智能将如何影响我们的讨论中&…

Android内核之Binder消息处理:binder_transaction用法实例(七十三)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

overflow:hidden对解决外边距塌陷的个人理解

外边距塌陷&#xff1a; 子元素的上外边距大于父元素的上外边距&#xff0c;导致边距折叠&#xff0c;取两者之间最大值&#xff0c;即子元素外边距&#xff0c;导致父元素上外边距失效。 解决办法&#xff1a;在父元素样式添加overflow:hidden;或者border:1px solid black;(不…

Python数据分析实战

文章目录 第1关&#xff1a;读取MoMA数据集第2关&#xff1a;计算艺术家年龄第3关&#xff1a;把年龄换算成年代第4关&#xff1a;总结年代数据第5关&#xff1a;将变量插入字符串第6关&#xff1a;创建艺术家频率表第7关&#xff1a;创建显示艺术家信息的函数第8关&#xff1a…
最新文章