这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界» 论坛首页» 高校专区» 东师科技爱好者» 秉着开源的原则,将MATLAB串口示波器的源代码发放出来,希望能给大家帮助(原创

共16条 1/2 1 2 跳转至

秉着开源的原则,将MATLAB串口示波器的源代码发放出来,希望能给大家帮助(原创)

菜鸟
2016-04-17 20:06:58 打赏

转载请注明作者:东北师范大学 黄兆伟

嗯~整个项目在MATLAB上做了大概四天,从对MATLAB的串口操作一无所知到现在做出一个小的7通道的16位无符号(有符号)整型串口示波器,接触到了很多MATLAB高大上的玩法,而且网上用matlab来做波形显示的参考资料不多,希望。将源代码发出来,供大家参考,废话不多说,马上上代码~代码分为四个文件,其中MATLAB串口代码三个,一层楼一个~首先是串口配置函数。接下来的每层楼都更新一个函数,并配上标注~

协会开论坛不容易,大家用了的话~能回帖的尽量回个贴~


close all; clear all; clc; hold on %这一句经测试是必要的,没有这句的话~波形显示的句柄好像无法调用 global t; global x; global m; global ii; global data; %数据缓冲矩阵 data = [0]; t = [0]; %显示的时候为x轴变量,本质是采样点数 m = ones(7,1); %m为数据存储矩阵,每一行为一个通道,从串口打开到结束,每一行的数据都存放于这个矩阵,接收到波形后可以进行数据分析、拟合 x = -100; %x轴起始坐标 ii = 1; %也是一个类似起始位的东西 h1 = plot(1,'b','MarkerSize',20); %通道1的颜色与线粗,h1为句柄,以下同 h2 = plot(0,'g','MarkerSize',20); h3 = plot(0,'r','MarkerSize',20); h4 = plot(0,'c','MarkerSize',20); h5 = plot(0,'m','MarkerSize',20); h6 = plot(0,'y','MarkerSize',20); h7 = plot(0,'k','MarkerSize',20); H = [h1;h2;h3;h4;h5;h6;h7]; %所有通道句柄的入口矩阵,方便回调函数传参 title('Matlab Scope——东北师范大学电磁翼'); %本开源代码由东北师范大学——电磁翼小组(2016年4月17日)编写 legend('ch1','ch2','ch3','ch4','ch5','ch6','ch7',2); %在左上角标注通道 %grid on; xlabel('采样点数'); %标注X轴 ylabel('数值大小'); %标注Y轴 s = serial('COM18'); %选择串口~ s.BaudRate = 9600; %选择波特率 s.DataBits = 8; %设置数据位数 s.StopBits = 1; %设置停止位 set(s,'Parity', 'none','FlowControl','none'); %无校验位,无流控制 s.ReadAsyncMode = 'continuous'; %异步接收模式为连续 s.BytesAvailableFcnMode = 'byte'; %回调函数模式为字节 s.BytesAvailableFcnCount = 20; %每接收到20个字节,触发中断,调用回调函数,0xff,0xa5,0x5a(0x5b) 三位帧头+七位数据 s.BytesAvailableFcn = {@callback_16bit,H}; %回调函数地址,以及相应波形显示通道句柄 try fopen(s); %打开串口 catch err fprintf('串口打开失败。\n'); end fprintf('串口打开成功\n');






关键词: MATLAB 串口 波形

菜鸟
2016-04-17 20:14:45 打赏
2楼
function callback_16bit(s,BytesAvailable,p) %function callback(s, p) % 串口接收中断的回调函数 global t; global x; global m; global ii; global data; n_bytes = s.BytesAvailable; %获取串口接收到数据的个数 out = fread(s,[1 n_bytes],'uint8'); %将串口数据以一行8位整型的形式显示出来 mat = zeros(7,1); %8位转16位数据处理矩阵 data = [data out]; %合并缓存矩阵 while(length(data) >= 17) %当data长度大于17时,不停循环 if(data(1) == 255 && data(2) == 165 && data(3) == 90) %有符号整型帧头 0xff,0xa5,0x5a %确认为一帧数据 data(1:3) = []; %清空帧头位 for i = 1:7 %将7个通道的数据提取出来 mat(i,1) = data(1)*256+data(2); %将两个8位数据合并成16位数据 if (mat(i,1) > 32768) %提取符号位 mat(i,1) = -(65536-mat(i,1)); %求补码 end data(1:2) = []; %清空提取到的data缓存数据 end m = [m mat]; %合并波形显示矩阵 ii = ii + 1; %计数+1 t = [t ii]; %合并采样点数矩阵 x = x + 1; %移动x轴 for j = 1:7 %刷新7通道的显示句柄 set(p(j),'xdata',t,'ydata',m(j,1:length(t))); end elseif(data(1) == 255 && data(2) == 165 && data(3) == 91) %无符号整型帧头 0xff,0xa5,0x5b %确认为一帧数据 data(1:3) = []; %同上 for i = 1:7 mat(i,1) = data(1)*256+data(2); data(1:2) = []; end m = [m mat]; %读取帧数据 ii = ii + 1; t = [t ii]; x = x + 1; for j = 1:7 set(p(j),'xdata',t,'ydata',m(j,1:length(t))); end else data(1) = []; %如果不是帧头,则数据错误??跳过错误数据直到找到帧头 end end y = length(m(1,:)); %求m矩阵的列数 % ymin = min(m(1:7,y)); %求同列的最小值 % ymax = max(m(1:7,y)); %求同列的最大值 ymin = min(min(m)); %求整个矩阵的最小值 ymax = max(max(m)); %求整个矩阵的最大值 drawnow %更新图形窗口 %axis([x-150 x+150 ymin-10 ymax+20]); %更新两轴 axis([x-150 x+150 -50 50]); end




菜鸟
2016-04-17 20:15:22 打赏
3楼

最后~关闭串口~

fclose(s);

delete(s);
clear s
close all;
clear all;
clc;


菜鸟
2016-04-17 20:18:17 打赏
4楼

再来一条,单片机上数据传回函数~

//---------------------------------------- // 函数名称:send_matlab // 功能说明:MATLAB串口示波器 // 参数说明:mode为0时,matlab波形显示为16位有符号整型, // mode为1时,matlab波形显示为16位无符号整型 // CH1-CH7为7个通道波形数据 // 函数返回:无 // 修改时间:2016/4/17 // 备 注: //---------------------------------------- void send_matlab(uint8 mode,int ch1, int ch2, int ch3, int ch4, int ch5, int ch6, int ch7) { uint8 send_data[17]={0}; uint8 i; send_data[0] = 0xff; send_data[1] = 0xa5; send_data[2] = 0x5a+mode; send_data[3] = (uint8)((ch1&0xff00)>>8); send_data[4] = (uint8)(ch1&0x00ff); send_data[5] = (uint8)((ch2&0xff00)>>8); send_data[6] = (uint8)(ch2&0x00ff); send_data[7] = (uint8)((ch3&0xff00)>>8); send_data[8] = (uint8)(ch3&0x00ff); send_data[9] = (uint8)((ch4&0xff00)>>8); send_data[10] = (uint8)(ch4&0x00ff); send_data[11] = (uint8)((ch5&0xff00)>>8); send_data[12] = (uint8)(ch5&0x00ff); send_data[13] = (uint8)((ch6&0xff00)>>8); send_data[14] = (uint8)(ch6&0x00ff); send_data[15] = (uint8)((ch7&0xff00)>>8); send_data[16] = (uint8)(ch7&0x00ff); for(i=0;i<17;i++) { uart_send1(UART1,send_data[i]); } }



菜鸟
2016-04-17 20:26:55 打赏
5楼

目前还有点小bug,只能通过代码来修改通道数。

偷偷的告诉大家,在串口示波器运行的时候也可以对回调函数的代码进行修改哦,例如通道数,x、y轴缩放~保存后立马就能在示波器上看到效果~祝大家代码无BUG~接下来几楼可能会插几张图片~代码和功能还将会持续更新~


菜鸟
2016-04-17 20:28:06 打赏
6楼

菜鸟
2016-04-17 20:33:52 打赏
7楼

菜鸟
2016-04-19 13:06:56 打赏
8楼

我又回来了,这次带来的更新可以看双路十通道波形,上面五个通道是第一路的,下面五个通道是第二路的,两个通道相互不影响,两通道的Y轴数量级可以不相同,初衷是想看5路幅值高的波形和5路幅值低的波形~


专家
2016-04-19 13:10:32 打赏
9楼
谢谢楼主分享。

菜鸟
2016-04-19 14:49:27 打赏
10楼
close all; clear all; clc; global t; global m; global x; global ii; global data; global SUBP data = [0]; t = [0]; m = ones(10,1); x = 1; ii = 1; %波形图形部分设置 figure('NumberTitle', 'off', 'Name', '东北师范大学 电磁翼十路示波器'); SUBP(1) = subplot(211); hold on h1 = plot(0,'b','MarkerSize',25); h2 = plot(0,'g','MarkerSize',25); h3 = plot(0,'r','MarkerSize',25); h4 = plot(0,'c','MarkerSize',25); h5 = plot(0,'m','MarkerSize',25); title('示波器通道1-5——东北师范大学电磁翼'); %本开源代码由东北师范大学——电磁翼小组(2016年4月19日)编写 legend('ch1','ch2','ch3','ch4','ch5',2); %在左上角标注通道 xlabel('采样点数'); %标注X轴 ylabel('数值大小'); %标注Y轴 %第二路(6-10通道)波形设置 SUBP(2) = subplot(212); hold on h6 = plot(0,'b','MarkerSize',25); h7 = plot(0,'g','MarkerSize',25); h8 = plot(0,'r','MarkerSize',25); h9 = plot(0,'c','MarkerSize',25); h10 = plot(0,'m','MarkerSize',25); title('示波器通道6-10——东北师范大学电磁翼'); %本开源代码由东北师范大学——电磁翼小组(2016年4月17日)编写 legend('ch6','ch7','ch8','ch9','ch10',2); %在左上角标注通道 xlabel('采样点数'); %标注X轴 ylabel('数值大小'); %标注Y轴 H = [h1;h2;h3;h4;h5;h6;h7;h8;h9;h10]; %串口部分设置 s = serial('COM18'); %选择串口~ s.BaudRate = 19200; %选择波特率 s.DataBits = 8; %设置数据位数 s.StopBits = 1; %设置停止位 set(s,'Parity', 'none','FlowControl','none'); %无校验位,无流控制 s.ReadAsyncMode = 'continuous'; %异步接收模式为连续 s.BytesAvailableFcnMode = 'byte'; %回调函数模式为字节 s.BytesAvailableFcnCount = 100; %每接收到100个字节,触发中断,调用回调函数,0xff,0xa5,0x5a(0x5b) 三位帧头+七位数据 s.BytesAvailableFcn = {@callback_16bit,H}; %回调函数地址,以及相应波形显示通道句柄 try fopen(s); %打开串口 catch err fprintf('串口打开失败。\n'); end fprintf('串口打开成功\n');


这个是之前那张图的程序,上下双路十通道示波器,基本满足一般需求,我们用的是蓝牙传输波形数据。OPEN_SERIAL.m 打开串口通信通道,并且配置图形显示方式


共16条 1/2 1 2 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册]