MATLAB串行通信的实现方法摘要本文介绍MATLAB环境下上位机与下位机通过RS232接口进行串行通信的实现方法;详细叙述了在MATLAB环境下使用其自带的控制工具箱中的串口事件回调函数,实时接收下位机输出串行信号的实现过程。关键词MATLAB7.0,串口通信,回调函数MATLAB是由美国MATHWORKS公司开发的面向理论分析研究和工程设计处理的一套具有强大功能的软件系统。在设计研究单位和工业部门,MATLAB被认作进行高效研究、开发的首选软件工具。其编程语法规则与一般的结构化编程语言大同小异,而且使用更方便,具有一般编程基础的用户都可以很快熟练掌握。MATLAB内置大量的数学算法函数,只要几个语句就能实现诸如矩阵/行列式运算、FIR/IIR滤波等数据分析处理、复杂的图形显示等。在实际应用中常常要通过各种方式将数据传入计算机,进而借助MATLAB的强大分析处理能力对数据进行分析、处理和图形显示。本文提出在上位机MATLAB7.0环境下,使用RS232串行接口实时接收。该方法较之使用VC/VB高级语言编程,极大地缩减了开发时间,提高了开发效率。一、总体框图本设计的总体原理框图可见图1,系统主要由上位机(PC机)和下位机(PC104)部分。上位机和下位机通过RS232进行通讯。上位机负责数据处理和图形化显示,它是在MATLAB7.0环境下进行的,应用了仪器控制工具箱中关于串行通信的函数,通过程序控制整个系统的工作并进行数据处理。下位机负责数据采集和响应主机的控制处理信号。二、通信原理在MATLAB7.0中的设备控制工具条(INSTRUMENTCONTROLTOOLBOX)用来负责上、下位机之间的通信。该设备控制工具箱的特色如下:INSTRUMENTCONTROLTOOLBOX包括两大部件:M文件函数和接口驱动适配器。这两部件提供了MATLAB与外设的通讯功能如图1所示。图1串行通讯端口的通讯原理由图1可见,MATLAB的两大部件提供了一条外设与MATLAB之间的交互通道,使用户与外设之间进行信息获取和传送。同许多高级语言一样,MATLAB通过调用M文件函数来创建设备对象,得到设备的文件句柄,而设备驱动程序作为操作系统中直接控制硬件的模块,是链接操作系统内核与系统外部设备I/O操作的关键模块。它将具体的硬件细节隐藏实现对外设操作的透明,因此MATLAB可以象操作文件一样实现对外设的读、写操作。同时MATLAB支持二进制和文本(ASCII)两种串行通信方式,文本方式支持SCPI(STANDARDCOMMANDSFORPROGRAMMABLEINSTRUMENTS)语言;支持异步通信和同步通信;支持查询和基于事件驱动的两种串行通信方式。三、MATLAB串行通信在MATLAB环境下,读取串口数据的方式可以分为两种:查询法和事件驱动法。以查询的方式进行串行通信时,如下位有大量的数据分时分批传送给PC机,上位机就需要不停查询串行口的缓冲区,有数据就读取;虽然编程容易,但这样无法实现对数据进行实时处理和图形显示,系统实时性不高,而且会极大地占用系统的资源和出现丢帧现象。以事件驱动的方式对串口进行控制实现串行通信,就可以实时处理下位机传送的数据;但编程相对复杂一些,需要采用MATLAB的事件和回调函数机制。1.查询法MATLAB使用查询法对进行串行通讯的程序如下:g=serial('com1');%创建串口对象g.baudrate=115200;%设置波特率,缺省9600bit/sg.parity='none';%设置校验位无奇偶校验g.stopbits=1;%设置停止位g.inputbuffersize=256;%设置输入缓冲区为256b,缺省值为512bg.Terminator='LF';%设置输入缓冲区为256b,缺省值recbuf=zeros(1,40);%清接收缓冲区(40)framelen=23;%帧长度(每帧23byte)framenum=0;%清接收帧数rectr=0;%接收计数器清零xctr=0;%输入接收的数据帧数recnum=input('请输入要接收的数据帧数:\n');%打开串口设备fopen(g);%打开串口设备对象gfwrite(g,255);%以二进制的方式发送握手信号0xFF%进入接收循环whileframenumrecnumrecdta=fread(g,1,'uint8');%以二进制的方式读入数据ifrecdta==255%找帧头rectr=rectr+1;%接收计数器加1recbuf(rectr)=recdta;%送入接收缓冲区elseifrecdta==framelen&rcbuf(1)==255%验证接收长度和帧头framelen=recdta;%取帧长度rectr=rectr+1;%接收计数器加1recbuf(rectr)=recdta;%送入接收缓冲区elseifrectr1&rectrframelen%接收数据rectr=rectr+1;%接收计数器加1recbuf(rectr)=recdta;%送入接收缓冲区ifrectr==framelen%如果接收完进行处理rectr=0;%清接收计数器framenum=framenum+1;%帧数累加%根据具体通讯协议提取数据…%接收滤波后的数据….plot(…)%输出显示endelserectr=0;%未找到帧头清计数器end%接收结束end%主循环结束%程序结束关闭串口类fclose(g);%关闭串口delete(g);%删除串口对象clearg;%清除变量注意:串口的读写操作有文本方式和二进制方式两种。在文本方式下,串口设备只接收可以显示的ASCII字符,将0X00H~0X1FH范围内的字符解释为控制字符。使用文本方式对串口的读写函数分别为FPRINTF()(写)、FSCANF()(读)。2.事件驱动法在MATLAB环境下以事件驱动的方式进行串行通信,类似于VC中的MSCOMM控件中ONCOMM事件的实现方法。MATLAB7.0提供了INSTRCALLBACK(OBJ,EVENT)回调函数,用户根据需要可以自行设置具体的串行通信事件。MATLAB常用的串行口通信中断事件有:缓冲区有指定字节数目的数据可用事件(BYTES-AVAILABLEEVENT)、串口接收到的数据长时间处于非激活状态事件(BREAK-INTERRUPTEVENT)、串行口引脚状态改变事件(PIN-STATUSEVENT)、输出缓冲区为空事件(OUTPUTEMPTYEVENT)等。当串口上有监视的事件发生时,MATLAB会自动调用回调函数进行通信事件的处理。因此,事件驱动实质上是一种中断机制,而回调函数实质上相当于一个中断服务子程序。MATLAB端实时串行通信的程序流程如图4所示,以下是具体的编程步骤。(1)主程序g=serial('com1');%创建串口对象g.baudrate=115200;%设置波特率,缺省9600bit/sg.parity='none';%设置校验位无奇偶校验g.stopbits=1;%设置停止位g.BytesAvaibleFcnMode='byte';%设置中断触发事件为‘bytes-availableEvent’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文件如下:functioninstrcallback(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的INSTRUMENTCONTROLTOLLBOX的SERIAL类及INSTRCALLBACK()回调函数,实现基于事件驱动的实时通信。使开发人员使用MATLAB工具箱中的现有函数,方便地实现串行通信,充分的利用MATLAB中独有数据分析处理和图形显示函数,大大简化系统上位机软件的编程工作量,使系统开发人员可以专注于系统的算法实现和优化。%主要用到的命令及函数%所有注释文字均为原创,用词并非一定准确,仅供参考%没有写GUI的程序,若用VC或.NET写串口通讯的界面程序,需要考虑到多线程任务的处理,比较复杂,因为MATLAB有中断响应事件instrcallback,大大简化了程序的编写;%设置串口号,字符串形式strSerialPortNum=input('串口号(数字):');strSerialPortName=['COM',num2str(strSerialPortNum)];%设置串口参数%设置串口对象s=serial(strSerialPortName);%设置串口波特率(38400),校验位(偶校验)%其他参数可查看MATLAB帮助文档set(s,'BaudRate',38400,'parity','even');%设置中断反馈函数set(s,'BytesAvailableFcn',{'instrcallback'});%注意函数“instrcallback”的位置,比如我的是D:\ProgramFiles\MATLAB\R2011b\toolbox\shared\instrument\@instrument\instrcallback.m,经验证,把instrcallback.m复制到主程序目录下并不产生作用,应该是只能修改安装目录下%toolbox\shared\instrument\@instrument\instrcallback.m的文件中的程序才有用。%设置中断响应(有10个可用字节时,产生中断)set(s,'BytesAvailableFcnCount',10);%设置中断响应模式(有“byte”和“Terminator