%matlab2019b串口功能
%matlab:注意是2019B 版本;
%300,,,300/256=1 300%256=44
%300===0X01 2c
%数据格式 S+int16的高八位+int16的低八位+int16的低八位(其实是校验和)+0x0D+0x0a
close all;
clear all;
global data000;
global count;
global ByteLength;
global RecDataInt16;
global RecDataNum;
global RecFlag;
RecFlag=0;%接收标记位
RecDataNum=1;
ByteLength=6;
count=1;
%data000=zeros(1,50000); %定长度数组
%data000(:,:)=255;%赋初值
%设置fig的属性
runtimes = 0;
recvData = 2;
fig1 = figure(1);
%设置fig和边框的距离
set(fig1, 'Position', [100, 100, 800 700], 'color', 'w'); %
xlabel('runtimes');
ylabel('data');
grid on;
hold on;
%串口设置CH340是COM3
%DAP是串口COM2
%matlab--COM3;接收端
%DAP串口---COM2发送端
%数据格式S+int16H+int16L+csum+0x0D+0x0A;
port = 'com3';
baudrate = 115200;
s = serialport(port,baudrate);
configureCallback(s,"off")
while ishandle(fig1)
%数据更新
plottime=datetime;
hh=plottime.Hour;
mm=plottime.Minute;
ss=plottime.Second;
xt1=datenum(0,0,0,hh,mm,ss);%将时间转化为日期格式
x=xt1;%给后面设置x轴的属性
%时间轴更新时间,会不断流动,形成动态曲线
runtimes=runtimes+1;
%数据纵坐标更新。
yval=recvData*recvData;
recvData=recvData+1;
data1(: ,runtimes) = xt1;%横坐标放在data1中
data0(:, runtimes) = yval;%纵坐标放在对应的位置中;
times = [1 : runtimes];
%用星号和蓝色,xt1是当前的时间格式,通过datenum转化成时分秒格式,
plot(xt1,data0(runtimes),'*b');
if RecFlag==1
plot(xt1,RecDataInt16(:,RecDataNum-1),'*r');
RecFlag=0;
end
%datetick用来自动完成对数据进行图形显示并且用日期或时间...
% %https://ww2.mathworks.cn/help/matlab/ref/datetick.html
%13的意思是时分秒的格式代号,%参考:http://blog.sina.com.cn/s/blog_86c2eb8f0102vqwt.html
datetick('x',13);
drawnow
hold on;
%延时函数
pause(1);
%串口接收到一个字节函数,然后跳到回调函数
configureCallback(s,"byte",ByteLength,@serial_callback);
pause(0.1)
%break 作用:用来跳出最内层的for循环或者while循环,脱离该循环后程序从循环代码后面继续执行。即break语句只能跳出当前层次的循环。
%如果按键e,那么就退出当前循环
if strcmpi(get(gcf,'CurrentCharacter'),'e')
clear s;
break;
end
%在命令窗口中显示相关信息
fprintf('runtimes = %d,recvData= %d\n', runtimes,recvData);
end
%串口接收回调函数
function serial_callback(s,~)
%将ByteLength个字节长度的数据接收进来
%这里的dataAAA是局部变量,每次进入之后,会将之前的ByteLength个字节数据清空
%设置一个全局变量
global data000;
global count;
global ByteLength;
global RecDataNum;
global RecDataInt16;
global RecFlag;
dataAAA = read(s,ByteLength,"uint8");
disp(dataAAA);
%因为有5个字节的数据,因此就进行5次
%i是局部变量,因此每次进入回调函数之后,每次都置0,这里重新赋值=1
%接收ByteLength个数据到data000中。
for i=0:ByteLength-1
data000(: ,count+i)=dataAAA(i+1);%因为count从1开始
fprintf('******i = %d*******\n',i);
end
%假如接收的数据不符合格式,那么将刚存入data000中的ByteLength个数据情况
if data000(count)=='S' %判断帧头
%计算校验和,如何校验和=接收的就校验和,那么就存储数据
SumTemp=data000(:,count+1) * 256+data000(:,count+2);
if data000(:,count+3)==rem(SumTemp,256)
fprintf('校验和相等\n');
%校验和相等,接收有效数据,先高字节,后低字节
RecDataInt16(:,RecDataNum)= data000(:,count+1) * 256 + data000(:,count+2);
count=count+ByteLength;
RecDataNum=RecDataNum+1;
RecFlag=1;
fprintf('recdatanum= %d \n',RecDataNum);
pause(5);
end
end
%符合传输格式,那么就将数据解出来,然后将count加ByteLength,到下一个ByteLength空间中
% fprintf('******count = %d,data_s=%d, dataNum=%d *******\n', count,data_s,dataNum);
end
视频解读
https://www.bilibili.com/video/BV1mB4y1K7Pc添加链接描述