Matlab GUI上位机界面实现串口通信

2022-08-28 13:06:55 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

Matlab GUI因项目需求,不得不学的又杂又浅,趁着还没彻底忘记,写下来一些关键注意点。

命令行窗口输入guide→Blank GUI→确定

根据自己的需求,拖动选择对应的工具,如下图所示

双击每一个对象,就可以弹出其检查器,修改其属性,字体大小、粗细、位置等,其中最关键的是两个,一是String,二是Tag,String是用来修改对象中的文字,Tag是所调用的代码名,这个要好的代码习惯,尽量所见即所得,比如串口按键就用portbutton等。弹出式菜单的String,根据需要输入多行。一般来说,习惯用面板将某一个模块的各个功能圈起来,如上图的控制区、发送区、接收区等

界面的拖动相对比较简单,接下来就需要实现具体的功能,右键对象→查看回调→callback,即可调到代码区。

我实现的功能及代码主要包括以下部分

1.串口打开与关闭

1.1右键“端口号com1”的按钮,打开callback。因为在打开串口之前需要选择对应的端口号。

代码语言:javascript复制
function ppPort_Callback(hObject, eventdata, handles)
% hObject    handle to ppPort (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns ppPort contents as cell array
%        contents{get(hObject,'Value')} returns selected item from ppPort
global port
scoms = instrfind; %读取所有存在的端口
if ~isempty(scoms)
    stopasync(scoms); fclose(scoms); delete(scoms);%停止并且删除串口对象
end
vall=get(handles.ppPort,'Value');
switch vall
    case 1
        port='com1';
    case 2
        port='com2';
    case 3
        port='com3';
    case 4
        port='com4';
    case 5
        port='com5';
end

这里handles.xxx是抓取所点击的项, handles.后面的为所抓取函数的函数名,上述代码抓取端口号com1~com5中的一个,也就是tag为ppPort的对象的值。

在弹出式菜单的String里每一行对应于case的1~5,点这些选项对应执行‘port=xxx’

1.2右键“打开串口”的按钮,打开其callback函数

代码语言:javascript复制
function pbOpenSerial_Callback(hObject, eventdata, handles)
% hObject    handle to pbOpenSerial (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global port;
display(port)
Conm_num_str = port;
global Scom;
Scom=serial(Conm_num_str);
Scom.InputBufferSize=2000; %设置好buf的空间,足够最多一次指令返回数据的存储
Scom.timeout=3;
Scom.BaudRate=115200;
Scom.DataBits=8;
Scom.Parity='none';
Scom.StopBits=1;
Scom.ByteOrder='bigEndian';
fopen(Scom); %打开串口设备对象
fprintf("open serial success");
set(handles.pbOpenSerial,'enable','off');%打开串口的按钮变成灰色,不再可用

这里需要注意的是如果想在不同的函数下用同一个变量,需要用global定义全局变量,并且在每一个要用到这个这个变量的函数中都用global 定义一下。在打开串口的函数中,串口号port调用于串口选择函数,串口配置Scom将会在关闭串口的函数中用到。

1.3右键“关闭串口”,选择callback。

代码语言:javascript复制
function pbCloseSerial_Callback(hObject, eventdata, handles)
% hObject    handle to pbCloseSerial (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
set(handles.pbOpenSerial,'enable','on');%打开串口的按钮重新可用
global Scom;%全局变量Scom
display(Scom)
fclose(Scom);
delete(Scom);

2.串口收发

在打开串口之后,开始执行数据的收发,并在发送区和接收区显示

2.1串口通过发送区文本框以及“发送数据按”钮实现串口发送

代码语言:javascript复制
function pbSend_Callback(hObject, eventdata, handles)
% hObject    handle to pbSend (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global d
global Scom
global tmp_hex
d=get(handles.editS,'String');�itS为发送数据的文本编辑框,抓取里面的字符串
if(iscell(d))%这句是debug出了问题之后的修正,有时候输入的字符串会抓取为元胞数组,需要提取其字符串,如果抓取的值直接是字符串那就处理字符串,如果抓取的是元胞数组,就提取其字符串并处理
    m=d{1};
else
    m=d
end
display(d)
switch m
    case {'PRESS','press'}
        a=['01';'03';'xx';'xx';'xx';'xx';'xx';'xx'];%本代码采用modbus协议
        data=hex2dec(a);%将16进制数字转换为10进制
        fwrite(Scom,data);%将数据发送至串口
        tmp_hex = fread(Scom,8)%接收单片机数据,并存入tmp_hex数组
        tmp_int=tmp_hex(4)*256 tmp_hex(5);
        tmp_dec=tmp_hex(6)*256 tmp_hex(7);
        tmp_press=(tmp_int*1000 tmp_dec)/1000.0%保留三位有效数字
       set(handles.editR,'string',['压力: ',num2str(tmp_press),'mN']);%将数组的值转换为字符串并在接收区显示editR为接收数据的文本编辑框
        press=[ press,tmp_press];%将数据存入press数组中,以便在坐标系中绘制曲线
   case ...
end

目前演示结果如下:

2.2发送区和接收区数据清空

代码语言:javascript复制
function pbClearT_Callback(hObject, eventdata, handles)
% hObject    handle to pbClearT (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
set(handles.editS,'String','');

% --- Executes on button press in pbClearR.
function pbClearR_Callback(hObject, eventdata, handles)
% hObject    handle to pbClearR (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
set(handles.editR,'string','');

3 坐标系显示曲线

由于项目有多种待测量需要分时显示,故采用一个弹出式菜单来控制曲线绘制。

代码语言:javascript复制
function ppCurveDisplay_Callback(hObject, eventdata, handles)
% hObject    handle to ppCurveDisplay (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns ppCurveDisplay contents as cell array
%        contents{get(hObject,'Value')} returns selected item from ppCurveDisplay
global ch
global press;%串口收发生成press数组
vall=get(handles.ppCurveDisplay,'Value');
switch vall
    case 1
        ch='xxx',axes(handles.axes1),plot(R2T,'g'),hold on,plot(R3T,'b'),plot(R4T,'r')...;
    case 2
        ch='侧向压力',cla,axes(handles.axes1),plot(press,'b'), grid on ,xlabel('SampleNum'),ylabel('Press/mN'),title(ch);%cla用于清空曲线,否则会出现曲线的叠加,坐标系的函数名为axes1,抓取该坐标系并对其进行操作
    case 3
    ...
end

显示结果如下,当然由于未连接设备,采集到的数据均为0,故为一条press=0mN的直线。

Matlab GUI实现简单的很容易,但是在操作过程中会有各种各样的bug,需要慢慢探索研究……

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/146162.html原文链接:https://javaforall.cn

0 人点赞