摘 要 本文介绍MATLAB环境下上位机与下位机通过RS232接口进行串行通信的实现方法;详细叙述了在MATLAB环境下使用其自带的控制工具箱中的串口事件回调函数,实时接收下位机输出串行信号的实现过程。
关键词 MATLAB7.0,串口通信,回调函数
MATLAB是由美国Mathworks公司开发的面向理论分析研究和工程设计处理的一套具有强大功能的软件系统。在设计研究单位和工业部门,MATLAB被认作进行高效研究、开发的首选软件工具。其编程语法规则与一般的结构化编程语言大同小异,而且使用更方便,具有一般编程基础的用户都可以很快熟练掌握。MATLAB内置大量的数学算法函数,只要几个语句就能实现诸如矩阵/行列式运算、FIR/IIR滤波等数据分析处理、复杂的图形显示等。在实际应用中常常要通过各种方式将数据传入计算机,进而借助MATLAB的强大分析处理能力对数据进行分析、处理和图形显示。
本文提出在上位机MATLAB 7.0环境下,使用RS232串行接口实时接收。该方法较之使用VC/VB高级语言编程,极大地缩减了开发时间,提高了开发效率。
一、总体框图
本设计的总体原理框图可见图1, 系统主要由上位机(PC机)和下位机(PC104)部分。上位机和下位机通过RS232进行通讯。上位机负责数据处理和图形化显示,它是在MATLAB7.0环境下进行的,应用了仪器控制工具箱中关于串行通信的函数,通过程序控制整个系统的工作并进行数据处理。下位机负责数据采集和响应主机的控制处理信号。
二、通信原理
在Matlab7.0中的设备控制工具条(instrument control toolbox)用来负责上、下位机之间的通信。该设备控制工具箱的特色如下:Instrument Control Toolbox包括两大部件:M文件函数和接口驱动适配器。这两部件提供了Matlab与外设的通讯功能如图1所示。
图1 串行通讯端口的通讯原理
由图1可见,Matlab的两大部件提供了一条外设与Matlab之间的交互通道,使用户与外设之间进行信息获取和传送。同许多高级语言一样,Matlab 通过调用M文件函数来创建设备对象,得到设备的文件句柄,而设备驱动程序作为操作系统中直接控制硬件的模块,是链接操作系统内核与系统外部设备I/O操作的关键模块。它将具体的硬件细节隐藏实现对外设操作的透明,因此Matlab可以象操作文件一样实现对外设的读、写操作。同时Matlab支持二进制和文本(ASCII)两种串行通信方式,文本方式支持SCPI(Standard Commands for Programmable Instruments)语言;支持异步通信和同步通信;支持查询和基于事件驱动的两种串行通信方式。
三、Matlab串行通信
在Matlab环境下,读取串口数据的方式可以分为两种:查询法和事件驱动法。以查询的方式进行串行通信时,如下位有大量的数据分时分批传送给PC机,上位机就需要不停查询串行口的缓冲区,有数据就读取;虽然编程容易,但这样无法实现对数据进行实时处理和图形显示,系统实时性不高,而且会极大地占用系统的资源和出现丢帧现象。以事件驱动的方式对串口进行控制实现串行通信,就可以实时处理下位机传送的数据;但编程相对复杂一些,需要采用Matlab的事件和回调函数机制。
1.查询法
MATLAB使用查询法对进行串行通讯的程序如下:
g =serial('com1'); %创建串口对象
g.baudrate=115200; %设置波特率,缺省9600bit/s
g.parity='none'; %设置校验位无奇偶校验
g.stopbits=1; %设置停止位
g.inputbuffersize=256; %设置输入缓冲区为256b,缺省值为512b
g.Terminator='LF'; %设置输入缓冲区为256b,缺省值
recbuf=zeros(1,40); %清接收缓冲区(40)
framelen=23; %帧长度(每帧23byte)
framenum=0; %清接收帧数
rectr=0; %接收计数器清零
xctr=0; %输入接收的数据帧数
recnum= input('请输入要接收的数据帧数:\n');
%打开串口设备
fopen(g); %打开串口设备对象g
fwrite(g,255) ; %以二进制的方式发送握手信号0xFF
%进入接收循环
while framenum<recnum
recdta=fread(g,1,'uint8'); %以二进制的方式读入数据
if recdta==255 %找帧头
rectr=rectr+1; %接收计数器加1
recbuf(rectr)=recdta; %送入接收缓冲区
elseif recdta==framelen&rcbuf(1)==255 %验证接收长度和帧头
framelen=recdta; %取帧长度
rectr=rectr+1; %接收计数器加1
recbuf(rectr)=recdta; %送入接收缓冲区
elseif rectr>1&rectr<framelen %接收数据
rectr=rectr+1; %接收计数器加1
recbuf(rectr)=recdta; %送入接收缓冲区
if rectr==framelen %如果接收完进行处理
rectr=0; %清接收计数器
framenum=framenum+1; %帧数累加
%根据具体通讯协议提取数据
…
%接收滤波后的数据
….
plot(…) %输出显示
end
else rectr=0; %未找到帧头清计数器
end %接收结束
end %主循环结束
%程序结束关闭串口类
fclose(g); %关闭串口
delete(g); %删除串口对象
clear g ; %清除变量
注意:串口的读写操作有文本方式和二进制方式两种。在文本方式下,串口设备只接收可以显示的ASCII字符,将0x00H~0x1FH范围内的字符解释为控制字符。使用文本方式对串口的读写函数分别为fprintf()(写)、fscanf()(读)。
2.事件驱动法
在Matlab环境下以事件驱动的方式进行串行通信,类似于VC中的MSCOMM控件中ONCOMM事件的实现方法。Matlab7.0提供了instrcallback(obj,event)回调函数,用户根据需要可以自行设置具体的串行通信事件。Matlab常用的串行口通信中断事件有:缓冲区有指定字节数目的数据可用事件(bytes-available event)、串口接收到的数据长时间处于非激活状态事件(break-interrupt event)、串行口引脚状态改变事件(pin-status event)、输出缓冲区为空事件(output empty event)等。当串口上有监视的事件发生时,Matlab会自动调用回调函数进行通信事件的处理。因此,事件驱动实质上是一种中断机制,而回调函数实质上相当于一个中断服务子程序。Matlab端实时串行通信的程序流程如图4所示,以下是具体的编程步骤。
(1)主程序
g =serial('com1'); %创建串口对象
g.baudrate=115200; %设置波特率,缺省9600bit/s
g.parity='none'; %设置校验位无奇偶校验
g.stopbits=1; %设置停止位
g.BytesAvaibleFcnMode='byte';% 设置中断触发事件为‘bytes-available Event’
g.BytesAvailableFcnCount=30; % 设置接收缓冲区每收到30个字节时,触发回调函数
g.BytesAvailableFcn=@instrcallback;得到回调函数句柄
fopen(g);%连接串口设备对象
fwrite(g,255);%写串口,发送握手信号0xFF(等价于十进制下的数值255)
(2)中断调用程序
Matlab缺省的回调函数instrcallback(obj,event)存在于instrcallback.m文件中。该文件类似于VC中的ONCOMM事件函数模块。需用户自行添加相应的中断处理程序代码。
Matlab安装目标盘下有两个instrcallback.m文件,我们只需要修改Matlab7\toolbox\matlab\iofun\@instrument目录下的instrcallback.m文件即可。注意,在修改instrcallback.m文件之前,最好对进行备份。另外,需要注意的是:程序调试过程中如果再次修改了该回调函数,要重新启动Matlab,才能使得新的回调函数文件生效。
%修改后的instrcallback.m文件如下:
function instrcallback(obj, event)
%以下是用户自行添加的通信事件处理及通信数据处理的中断服务程序代码
%定义存储串口30个字节通信数据的数组
Inbuffer1=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
inbuffer2=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
%以下程序用以对串口通信事件处理
out= fread (obj, 30, 'uint8') %接下位机发送的30个数据(每个数据占一个字节)
%以下程序用以数据进行滤波
inbuffer2=filter(…., Inbuffer1);
%以下程序用以对滤波后数据进行文件存储
fid = fopen('C:\MATLAB7\work\data.txt','a+'); %创建并data.txt文件
fprintf(fid,'%3d',inbuffer2); %将滤波后数据存储到fid文件设备中
fclose(fid); %关闭fid文件设备
%数据计算
…
% 进行实时图形输出显示
plot(…);
end
实验证明,基于Matlab事件驱动方式的实时串行通信稳定可靠,处理数据方便,编程简单,开发效率大大提高。
四、结论
本文介绍的基于Matlab环境下PC机与PIC单片机串行通信的实现方法,利用Matlab的Instrument Control Tollbox的serial类及instrcallback()回调函数,实现基于事件驱动的实时通信。使开发人员使用Matlab工具箱中的现有函数,方便地实现串行通信,充分的利用Matlab中独有数据分析处理和图形显示函数,大大简化系统上位机软件的编程工作量,使系统开发人员可以专注于系统的算法实现和优化。
|