You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MATLAB高速UART接收16位数据异常问题求助

问题描述

STM32将16位传感器数据拆分为两个8位字节,通过UART发送至MATLAB;MATLAB先发送验证值11(uint8)给STM32,STM32收到后开始持续发送数据,MATLAB将两个字节重组为16位数据。

已知条件:

  • 数据拆分与重组逻辑经测试无误
  • 第三方串口工具接收STM32数据显示正常
  • 在STM32中加入20ms延迟后问题解决,但延迟过大不符合高速传输需求
  • 删除MATLAB中的plot命令后性能有提升,但核心问题(循环仅存储首个数据)仍未解决

当前现象:MATLAB接收1000条数据时,所有存储值均为首个数据(如2530)

附MATLAB代码:

clear
close all;
load('fi4.mat');
clc
serialportObj = serialport("COM3",115200);
i=2
tim=0;
data=0;
w=0;
data_valid=0;
validate=11;
write(serialportObj, validate, "uint8");

while(1)
    tic
    data=read(serialportObj,2,"uint8");
    res = double(typecast([uint8(data(2)), uint8(data(1))], 'uint16'))
    %FilterdSignal=filter(Hd, res);
    sig(i)=res;
    w(i)=sig(i)+(0.95*w(i-1));
    ff(i)=w(i)-w(i-1);

    if i <=300
        figure(2)
        plot (sig);
    else
        figure(2)
        plot(sig(end-300:end));
    end
    i=i+1;
    c=toc;
    tim=c+tim;
end

解决思路与方案

1. 修复串口数据读取的同步问题

核心问题是MATLAB每次读取时只取缓冲区最旧的2个字节,没有处理累积的新数据,导致循环重复读取初始值。修改读取逻辑,确保每次获取最新的完整数据组:

while(1)
    tic
    % 等待缓冲区有至少2字节数据,避免空读
    while serialportObj.NumBytesAvailable < 2
        pause(0.001); % 短等待降低CPU占用
    end
    % 读取所有可用字节,只保留最后一组完整的2字节(最新数据)
    all_data = read(serialportObj, serialportObj.NumBytesAvailable, "uint8");
    if mod(length(all_data),2) == 1
        all_data = all_data(1:end-1); % 丢弃奇数个字节中的最后一个,保证数据完整性
    end
    data = all_data(end-1:end); % 取最新的一组2字节
    
    res = double(typecast([uint8(data(2)), uint8(data(1))], 'uint16'));
    % 后续数据处理逻辑不变...

2. 优化实时绘图性能

重复创建figure和plot会严重阻塞主线程,提前创建绘图对象并仅更新数据:

% 循环外提前初始化绘图组件
figure(2);
ax = axes;
h_plot = plot(ax, []);
xlim(ax, [1 300]);
ylim(ax, [0 65535]); % 根据你的16位数据实际范围调整

while(1)
    % ... 数据接收与处理逻辑 ...
    
    sig(i)=res;
    w(i)=sig(i)+(0.95*w(i-1));
    ff(i)=w(i)-w(i-1);

    % 仅更新绘图数据,不重复创建对象
    if i <=300
        set(h_plot, 'XData', 1:i, 'YData', sig(1:i));
    else
        set(h_plot, 'XData', (i-299):i, 'YData', sig(end-300:end));
        xlim(ax, [i-299 i]);
    end
    drawnow limitrate; % 控制绘图刷新速率,避免阻塞主线程
    
    i=i+1;
    c=toc;
    tim=c+tim;
end

3. 确认STM32发送逻辑

检查STM32代码,确保收到验证值后,是持续读取并发送最新的传感器数据,而非重复发送初始值。可以在STM32中添加日志输出,确认每次发送的字节都是传感器的实时拆分数据。

4. 校准串口参数

  • 确保STM32与MATLAB的串口参数完全一致:波特率115200、数据位8、停止位1、无校验
  • 为MATLAB串口设置合理超时时间,避免读取异常:
serialportObj.Timeout = 0.1; % 设置0.1秒超时

内容的提问来源于stack exchange,提问作者yaser kh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 01:20:38