Matlab串口接收绘制曲线

作者:岚膺麒钿
日期:2020.2.18
咨询QQ:2498317094(加QQ时要注明是干什么的)

关于Matlab,很多人只知道它是一个强大的数学工具,但是Matlab也可以用于嵌入式,制作界面,和下位机交互数据,实时绘制出曲线图。本文将简单介绍如何利用Matlab制作串口接收界面,实时绘制曲线。这里要用到的知识有很多,例如:matlab的GUI编程、定时器,串口通信、回调函数、Matlab的画图等。

一些知识也不多废话,直接上代码

一、主界面代码(main.m)

clc;
clear;
close all;

%%%%%%%%%%%%%%%%%%%%全局变量定义%%%%%%%%%%%%%%%%%%%%%
global Xmin Xmax Ymax Ymin  X_Start X_End Y_Start Y_End       %画曲线的重要变量
global ReceiveFlag FlagStartOrEnd COM_flag                     %标志位
global hf ha T hb1 hb4 hb2 scom hbcomText  hbPlotText hbDataText            %句柄变量
global comReceiveData AllReceiveY

%变量初始化
Xmin=-1;
Xmax=10;
Ymax=10;
Ymin=-1;
X_Start=0;
X_End=0;
Y_Start=0;
Y_End=0;
AllReceiveY=[];
FlagStartOrEnd=0;
COM_flag=0;
ReceiveFlag=0;
T=[];
scom=[];
comReceiveData=[];

% 建立界面
hf = figure('Units', 'Normalized', 'Menubar', 'figure','NumberTitle', 'off','Name', '程隆军制作(天津工业大学)','menubar','none');
set(gcf,'position',[0.2,0.1 0.6,0.8]);
ha = axes('Parent', hf, 'Units', 'Normalized','Position', [0.2 0.05 0.75 0.9]);
T = timer('Period',0.1,'ExecutionMode','FixedRate', 'TasksToExecute',inf,'TimerFcn','TimeCallback();');
hb4 = uicontrol('Parent', hf, 'Units', 'Normalized','Position', [0.02 0.85 0.1 0.1], ...
'String', '打开串口','fontsize',16,...                    %控件字体大小...
'Callback','COM_OffOrOn();');
hb1 = uicontrol('Parent', hf, 'Units', 'Normalized',...
    'fontsize',16,...                    %控件字体大小
'Position', [0.02 0.7 0.1 0.1], 'String', '开始',...
'Callback','StartOrEnd();');
hb2 = uicontrol('Parent', hf, 'Units', 'Normalized',...
    'fontsize',16,...                    %控件字体大小
'Position', [0.02 0.55 0.1 0.1], 'String', '保存',...
'Callback','SaveData(AllReceiveY);');
hbPlotText = uicontrol('Parent', hf, 'Units', 'Normalized','Position', [0 0.2 0.15 0.03 ], 'String', '停止',...
    'Style', 'text',...
  'fontname','仿宋',...                   %控件字体
    'fontsize',16,...                    %控件字体大小
'foregroundc',[0 0 0],...                %控件内字的颜色
'backgroundcolor',[1 1 1]);              %控件背景颜色设置                                       
hbcomText = uicontrol('Parent', hf, 'Units', 'Normalized','Position', [0 0.1 0.15 0.03], 'String', '串口关闭了',...
    'Style', 'text',...
  'fontname','仿宋',...                  %控件字体
    'fontsize',16,...                    %控件字体大小
'foregroundc',[0 0 0],...            %控件内字的颜色
'backgroundcolor',[1 1 1]);  %控件背景颜色设置

hbDataText = uicontrol('Parent', hf, 'Units', 'Normalized','Position', [0 0.3 0.15 0.03], 'String', '无数据',...
    'Style', 'text',...
  'fontname','仿宋',...                  %控件字体
    'fontsize',16,...                    %控件字体大小
'foregroundc',[0 0 0],...            %控件内字的颜色
'backgroundcolor',[1 1 1]);  %控件背景颜色设置
set(hf, 'DeleteFcn', {@DeleteAll});

二、串口配置代码(COM_OffOrOn.m)

function COM_OffOrOn()
global scom COM_flag hb4 FlagStartOrEnd hbcomText
if (FlagStartOrEnd==0)
    if (COM_flag==0)
        ComName_list1=inputdlg('请输入串口名称');
        ComName_list=ComName_list1{1,1};
        BaudRateName_list_Str=inputdlg('请输入串口比特率');
        BaudRateName_list_num=str2num(BaudRateName_list_Str{1,1});

        delete(instrfindall)      % 关闭串口,此句十分重要,下篇再详细解释  
    %     global s;                 % 全局变量,供串口中断函数使用  
    %     s = serial('com3');       %使用默认设置创建串口s  
    %     fopen(s);                 %打开串口  
    %     set(s,'BytesAvailableFcnMode','Terminator'); %设置中断触发方式  
    %     set(s,'Terminator','H');  
    %     s.BytesAvailableFcn =@ReceiveCallback;       % 定义中断响应函数对象  
        scom=serial(ComName_list);
    %     scom=serial(ComName_list,'BaudRate',BaudRateName_list_num,'Parity','none','DataBits',8,'StopBits',1);%设置串口属性

        set(scom,'BaudRate',BaudRateName_list_num,...
            'Parity','none',...
            'DataBits',8,...
            'StopBits',1);
        set(scom,'BytesAvailableFcnMode','terminator');
        set(scom,'terminator',10);
        scom.BytesAvailableFcn=@ReceiveCallback;  
        try 
            fopen(scom);
            set(hb4,'String', '关闭串口','foregroundc',[1 0 0]);
            COM_flag=1;
        catch
            errordlg('串口打开失败!');
            fclose(scom);%关闭串口设备对象
            delete(scom);%删除内存中的串口设备对象
            clear scom; %清除工作空间中的串口设备对象
        end

    else 
        COM_flag=0;  
        set(hb4,'String', '打开串口','foregroundc',[0 1 0]);
        fclose(scom);%关闭串口设备对象);%关闭串口设备对
        set(hbcomText,'String','串口关闭了','foregroundc',[0 0 0]);
    end
else
    errordlg('请先停止!');
end

三、绘制曲线代码(MyPlot.m)

function MyPlot(Data)
global Xmin Xmax Ymax Ymin  X_Start X_End Y_Start Y_End ha AllReceiveY     
Y_End=Data;
X_End=length(AllReceiveY)*0.1;
line([X_Start(1) X_End(1)],[Y_Start(1) Y_End(1)],'color','r','linestyle','-','Parent',ha,'linewidth',1);
if (Xmin>min(X_End))  
    Xmin=min(X_End);
end
if (Xmax<max(X_End))  
    Xmax=max(X_End);
end       
if (Ymin>Y_End) 
    Ymin=Y_End;
end
if (Ymax<Y_End) 
    Ymax=Y_End;
end
if (Xmax-Xmin>10)
    Xmin=Xmin+0.1;
end
axis(ha,[Xmin Xmax Ymin Ymax]);
Y_Start=Y_End;
X_Start=X_End;

四、串口接收代码(ReceiveCallback.m)

function ReceiveCallback(obj,event)
global scom ReceiveFlag comReceiveData hbcomText
temp = fscanf(scom) ;      % 接收数据并显示(无分号) 
if (temp(1)=='$')
    comReceiveData=temp(2:1:end);
    ReceiveFlag=1;
    set(hbcomText,'String','串口接收成功','foregroundc',rand(1,3));
else
    set(hbcomText,'String','串口接收失败','foregroundc',[1 0 0]);
end
% I = 'I received'    % 检验是否中断响应函数正常被触发(无分号) 

五、保存数据代码(SaveData.m)

function SaveData(Data)
global FlagStartOrEnd
if (FlagStartOrEnd==1)
    errordlg('请先停止!');
else
    if (length(Data)==0)
       errordlg('数据为空!');
    else
        DataName=inputdlg('请输入文件名称,本次保存为文本文件');
        DataName_list=DataName{1,1};
        fid=fopen([DataName_list,'.txt'],'a');
        [m,n]=size(Data);
        for i=1:m
            for j=1:n
                if (j==n)
                    fprintf(fid,'%d',Data(i,j));
                else
                    fprintf(fid,'%d,\t\t',Data(i,j));
                end
                
            end
            fprintf(fid,'\r\n');    
        end
        fclose(fid);
    end
end

六、开始/暂停(StartOrEnd.m)

function StartOrEnd()
global FlagStartOrEnd hb1 T COM_flag hbPlotText
if (COM_flag==1)
    if (FlagStartOrEnd==0)
        FlagStartOrEnd=1;
        start(T);
        set(hb1,'String','停止','foregroundc',[1 0 0]);
%         set(hbPlotText,'String','画图ing!','foregroundc',rand(1,3));
    else 
        FlagStartOrEnd=0;
        stop(T);
        set(hb1,'String','开始','foregroundc',[0 0 1]);  %控件背景颜色设置;
        set(hbPlotText,'String','停止画图!','foregroundc',[0 0 0]);
    end
else
    errordlg('请先打开串口!');
end

七、定时器回调函数(TimeCallback.m)

function TimeCallback()
global ReceiveFlag  comReceiveData hbPlotText AllReceiveY hbcomText hbDataText
Data=0;
if (ReceiveFlag==1)
    ReceiveFlag=0;
    Data=str2num(comReceiveData);
    if (length(Data)==1)     
        AllReceiveY=[AllReceiveY;Data];
        MyPlot(Data);
        Data=[];
        set(hbPlotText,'String','画图ing!','foregroundc',rand(1,3));
        set(hbDataText,'String',comReceiveData,'foregroundc',[0 0 1]);
        comReceiveData=[];
    else
        set(hbPlotText,'String','数据格式错误!','foregroundc',[1 0 0]);
        set(hbDataText,'String','无数据','foregroundc',[1 1 1]);
    end
else
    set(hbPlotText,'String','画图失败!','foregroundc',[1 0 0]);
    set(hbcomText,'String','串口接收失败','foregroundc',[1 0 0]);
    set(hbDataText,'String','无数据','foregroundc',[1 1 1]);
end

八、安全关闭窗口代码(DeleteAll.m)

function DeleteAll(hObject, eventdata,~)
global scom T COM_flag
if (isempty(T)~=1)
    stop(T);
    delete(T);
else
    clear T;
end
if(isempty(scom)~=1 )
    fclose(scom);%关闭串口设备对象
    delete(scom);%删除内存中的串口设备对象
    clear scom; %清除工作空间中的串口设备对象
else
    clear scom;
end

好了,以上就是全部代码,一共是8个.m文件。因为我喜欢分开写代码,所以就写在了8个脚本文件中,下图就是界面图。
在这里插入图片描述

说明
功能:串口单坐标轴单曲线接收,并可以保存数据。
使用方法:
1、运行"main.m"
2、点击“打开串口按键”,输入串口名称(例如:com1)和比特率(例如:9600)
3、点击“开始”按键,即开始画图
注意:
1、先打开串口,再开始
2、先停止,再关闭串口
3、先停止,再保存数据
4、串口发送格式:$+数据+回车,例如:$12(回车) “$”和“回车”很重要!!!!!!!

  • 18
    点赞
  • 114
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值