实时读取和保存串口数据问题解决记录(附Windows和Linux下的代码)

Python — 获取电脑串口数据并保存到txt文件 Python —— 获取电脑串口数据 阅读详情

这两天在研究用C语言从串口接收数据。在Windows下接收数据网上已经有例子直接能用,但是在Linux下接收数据总是有问题,费了几天时间才解决,这里简单记录一下踩过的坑。

Linux下使用termios库来进行串口通信,主要是VTIME和VMIN两个参数的配置,具体的参数含义和组合说明有文章已经写得很清楚了,具体看Linux 串口编程学习记录(termios.h)

但是按照这样配置完成后发现读取的数据老是掉帧。把录制下来的数据打开后一个个字节地寻找帧头帧尾查看问题原因,发现是循环read的过程中,每次read经常是漏了一两个字节的数据,造成数据丢失,解析不出完整帧导致掉帧。最后发现是其中一些特定数据被用作特殊控制了。具体解决方法在解决方法:Linux串口接收字节0x11,0x0d,0x13丢失。简单来说就是网上的很多Linux下读写串口的示例程序都没对c_iflag进行有效的设置,这样传送ASCII码时没什么问题,但传送二进制数据时遇到0x0d,0x11和0x13却会被用作特殊控制了,关掉 ICRNL 和 IXON 选项即可解决。

实际数据特殊控制字符
0x0d回车符CR
0x11^Q VSTART字符
0x13^S VSTOP字符

在我的程序中具体表现是360000字节的数据中没有一个0x11或者0x13,0x0d倒还是正常的。

插入一行代码就能解决

// 把终端I/O设置为原始模式(串口通讯就是终端I/O的原始模式)时输入属性设置为
options.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);

具体在Linux下读取串口数据并保存在二进制文件中的完整代码附在下面

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>

int main(int argc, char *argv[])
{
    int fd;
    uint8_t buf[60];
    int msg_length;
    
    // 用来存储原始串口消息
    FILE *fp_msg = fopen("msg_result.txt", "wb+");

    // O_RDWR表示以读写方式打开,O_NOCTTY表示不将串口设备作为控制终端
    fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY );
    if (fd < 0)
    {
        perror("open serial port failed!!!");
        return -1;
    }
    
    // 使用tcgetattr()函数获取当前的串口配置参数,然后修改需要的参数,最后使用tcsetattr()函数重新设置串口参数
    struct termios options;
    tcgetattr(fd, &options);

    cfsetispeed(&options, B921600);                         // 串口波特率为115200
    cfsetospeed(&options, B921600);
    options.c_cflag |= CLOCAL | CREAD;                      // 忽略调制解调器状态线 | 启用接收器
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;                                 // 使用8个数据位
    options.c_cflag &= ~PARENB;                             // 禁用奇偶校验
    options.c_cflag &= ~CSTOPB;                             // 使用1个停止位
    
    // options.c_cflag |= CRTSCTS;                             // 使用硬件流控制。在高速(19200bps或更高)传输时,使用软件流控制会使效率降低,这个时候必须使用硬件流控制。
    // options.c_iflag |= IXON | IXOFF; //使用软件流控制
    // options.c_cflag &= ~OPOST;        //原始数据(RAW)输出
    options.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);

    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    options.c_oflag &= ~OPOST;
    options.c_cc[VMIN] = 60;                                
    options.c_cc[VTIME] = 0;                               // 串口读取的超时等待时间
    tcsetattr(fd, TCSANOW, &options);

    // 读取前先清空缓存,防止数据污染
    tcflush(fd, TCIOFLUSH);

    // while (1)
    for(int32_t j = 0; j < 6000; j++)
	{
        msg_length = read(fd, buf, sizeof(buf));
        printf("%d attempt get %d byte\n", j, msg_length);
        
        if (msg_length > 0)
        {
            fwrite(buf, sizeof(uint8_t), msg_length, fp_msg);
        }
	}

    fclose(fp_msg);
    close(fd);
    return 1;
}

顺便把Windows下读取串口数据并保存在二进制文件中的完整代码也附上吧

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdint.h>
#include <Windows.h>
#include <time.h>
#include <winnt.h>

int main()
{
    HANDLE hCom;
	TCHAR serial_port[100];
    uint8_t buf[58] = {0};
	DWORD RLen = 0;
    BOOL status;

	wsprintf(serial_port, TEXT("\\\\.\\COM%d"), 5);
	// COM口 
    // 允许读和写 
    // 指定共享属性,由于串口不能共享,所以该参数必须为0 
    // 打开已经存在的串口 
    // 属性描述,该值为FILE_FLAG_OVERLAPPED,表示使用异步I/O,该参数为0,表示同步I/O操作
	hCom = CreateFile(serial_port, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hCom == INVALID_HANDLE_VALUE){
		// printf("打开COM口失败! %s\n", serial_port);
		return 0;
	}

	SetupComm(hCom, 5800, 5800);                //设置输入缓冲区和输出缓冲区的大小
 
	// 超时设置
	COMMTIMEOUTS TimeOuts;
	// 设定读超时
	TimeOuts.ReadIntervalTimeout = 0;           //读间隔超时
	TimeOuts.ReadTotalTimeoutMultiplier = 0;    //读时间系数
	TimeOuts.ReadTotalTimeoutConstant = 5000;   //读时间常量
	// 设定写超时
	TimeOuts.WriteTotalTimeoutMultiplier = 1;   //写时间系数
	TimeOuts.WriteTotalTimeoutConstant = 1;     //写时间常量
	SetCommTimeouts(hCom, &TimeOuts);           //设置超时

	// 配置串口
	DCB dcb;
	GetCommState(hCom, &dcb);
	dcb.BaudRate = 921600;                      // 波特率
	dcb.ByteSize = 8;                           // 每个字节有8位
	dcb.Parity = NOPARITY;                      // 无奇偶校验位
	dcb.StopBits = ONESTOPBIT;                  // 一个停止位
	SetCommState(hCom, &dcb);

    // 用来存储原始串口消息
    FILE *msg_result_txt = fopen("msg_result.txt", "wb+");
    assert(msg_result_txt != NULL);

    // while (1)
    for(int32_t j = 0; j < 60000; j++)
	{
		// PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR); // 清空缓冲区
		status = ReadFile(hCom, buf, sizeof(buf), &RLen, NULL);
		if (status)
		{
            fwrite(buf, sizeof(uint8_t), RLen, msg_result_txt);
			printf("%d attempt get %d byte\n", j, RLen);
		}
	}

    fclose(msg_result_txt);
    CloseHandle(hCom);

    return 1;
}
【博客5】缤果LabView串口调试助手V2.0 (高级篇) 一款强大而稳定的串口调试助手,支持常用的110-921600bps波特率及自定义波特率,波特率最高可支持8000000(串口硬件有关),可适应于非标准波特率。支持串口自动识别,能设置校验、数据位和停止位,能以ASCII码或十六进制接收或发送任何数据或字符,可以任意设定自动发送周期,并能将接收数据保存成文本文件,能发送任意大小的数据或字符。 阅读详情

相关推荐

SerialPlot教程:串口数据实时波形显示与多通道可视化调试

串口通信是嵌入式开发和电子调试中最基础的数据交互方式,但面对不断涌来的十六进制或ASCII数据流,仅靠文本形式难以直观判断信号变化趋势。串口数据可视化的核心价值,在于将离散的字节流转换为可观察的连续波形,从而快速定位异常、验证算法与调参效果。实时曲线显示技术不仅适用于传感器数据采集、IMU姿态解算、电机PID调试等典型场景,也能大幅缩短“采集—分析—调整”的迭代周期。SerialPlot作为一款基于Qt的跨平台串口波形显示工具,支持多通道数据解析、自定义帧格式、波形缩放与CSV导出,能以极低的学习成本实现串

weixin_33979203的博客 462

STM32使用DMA传输UART空闲中断中接收的数据遇到的问题以及解决方法

串口配置:使用默认配置(传输数据长度为8 Bit,奇偶检验无,停止位为1 Bit, 接收和发送都使能),因为我的是LIN项目所以使用的时串口的LIN模式,一般就是异步通信。开启DMA通道中断,虽然Size会有错误,但是接收的数据是正确的,只要全满中断和串口空闲中断就可以了,不需要半满中断。stm32g0xx_hal_dma.h定义了全满中断、半满中断和错误中断。至此,可以正常接收数据,并且中断回调函数中的Size得到的值也是正确的。在串口页面查看中断,可以发现DMA通道的中断已经取消了。

objctly的博客 5387

告别硬件依赖!用VSPD和socat搞定跨平台串口调试(Windows/Linux保姆级教程)

本文详细介绍了如何利用VSPD和socat工具实现跨平台虚拟串口调试,解决Windows和Linux环境下的硬件依赖问题。通过实战案例和优化技巧,帮助开发者在嵌入式开发和物联网协议调试中提升效率,特别适合Modbus和DLT645等协议的验证与测试。

weixin_28726671的博客 367

练手项目:串口 读取 温度传感器 数据 并显示

练手项目:串口 读取 温度传感器 数据并显示 串口读取的温度数据, 可以传给数据库,记录下来 可以传给网页实时显示。 这样就可以同时学习网页制作,和数据库的相关内容了, 以检测你学些web html技术和学习 mysql 技术的成果。 也可以通过Qt 程序读取。 平时学习编程的时候,如果有了实物配合,有具体的要求 之后,会学习的更快。 1 硬件准备 这个项目要求如下的硬件配置: 电脑一台,win7 64位系统。 USB 转485 模块一个,该模块可以给外部 温度传感器模块,提供5v 直流电源。 温度传感器模

abc 1万+

Linux串口编程:解决read()读不全问题与可靠数据帧接收实现

在嵌入式系统与物联网开发中,串口通信是连接微控制器、传感器等设备的基础接口。其底层基于UART协议,工作在物理层与数据链路层,负责字节流的透明传输。由于UART硬件FIFO缓存与操作系统终端驱动的工作机制,Linux环境下直接调用read()系统调用读取串口数据时,常出现无法一次性读取完整数据帧的现象,这源于非规范模式下read()的即时返回特性与硬件中断触发策略。为解决这一问题,需在应用层实现帧同步,核心是设计带超时机制的可靠读取函数。通过I/O多路复用技术如select(),结合非阻塞I/O与精确超时控

weixin_30613433的博客 290

串口屏开发:数据记录控件的使用总结

数据记录控件是串口屏开发中非常有用的功能之一,它可以帮助我们以表格形式记录和显示告警数据。通过使用数据记录控件提供的API,我们可以方便地创建表格、填充数据并将其显示在串口屏上。数据记录控件是串口屏中的一个功能模块,它允许我们以表格形式记录和显示数据。通过数据记录控件,我们可以方便地创建表格,并在表格中填充数据。对于告警数据的记录和显示,数据记录控件是一个非常有用的工具。数据记录是串口屏中重要的功能之一,它可以帮助我们记录和显示告警数据。创建表格后,我们可以使用数据记录控件的API来填充表格数据。

CfgTf__的博客 433

SpringBoot+jSerialComm实现Java串口通信 读取串口数据以及发送数据

记录一下使用SpringBoot+jSerialComm实现Java串口通信,使用Java语言开发串口,对串口进行读写操作,在win和linux系统都是可以的,有一点好处是不需要导入额外的文件。

蚂蚁舞 1万+

串口调试助手.zip_labview_polehdn_串口助手_串口自动保存_串口读写助手

实现串口读写功能,自动根据读取的串口更新串口号,并能实时保存收发数据

SpringBoot+RXTXcomm实现Java串口通信 读取串口数据以及发送数据

记录一下使用SpringBoot+RXTXcomm实现Java串口通信,使用Java语言开发串口,对串口进行读写操作。

蚂蚁舞 6441

在 Zemax 非序列模式下建立干涉仪模型

Zemax 利用其相干检测功能,将到达探测器的射线的能量相干地组合起来,同时考虑每条检测到的射线的幅度和相位。从对这些干涉条纹的定量评估来看,光学干涉仪具有广泛的应用,包括在天文学中用于测量天体的大小,在计量学中用于精确测量距离,在显微镜中用于提高分辨率,以及在物理和工程的各个领域中用于检测条件的微小变化。在光学干涉仪中,使用的是光波。非相干和相干相加的总功率是守恒的,但相干光束的峰值辐照度应该是非相干光束总和的 2 倍,这是理所当然的。请注意,条纹的缺失是显而易见的,因为不再从相干的角度观察探测器。

jkh920184196的博客 2382

Windows 10/11下Drive Composer Pro 2.9.0完整安装与连接ACS880变频器实战教程

本文详细介绍了在Windows 10/11系统上安装Drive Composer Pro 2.9.0并连接ACS880变频器的完整教程。从系统环境准备、软件安装到许可证配置,再到USB、蓝牙和以太网三种连接方式的实战操作,帮助工业自动化工程师快速掌握ABB变频器的调试技巧。

weixin_32956805的博客 528

如何用RJCP.DLL.SerialPortStream构建跨平台串口应用:Windows与Linux完美兼容指南

RJCP.DLL.SerialPortStream是一个独立实现的串口通信库,提供了比系统自带SerialPort更可靠的跨平台串口通信解决方案,支持Windows和Linux系统。本文将详细介绍如何快速上手使用这个库构建跨平台串口应用,解决传统串口通信中的稳定性问题。 ## 🚀 快速了解RJCP.DLL.SerialPortStream ### 为什么选择它? 传统的System.IO.

gitblog_00771的博客 1012

海外跨境电商商城源码-进出口电商平台网站-多语言多商户平台

我们的海外跨境电商系统源码还包括各种功能模块,如用户管理、商品管理、订单管理等。支付管理:与主流支付平台(如Stripe、PayPal等)的集成,支持多种支付方式;订单管理:创建订单、支付订单、取消订单等操作,以及订单状态查询和历史记录;购物车管理:添加商品到购物车、查看购物车、修改购物车中的商品数量等操作;商品管理:商品信息录入、编辑、删除等操作,以及商品分类和搜索功能。客服管理:在线咨询、投诉处理等功能,提供更好的用户服务。用户管理:注册、登录、忘记密码、个人资料。# 检查电子邮件地址是否有效。

柏诣科技的博客 2661

window Linux下的串口通讯

windows下的串口你通讯 参照https://blog.youkuaiyun.com/yafeilinux/article/details/4717706 2.Linux下的串口通讯: https://blog.youkuaiyun.com/g1036583997/article/details/44805217 上面这个链接中就有说明Linux下用polling 模式打开,使用定时器去读取数据。 https:/...

u012719076的博客 470

部署与可视化系统:移动端落地保姆级教程:YOLOv8 转换为 NCNN 并封装进 Android App 调用摄像头实时检测

本文介绍了在移动端部署YOLOv8模型的最佳实践。通过实测数据对比,采用NCNN框架在骁龙865设备上可实现35+FPS的实时推理性能。文章详细分析了NCNN相比TFLite、MNN等框架的优势,包括更高的ARM CPU性能、更优的Vulkan GPU加速和更小的模型体积。同时提供了从PyTorch模型到NCNN格式的完整转换流程,包括FP16优化和INT8量化方法,并重点解析了YOLOv8特有的输出格式处理要点。建议开发者先在Python环境验证NCNN推理流程,再部署到Android平台,以确保最佳性能

ZXSXJ的博客 209

ThingsBoard教程(十九):规则节点概览介绍

在ThingsBoard的CE V2.5.6版本中,一共有这几种类型在每一种类都有包含了多个节点,每一种类型的节点都有不同的颜色表示本篇文章做一个简单的概括,后续的文章会详细讲解每一个种类的节点如何使用,每一个节点的使用。一共有10个,使用黄色表示 过滤器节点用于消息过滤和路由。一共有9个,使用绿色 属性节点用于更新传入消息的元数据。一共三个,使用蓝色 转换节点用于更改传入消息字段,如发起者、消息类型、有效负载和元数据。一共21个,使用红色标识 动作节点根据传入的消息执行各种动作。一共9个,使用黄色表示,

知无涯 1万+

USB转串口设备串口号固定:Windows与Linux双平台实战指南

串口通信是嵌入式开发、工业控制和设备调试中的基础技术,它实现了计算机与外部硬件设备的数据交换。其核心原理是通过特定的通信协议在发送端和接收端之间传输串行数据流。在工程实践中,稳定的设备标识是保证通信可靠性的关键。然而,操作系统对USB转串口设备的动态枚举机制,常导致设备号(如COM口或/dev/ttyUSB*)随连接端口或顺序变化,这给需要固定端口的上位机软件、自动化脚本和持续集成环境带来了困扰。通过理解设备枚举与驱动加载机制,我们可以利用系统的底层配置能力来锁定设备标识。在Windows平台,可通过设备管

weixin_30735745的博客 318

基于STM32L4XX 、HAL库的TMC2209-LA-T步进电机驱动器驱动程序应用设计

/ R/W=0 表示写。uint32_t gconf_value = (0 << 0) // I_scale_analog: 禁用,使用UART控制电流。uint32_t ihold_irun = (8 << 0) // 保持电流 8/31 最大值。

PP_Cottage的博客 450

windows开发的qt项目移植到linux平台

关键字:qt、linux、window、Qserialport 0 前言 接触这个任务之前,完全qt小白,大大小小的坑踩了不少。 1 环境与配置 qt5.12.12 ubuntu20.04 基于stm32板子的开发程序 2 实现的功能 需要将window平台开发的qt程序移植到linux系统中运行。 3 串口问题 从win移植到linux中,串口老是报错。解决思路如下: ...

m0_52174744的博客 6461

神经形态芯片:IBM TrueNorth技术详解以及应用案例

2018年的一项演示中,机器人使用TrueNorth处理了复杂的路径规划,功耗仅为传统系统的1/10。它通过模仿人脑的结构,解决了传统芯片在功耗和并行性上的痛点,并在图像识别、物联网和机器人等领域展现了强大潜力。:不同于传统芯片的时钟驱动,TrueNorth是事件驱动的。例如,工厂中的振动传感器使用TrueNorth检测设备故障的早期迹象,实现了更高效的维护策略,避免了停机时间。:在医疗领域,TrueNorth可以用于可穿戴设备,比如一个智能助听器,它能过滤噪音并增强特定声音,功耗低到可以用纽扣电池供电。

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 2477

在anaconda环境中使用conda命令安装cuda、cudnn、tensorflow(-gpu)、pytorch

文章目录在anaconda环境中使用conda命令安装cuda、cudnn、tensorflow(-gpu)、pytorch结论参考资料解释相关命令版本关系版本选择总结:实验 在anaconda环境中使用conda命令安装cuda、cudnn、tensorflow(-gpu)、pytorch 结论 使用conda虚拟环境 使用conda命令安装 最重要的是版本关系(python、cuda、cudnn、pytor或者tensorflow框架)的对应。 参考资料 tensorflow2.x安装 理清GPU、

纸上得来终觉浅,绝知此事要躬行! 3万+

go-serial调试技巧:如何诊断和解决串口通信问题

串口通信是许多硬件项目中不可或缺的一环,但调试过程中常常会遇到各种棘手问题。本文将分享使用go-serial库时的实用调试技巧,帮助开发者快速定位并解决常见的串口通信故障,让你的项目开发更加顺畅高效。 ## 一、环境配置检查:确保基础设置正确无误 在开始调试前,首先要确认你的开发环境是否正确配置。go-serial作为跨平台的串口库,需要针对不同操作系统进行适当设置。 ### 1.1 确认端

gitblog_00173的博客 312

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

ubuntu 下虚拟串口问题及处理方案

代码如下:(水平不高,高手斧正)

bird_bai001的博客 1014

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

终极跨平台串口助手:如何在Windows、Linux、Android和macOS上轻松调试串口设备

你是否曾经为了调试嵌入式设备而在不同操作系统间切换,每次都要重新适应新的串口工具?或者因为找不到一款真正跨平台的串口助手而头疼?今天,我要向你介绍一个能彻底解决这些问题的开源神器——SerialPortAssistant串口助手。这款工具就像你的数字瑞士军刀,可以在Windows、Linux、Android和macOS四大主流平台上无缝运行,让你无论使用什么设备,都能享受一致的串口调试体验。 #

gitblog_01193的博客 461

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

免费串口调试工具终极指南:3分钟掌握跨平台通信技巧

在嵌入式开发和硬件调试的世界里,串口通信是最基础也是最重要的调试手段。无论你是在调试单片机、物联网设备还是工业控制系统,一个可靠、易用的串口调试工具都能让你的工作效率提升数倍。今天,我要向大家介绍一款完全免费、功能全面的开源串口调试工具——SerialPortAssistant(串口助手)。 这款基于Qt框架开发的工具支持Windows、Linux、Android和macOS四大主流平台,提供了

gitblog_00647的博客 1065

Go串口开发避坑指南:基于tarm/serial的常见问题与解决方案

串口通信是嵌入式开发和硬件交互中的关键技术,但在Go语言实现过程中常遇到各种棘手问题。本文基于tarm/serial库(项目路径:gh_mirrors/ser/serial),总结了10个新手最易踩坑的场景及对应的解决方案,帮助开发者快速构建稳定可靠的串口应用。 ## 一、设备权限被拒绝:权限配置终极方案 **问题表现**:调用`OpenPort`函数时返回`permission denied

gitblog_01165的博客 1142
上一篇: 使用matlab建立Kd-tree及最近邻查询
john_xia
博客等级 码龄8年 92粉丝 25原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值