[转帖]基于Matlab串口中断通信的温度监测系统

jackxiang 2009-5-8 14:01 | |
摘要:基于某食品加工严格控制温度的需求,提出温度监测系统的总体设计方案,介绍在Matlab环境下串口中断通信的特点,详细描述基于事件驱动的串口中断通信的方法和步骤,最后给出具体的编程方法,并就如何修改回调函数提出几个需要关注的问题。该方法实用可靠,已成功应用。
关键词:温度 Matlab RS-232 回调函数
Temperature Monitoring System Based on Matlab
Serial-interruption Communication
Abstract:According to the requirements of controlling temperature strictly during some foodstuff machining,the paper puts forward the whole design project of the temperature monitoring system,introduces the features of serial-interruption communication under Matlab condition,explains the methods and process of serial-interruption communication based on event-driven in detail, and then provides available programming methods,puts forward several noticeable questions as to how to amend callback function.Successful application shows that this method is practical and credible.
Keywords:temperature Matlab RS-232 callback function
1、引言
某食品在初加工时需要严格控制温度在一定范围内并持续规定时间,温度过低达不到灭菌效果,温度过高食品容易腐烂,为此作者设计一套基于Matlab环境下的温度监测系统。利用AVR单片机将采集到的温度数据传送至计算机的串口中,在Matlab环境下,基于事件驱动的中断通信机制,从计算机的RS-232串口中读取数据,运用Matlab的工程计算和图形处理等优点,对温度数据进行分析处理、文件存储、图形显示等,具备实时监测的功能。
Matlab是由美国Mathworks公司开发的面向工程计算和图形处理的功能强大的软件系统,其Matlab语言以矩阵为基本运算单元。从Matlab6.0版本开始,增加了设备控制箱(instrument control toolbox),正式提供了对RS-232/RS-485通信标准的串口通信的支持;利用该工具箱的serial类及instrcallback()回调函数,能可靠地进行实时串行通信。本文介绍在Matlab环境下,如何运用基于事件驱动的串口中断通信机制,将温度数据读至计算机中,利用Matlab进行数据存储、显示等。
2、系统总体设计简介
假设食品加工时需要N个加热容器,在每个加热容器中放置一个温度传感器,用N个ATMEL公司生产的AVR单片机ATmega48做为温度采集单元对温度数据进行采集,经RS-485总线将数据上传至数据采集板,数据采集板采用AVR单片机ATmega16,完成N个加热容器温度的读取、校验,通过RS-232串口发送至计算机中,利用Matlab的串口中断通信机制接收数据,然后对数据进行分析、存储、绘图和打印等。图1为系统总体设计框图。

图1:系统总体设计框图
数据采集板循环读取各个温度采集单元的数据,每次循环后将各单元数据按一定格式通过串口发送至计算机。数据采集板到计算机的数据格式如下:
起始 温度点数 温度1整数 温度1小数 ? ? ? 温度N整数 温度N小数 校验和
0xff N 0xnn 0xnn ? ? ? 0xnn 0xnn 0xcc
校验和=温度点数(N)+2N个温度数据(取8位)。
计算机利用Matlab的串口中断通信机制接收数据,并且以曲线的形式在计算机上显示,同时对数据进行存储以备打印。
3、Matlab环境下PC计算机与单片机的通信
在Matlab6.0以上版本中新增的设备控制工具条(instrument control toolbox)具备支持计算机与其它具有串口的外部设备之间的通信的功能。其特点如下:
a、支持基于串行接口(RS-232、RS-422、RS-485)的通信;
b、通信数据支持二进制和文本(ASCII)两种方式;
c、支持异步通信和同步通信;
d、支持基于事件驱动的通信(亦称中断方式)。
据此可知,Matlab可以满足串行通信的要求。
3.1 Matlab对串口控制的方法与步骤
Matlab对串口的控制是通过serial()类以及相应的控制函数的方法实现的,主要分为四个步骤:
⑴创建串口设备对象并设置其属性
s=serial('com1'); %创建串口1的设备对象s。
s.InputBufferSize=1024; %输入缓冲区为256B,缺省值为512B。
s.Timeout=2; %设置一次读或写操作的最大完成时间为2s,缺省值为10s。
s.ReadAsyncMode='continuous' (缺省方式); %在异步通信模式方式下,采用连续 (continuous)模式(缺省方式)读取串口数据,而且数据会自动地存入输入缓冲区中。
某些属性只有在对象没有被打开前才能改变其值,如InputBufferSize等。需要注意的是串口设备对象属性的缺省值为波特率9600b/s,异步方式,通信数据格式为8位数据位,无奇偶校验位,1位停止位,如果数据采集板的RS-232工作参数与此相同,则无需修改属性值。另外,用get(s)命令可知道其全部属性,用set(s)命令可知道其基本属性和当前的属性值。
⑵打开串口设备对象
在读写数据采集板的温度数据之前,必须用fopen()命令打开串口设备对象,或者说将计算机与数据采集板通过RS-232连接起来,具体命令格式是:
fopen(s);
打开串口设备对象之前,查看属性s.Status的值为close, 打开以后再查看,其值为open,说明计算机可以读取数据采集板的温度数据。
⑶读取串口数据
串口的读写操作支持二进制和文本(ASCII)两种方式。当Matlab通信数据采用文本(ASCII)方式时,读写串口设备的命令分别是fscanf(以及fgetl, fgets)、fpritf;当Matlab通信数据采用二进制方式时,读写串口设备的命令分别是fread、fwrite。本文以文本方式读取串口数据,故只介绍fscanf的用法,其它命令请参考相应文献。fscanf的命令格式为:
A = fscanf(s,'format',size);
其中,format是c语言的数据转换标准,缺省值为%c。Size是读取数据字节数,如果Size为[m,n]格式,则A是矩阵;如果Size为n格式,则A是数组。
⑷关闭串口设备对象
使用fclose(s)命令关闭串口设备对象。如果不再使用该串口设备对象,为节省系统资源,用delete(s)命令删除内存中的串口设备对象;用clear s命令清除Matlab工作空间中的串口设备对象。
3.2在Matlab环境下实现串行通信的软件设计
在Matlab环境下,读取串口数据的方法可以分为查询和中断两种。以查询的方式进行串行通信时,需要实时查询串口缓冲区,编程容易,但计算机大量时间用于查询,所以很少使用;以中断方式对串口进行控制实现串行通信,可以实时处理传送的数据,但编程相对复杂。
在Matlab环境下以中断方式进行串行通信,实际上是采用事件驱动的方法实现的。Matlab提供了instrcallback(obj,event)回调函数,用户根据需要可以自行设置具体的串口中断触发事件。Matlab有四种常用的串口中断触发事件:缓冲区有指定字节数目的可用数据事件(bytes-available event)、串口接收到的数据长时间处于非激活状态事件(break-interrupt event)、串口引脚状态改变事件(pin-status event)、输出缓冲区为空事件(output empty event)。当串口上有监视的事件发生时,Matlab会自动调用回调函数进行通信事件的处理。因此,事件驱动实质上是一种中断机制,而回调函数实质上相当于一个中断服务子程序。本文选择bytes-available event中断触发事件读取数据采集板传送的温度数据,下面介绍编程方法。
⑴建立主程序,串口设备初始化操作,指定串口中断触发事件和回调函数
创建串口设备对象、连接串口设备对象、初始化操作的代码与前述代码相同,不再赘述。当串口缓冲区中有n字节的数据时,触发中断事件,自动调用instrcallback(obj,event)回调函数。具体设置如下:
s.BytesAvaibleFcnMode='byte'; %中断触发事件为‘bytes-available Event’。
s.BytesAvailableFcnCount=n; %接收缓冲区每收到n个字节时,触发回调函数。
s.BytesAvailableFcn=@instrcallback; %得到回调函数句柄,指定回调函数。
⑵修改instrcallback(obj,event)回调函数,处理串口中断触发事件
Matlab缺省的回调函数instrcallback(obj,event)存在于toolbox\matlab\iofun\@instrument目录
中。它实际上是一个有待于用户修改的程序模块,Mathworks公司只给出一些最基本的程序代码,能够在Matlab的命令窗口(command window)中显示串口触发中断事件的类型,中断事件所发生的日期、时间以及导致事件发生的对象名等信息,如果在相应的语句后加上分号,则取消显示。中断发生后的通信事件处理以及数据的分析处理任务,需要用户自行添加相应的服务程序代码。
编写主程序和回调函数时,需要注意一下几个问题:
a、在对instrcallback.m文件添加代码之前,最好对其做一个备份,且不要修改Mathworks公司给出的基本程序代码,以免出现错误。
b、回调函数instrcallback(obj,event) 尽量只完成数据接收工作,其余的数据分析、显示、存储等工作放在主程序中进行。
c、在数据处理过程中,可以暂时关闭中断,以免下一个中断干扰处理工作。关闭中断采用语句:
s.ReadAsyncMode = 'manual';
数据处理完毕后,采用下列语句打开中断:
s.ReadAsyncMode = 'continuous';
d、主程序和回调函数之间的变量是相互独立的,各自有独立的工作空间。如有需要,可以将主程序的变量带入回调函数中。例如,把主程序中的变量s带入回调函数中,具体做法如下:
在指定回调函数语句中,将@instrcallback与变量s做为单元数组的元素包含在一个单元数组中:
s.BytesAvailableFcn ={ @instrcallback,s};
然后在编写回调函数代码时,将变量s加入到形式变量列表中:
function instrcallback(obj, event,s)
这样就可以在回调函数instrcallback()中使用变量s了。
4、结论
在Matlab环境下,基于事件驱动的中断通信机制,从计算机的RS-232串口中读取数据,编程简单,实现容易,且通信可靠,误码率低。实践证明,采用这种方法是可行的,它不但能够应用于本文的温度监测系统,也可广泛应用在其它具有串口通信能力的仪器设备中。另外,Matlab 还提供了对GPIB总线和VISA总线的通信支持,增加了Matlab的适用性。总之,将Matlab和事件驱动的串口通信结合起来,发挥各自优点,可以解决某些工程技术问题。
参考文献
1 [美]D.Hanselman,B.Littlefield著,张航,黄攀译.精通MATLAB 6.0.清华大学出版社,2002
2 马潮编著.高档8位单片机ATmega128原理与开发应用指南.北京航空航天大学出版社,2004
3 Matlab(R2007a)联机帮助.2007

作者简介:孙公道,男,1964年出生,工程硕士,高级工程师。
参看:
http://www.21eic.com/autocontrol/method2241.html





function serialdwj
%本程序使用的是虚拟串口软件VSPD虚拟的COM2和COM3来测试的
%使用COM1也可以使用 已经经过测试了
%如果要使用 请使用COM1口 就可以与下位机通信了
obj1=instrfind('Type','serial','Port','COM3','Tag','');
%COM2为测试串口
obj2=instrfind('Type','serial','Port','COM2','Tag','');
if isempty(obj1)
    obj1=serial('COM3');
    %新建测试串口
    obj2=serial('COM2');
else
    fclose(obj1);
    obj1=obj1(1);
    %打开串口
    fclose(obj2);
    obj2=obj2(1);
end
set(obj1,'BaudRate',9600,'FlowControl','none','Timeout',0.1)
set(obj1,'Inputbuffersize',512,'Outputbuffersize',512,'parity','none','databits',8,'stopbits',1);
%COM2的属性设置
set(obj2,'BaudRate',9600,'FlowControl','none','Timeout',0.1)
set(obj2,'Inputbuffersize',512,'Outputbuffersize',512,'parity','none','databits',8,'stopbits',1);

fopen(obj1);
%打开串口
fopen(obj2);
k=1;
datas=zeros([1,100]);
while(k<101)
    if obj1.BytesAvailable
        datas(1,k)=fread(obj1,1);
    end
    k=k+1;
    plot(datas);
    %向测试串口中写一个数据数据 在COM3中就可以接受到该数据
    fwrite(obj2,round(255*rand(1)));
    pause(1);
end
fclose(obj1);
delete(obj1);
%删除测试串口
fclose(obj2);
delete(obj2);
end
%现在使用的m文件来显示的
%到后来有机会就使用gui界面来显示

作者:jackxiang@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除
地址:https://jackxiang.com/post/1764/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!


最后编辑: jackxiang 编辑于2009-7-17 11:10
评论列表
发表评论

昵称

网址

电邮

打开HTML 打开UBB 打开表情 隐藏 记住我 [登入] [注册]