function callback_16bit(s,BytesAvailable,p) % 串口接收中断的回调函数 global t; global x; global m; global ii; global data; global SUBP %宏定义 plot_length = 8000; %整个视图中,波形显示多少个点, x_down = 1500; x_up = 150; road1_ch_down = 1; road1_ch_up = 5; road2_ch_down = 1; road2_ch_up = 5; n_bytes = s.BytesAvailable; %获取串口接收到数据的个数 out = fread(s,[1 n_bytes],'uint8'); %将串口数据以一行8位整型的形式显示出来 mat = zeros(10,1); %8位转16位数据处理矩阵 data = [data out]; %合并缓存矩阵 while(length(data) >= 23) %当data长度大于17时,不停循环 if(data(1) == 255 && data(2) == 165 && data(3) == 90) %有符号整型帧头 0xff,0xa5,0x5a %确认为一帧数据 data(1:3) = []; %清空帧头位 for i = 1:10 %将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轴 if(length(t) <= plot_length) for j = road1_ch_down:road1_ch_up %刷新第一路的1-5通道显示 set(p(j),'xdata',t,'ydata',m(j,1:length(t))); end for j = (5+road2_ch_down):(5+road2_ch_up) %刷新第二路的6-10通道的显示句柄 set(p(j),'xdata',t,'ydata',m(j,1:length(t))); end else for j = road1_ch_down:road1_ch_up %刷新第一路的1-5通道显示 set(p(j),'xdata',t(length(t)-plot_length:end),'ydata',m(j,length(t)-plot_length:length(t))); end for j = (5+road2_ch_down):(5+road2_ch_up) %刷新第二路的6-10通道的显示句柄 set(p(j),'xdata',t(length(t)-plot_length:end),'ydata',m(j,length(t)-plot_length:length(t))); end end elseif(data(1) == 255 && data(2) == 165 && data(3) == 91) %无符号整型帧头 0xff,0xa5,0x5b %确认为一帧数据 data(1:3) = []; %同上 for i = 1:10 mat(i,1) = data(1)*256+data(2); data(1:2) = []; end m = [m mat]; %读取帧数据 ii = ii + 1; t = [t ii]; x = x + 1; if(length(t) <= plot_length) for j = road1_ch_down:road1_ch_up %刷新第一路的1-5通道显示 set(p(j),'xdata',t,'ydata',m(j,1:length(t))); end for j = (5+road2_ch_down):(5+road2_ch_up) %刷新第二路的6-10通道的显示句柄 set(p(j),'xdata',t,'ydata',m(j,1:length(t))); end else for j = road1_ch_down:road1_ch_up %刷新第一路的1-5通道显示 set(p(j),'xdata',t(length(t)-plot_length:end),'ydata',m(j,length(t)-plot_length:length(t))); end for j = (5+road2_ch_down):(5+road2_ch_up) %刷新第二路的6-10通道的显示句柄 set(p(j),'xdata',t(length(t)-plot_length:end),'ydata',m(j,length(t)-plot_length:length(t))); end end else data(1) = []; %如果不是帧头,则数据错误??跳过错误数据直到找到帧头 end end if(x <= x_down) ymin1 = min(min(m(1:5,1:end))); %求整个矩阵的最小值 ymax1 = max(max(m(1:5,1:end))); %求整个矩阵的最大值 ymin2 = min(min(m(6:10,1:end))); %求整个矩阵的最小值 ymax2 = max(max(m(6:10,1:end))); %求整个矩阵的最大值 else ymin1 = min(min(m(1:5,x-x_down:end))); %求整个矩阵的最小值 ymax1 = max(max(m(1:5,x-x_down:end))); %求整个矩阵的最大值 ymin2 = min(min(m(6:10,x-x_down:end))); %求整个矩阵的最小值 ymax2 = max(max(m(6:10,x-x_down:end))); %求整个矩阵的最大值 end drawnow %更新图形窗口 set(SUBP(1),'XLim',[x-x_down x+x_up],'YLim',[ymin1-50 ymax1+50]); %set(SUBP(2),'XLim',[x-x_down x+x_up],'YLim',[ymin2-100 ymax2+100]); set(SUBP(2),'XLim',[x-x_down x+x_up],'YLim',[-450 +450]); end
这个是第二版的回调函数,之前发现当m数据量过大时(大概超过3W点左右)图形出现明显的滞后现象,所以增加了一个比较,将整个图形的点数限制在一定范围之内(点数限制变量为plot_length),完美解决,大家可以根据电脑差异更改这个值。