现在的位置: 首页 > 综合 > 正文

【原创讲义】matlab之串口通信

2013年09月15日 ⁄ 综合 ⁄ 共 2301字 ⁄ 字号 评论关闭

串口通信,一般是指RS232、RS422之间的通信。matlab中有专门的serial函数来创建串口对象。设串口ID号为COM1,则创建方法为:

复制内容到剪贴板

代码:

>>scom= serial('com1');

创建完串口对象后,一般需要设置串口对象的属性,否则,串口不会相互通信。

复制内容到剪贴板

代码:

>> get(scom)
   ByteOrder = littleEndian
   BytesAvailable = 0
   BytesAvailableFcn = 
   BytesAvailableFcnCount = 48
   BytesAvailableFcnMode = terminator
   BytesToOutput = 0
   ErrorFcn = 
   InputBufferSize = 512
    Name= Serial-COM1
   ObjectVisibility = on
   OutputBufferSize = 512
   OutputEmptyFcn = 
   RecordDetail = compact
   RecordMode = overwrite
   RecordName = record.txt
   RecordStatus = off
   Status = closed
    Tag= 
   Timeout = 10
   TimerFcn = 
   TimerPeriod = 1
   TransferStatus = idle
    Type= serial
   UserData = []
   ValuesReceived = 0
   ValuesSent = 0
   SERIAL specific properties:
    BaudRate= 9600
   BreakInterruptFcn = 
   DataBits = 8
   DataTerminalReady = on
   FlowControl = none
   Parity = none
   PinStatus = [1x1 struct]
   PinStatusFcn = 
    Port= COM1
   ReadAsyncMode = continuous
   RequestToSend = off
   StopBits = 1
   Terminator = LF

这些属性中,要使串口真正通信,一般要设置这几个属性:
BaudRate:波特率;
Parity:奇偶校验类型;
DataBits:数据位,一般为8,不用设置;
StopBits:停止位,一般为1,不用设置;

TimerFcn :定时回调函数;
TimerPeriod:定时周期;

BytesAvailableFcn:字节计数回调函数
BytesAvailableFcnCount:字节计数
BytesAvailableFcnMode:一般设置为字节模式,即byte

串口通信时,数据一般按帧传送,有的数据量比较大,会将帧打包后发送。这里仅讨论下数据按帧发送的情况。
假设,计算机与单片机由串口相连,单片机每50ms会通过串口向计算机发送一帧数据,数据格式如下:
帧数据 = 帧头 + 数据 + 帧计数 + 校验和,共9个字节。
帧头:两字节 0X55、0XAA
数据:5字节 dat1 dat2 dat3 dat4 dat5
帧计数:1字节 0到255,加1循环(相当于给每帧做一个标记,以防丢帧)
校验和:1字节 数据求和,然后对256求余;仅作为校验之用。

假设,串口波特率115200,偶校验,其他属性为默认值。我们可以设置TimerPeriod = 0.05,TimerFcn = {@data_rec, handles}。属性设置语句为:
set(scom, 'Parity', 'even', 'BaudRate', 115200, 'TimerPeriod', 'TimerFcn', {@data_rec, handles})
回调函数可以这么写:
function data_rec(obj, event,handles)
n_bytes = get(obj, 'BytesAvailable');
if n_tytes == 9
    flag =fread(obj, n_bytes, 'uint8');
  %以下进行数据处理
elseif rem(n_tytes, 9)==0
    flags =fread(obj, n_bytes, 'uint8');
  %以下进行数据处理
else
    %若连续四次rem(n_tytes, 9)~=0,将数据全部读出,解算出正确的帧,舍弃错误的帧。
end

这样的思路经实践证明是可以的。如果计算机同时要回传数据给单片机,可以在回调函数中的if语句前或后加上fwrite语句写数据到串口。例如,若每个200ms回传一次数据,则可以在回调函数中设定一个全局变量:

复制内容到剪贴板

代码:

freq_split =uint8(0);

每进一次回调函数,

复制内容到剪贴板

代码:

freq_split =freq_split + 1;
if freq_split >=5
   freq_split = 0;
   %写数据到串口
end

这里提一下,一般写数据到串口时,要设置为异步写,具体语句为:

复制内容到剪贴板

代码:

fwrite(obj,datas, 'uint8','async');

具体工程中,问题要复杂的多,读者遇到问题时还是要自己先仔细琢磨下。
《matlab GUI设计学习手记》中对串口编程进行了较为基础而完整的介绍,关键还在于回调函数的编写。
另外,书中也提到,如果要兼顾系统的稳定性和实时性,可以考虑用定时器来代替串口对象的TimerFcn,因为Timer似乎更强大,因为,Timer的执行模式若为FixedSpacing时,串口回调函数是顺序执行的,一个回调函数未执行完,才开始计时50ms,而不是不管你前一个回调运行完没,就开始计时。

抱歉!评论已关闭.