EDA365电子论坛网

标题: Matlab与单片机的串口通信 [打印本页]

作者: baqiao    时间: 2020-5-6 11:15
标题: Matlab与单片机的串口通信
Matlab提供了对串口进行打开、关闭、以及串口参数设置等操作的一系列函数。利用这些函数可以选择串口号、 设置串口通信参数( 波特率、 数据位、停止位、 校验位等)、进行中断控制、流控制。从建立串口通信到结束串口通信的完整流程包括以下几个步骤:
# d/ O2 `# U9 L; I( X, e' {7 X# k1、创建串口对象,实现该功能的函数为:
1 ^( `2 \  Q# m; ~- E( r8 S       obj=serial(port,'PropertyName',PropertyValue,....);
  [+ ?  M% h4 R. \5 y     例如: obj= serial(com3,'BaudRate'4800)* G  u6 K+ M" z/ n! W, N
    或使用以下默认设置,创建串口对象,在命令串口输入以下代码,第二句是查看其obj默认状态
1 [; |, ~" d' T' _( @3 C       obj = serial('com3');  $ {. @5 A) _" T6 Y; S6 I6 Y# T6 _
       obj7 L: E1 h  _5 T& T, F
    其中有两个重要设置项
7 P& |' n* A6 P- j% [       BaudRate:          9600   % 波特率默认9600
3 Q6 I( e2 g/ P" N, y7 V       Terminator:        'LF'     %串口触发字符“换行符”: P  ~9 t- ]" I4 E/ A" E
2、设置或者修改串口通信参数,实现该功能的函数为:
# `6 j( _! X$ h       set(obj,'PropertyName',PropertyValue,);
, E- u: C+ y8 Q- ]) k9 o& d    例如:set(obj,'BaudRate'4800);
: \' W! K" \0 R0 B    这样,我们就发现串口的一些基本设置,可以在创建串口时设置,也可以创建串口之后再进行设置。
. G! O: Q& d7 \' e) f5 _3、打开串口,实现该功能的函数为:5 I' }, E, C( ]9 ^+ O
       fopen(obj);
7 T1 ^0 Z6 G% W& E  J1 \     obj即为前边创建的串口对象。: s; P$ L$ ]! Q+ f
    其中,步骤2和3顺序是完全可以颠倒的。% @) `9 j& Z- e2 j+ d2 f; z" k
4、从串口读写数据,在前面三个步骤正常完成后, 即可以从串口读数据或者向串口写数据, 也就是接8 {4 n6 @7 ~' O0 l: `
    收或者发送数据。
  j. Y# x8 c) e2 @/ k3 u9 e    这里我介绍几个常用函数,读函数:fread,fscanf;写函数:fwrite,fprintf.8 }+ s1 v* ^' s. b! _% i
       A = fread(obj,size);   %从串口obj读取size字节长短的二进制数据,以数组形式存于A
4 W7 |+ d9 s5 W8 \0 z$ A9 J. V       str = fscanf(obj);      %从串口obj读取字符或字符串(ASCII码)形式数据,以字符数组形式存于str. \5 R) D, R8 V& I7 r! h% u
       fwrite(obj,A);           % 以二进制形式向obj写入数据A' i# Q; f8 p8 z* {
       fprintf( obj,str);        %以字符(ASCII码)形式向串口写数据str(字符或字符串)3 S% j' c( h% Q: ], A; T
5、关闭串口以及释放串口对象占用的存储空间。
7 F& }% ?0 R, ]8 A       fclose(obj);            % 关闭串口* C. C. w3 w- B8 c
       delete(obj);           % 释放串口对象占用的内存空间,
) k! V$ N# o9 q& @+ `. M       clear obj;              % 释放串口对象在Matlab工作区中占用的存储空间
! C) b1 Q; I. d! U4 p# t* j7 _8 v    下一篇讲解着几个函数在实际的应用及不足。$ s! v5 [9 G8 X/ ~4 A/ J9 Y6 k
实例1:在51单片机下载串口代码后,在matlab上执行如下代码:0 K6 }4 u! v& f- o- c. O2 ^
       sr3 = serial('COM3');       % 使用默认设置创建串口sr31 p0 L& n6 G( r1 x
       fopen(sr3);                 %打开串口* |- [4 A  L- M7 X6 }+ c
       fprintf(sr3,'xxx');         % 给串口写入数据! x2 B. @8 X  m8 w  ], w
       str = fscanf(sr3)           %读取串口数据(无分号,可在Matlab工作区实时查看)7 ?  s  ~/ |) n# X1 J8 m8 l% K
       fclose(sr3);                %关闭串口
( S9 ~+ M/ N+ P6 N' `. q       delete(sr3);
, \: f2 `1 w$ v' t2 B       clear sr3;
. I% J: K: k7 F& r9 i4 B) u
, P/ f- D/ k) f1 Q) y5 H4 n串口中断设置及中断处理函数  z; _- l" ]. m" `2 {  F' C- Q
要实现自动收发数据,还需要定义串口中断处理函数以及触发串口中断的方式。定义触发串口中断的方式其目的是为了在串口检测到接收数据的时候,通知并启动串口数据接收函数进行数据接收操作; 在串口输出缓存为空的时候, 通知启动串口数据发送函数。2 r0 _  a5 R) s$ S: ^
1、触发串口中断的方式。1 S3 w+ i2 p& C2 p7 G) S5 H1 U
    Matlab检测到串口通信事件,从而触发串口中断。串口读写的事件包括: Bytes available,Outputempty。其中Bytes available事件有两种: 一种是接收到的字符数达到人工设定的数目时,则系统产生该事件; 另一种是当接收到指定字符时, 系统产生该事件。Output empty事件是在系统检测到输出缓存区为空时, 产生该事件。
1 V9 O6 ~" V$ y3 K" v2、中断方式设置
" O1 U0 L5 D+ v3 }' p+ J- @# W   Bytes available 事件! r: Q: ~# D. q$ e' E( A$ k; y
      set(obj,'BytesAvailableFcnMode','byte');
2 X$ y2 R2 w2 R      set(obj,'BytesAvailableFcnCount', 240);           %串口检测到输入缓存中到达了240个字符数据时,触发串口中断。或 :9 I. u! R" n7 ~$ ]) ]) Q* q
      set(obj,'BytesAvailableFcnMode','terminator');
3 j+ h; m. t. n0 Z7 \- Y      set(obj,'terminator','H');                                 %当串口检测到字符H时,则触发串口中断2 s( ~. B0 ^! \: k: \
   Output empty事件& y4 s8 Q( q* q+ C- ?+ L) j
      输出缓存为空事件的产生。该事件由系统自动检测产生,不需要用户特别设置。该事件一般在输出缓存中的最后一个字符发送完毕后产生。用户可以定义该事件引起的串口中断处理函数。( _! {( K# l" w: p2 A" Q" f' E
3、串口中断处理函数6 L' k/ d' N$ A* S+ ], O5 i7 P8 b
     串口中断处理函数是重点中的重点,我查阅过一些文档,串口通信时接收数据一般分两种方式,一种是查询方式,一种是中断处理方式,了解处理器工作的人知道,使用查询方式需不断查询,耗用内存,效率十分低。所以实际通信过程中都使用中断方式,这就需要设置中断触发方式,中断处理函数。; I) X5 ]4 u- D8 b) L$ P
      很多参考文档都是使用matlab自带回调函数,再添加自己的代码,在最开始我也尝试这种方法,但发现实在太麻烦,还是选择自己写,其实很简单,只要注意几个细节问题,就能得到正常运行的函数。- r8 B3 Y$ n% `( M# D
      串口中断处理函数定义:
8 h0 x2 }$ N& w/ ` obj. BytesAvailableFcn=@ReceiveCallback;
8 w' V4 r2 R9 E6 m8 F# V' _9 F      再自行编写中断处理函数。. }/ Z$ X3 _' w# B* q* d9 t, n
实例2:51单片机端依然使用串口代码,matlab执行如下函数:4 L, O9 r% V4 M% R: O1 i
function SerialFuc()        % 创建函数: E- ?7 X& N! k
  delete(instrfindall)      % 关闭串口,此句十分重要,下篇再详细解释
3 x. @5 R. o0 P, z  global s;                 % 全局变量,供串口中断函数使用
7 |8 H+ F; ~! W( q  s = serial('com3');       %使用默认设置创建串口s
$ N! q1 P; B/ X4 I1 y' D' z  fopen(s);                 %打开串口
% Q& j) |% p3 Z, Y5 p! Q3 k  ?  set(s,'BytesAvailableFcnMode','Terminator'); %设置中断触发方式8 P3 ^8 b7 y. A/ V9 s) X
  set(s,'Terminator','H');+ E* F+ h& M- }! ?
  s.BytesAvailableFcn =@ReceiveCallback;       % 定义中断响应函数对象6 G( `2 @% ?7 G, L9 \! D3 j; O
  for k=1:1:5               % 每两秒发送字符串,循环五次% E! ?) [; U  e5 F3 Q& y
      fprintf(s,'ChunyuY19');; c7 r& X: M1 S( `! \) u
      pause(2);
  Y5 J1 }6 Q" J  h. r  end    " t1 V* N5 L' Q4 M: R
end
# n) T6 ]# c3 o. u& JfunctionReceiveCallback( obj,event)     %创建中断响应函数
" {  H1 s0 `& R' _( d. k# U% H) s! n   global s;
! k- R2 f/ `! l/ v7 n   a = fscanf(s)       % 接收数据并显示(无分号)
, [! c& D2 }: o: u% P% k   I = 'I received'    % 检验是否中断响应函数正常被触发(无分号)8 w8 {4 T) e# x- A5 _2 H
end
4 O5 P+ n. Z. d7 x% T/ k! |% n/ R5 }$ d" z% u3 ~
以上代码均已实测,51单片机代码查看如下链接:51单片机串口通信代码1 C; \  G7 K) ~4 G, j3 O
文章意在实现matlab与单片机之间的基本通信,串口函数简单,容易理解。
! W; K% U% T% T! @* i! ?" B9 u8 m/ b如有错误,诚望留言指正
" l0 }' I3 g- l' C2 N# E9 L. b; A7 p* h) u" J5 i0 h% H) j

作者: yin123    时间: 2020-5-6 14:08
Matlab与单片机的串口通信




欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/) Powered by Discuz! X3.2