有些人帮助编写一个s函数来从串口读取数据

时间:2014-02-22 17:34:50

标签: matlab serial-port simulink s-function

在我遇到问题后here,我需要一些帮助来编写一个带MATLAB功能块的函数。我在以下链接中看到有些人用该块或s函数解决了它: http://www.mathworks.co.uk/matlabcentral/newsreader/view_thread/317910

http://www.physicsforums.com/showthread.php?t=595813

http://www.mathworks.de/matlabcentral/newsreader/view_thread/250266

所以我尝试了这个:

function y = fcn(u)
coder.extrinsic('only3')
coder.extrinsic('serial', 'fopen','fread')
coder.extrinsic('set')

persistent s a 
y = (zeros(2,1));
  s = serial('COM12');

set(s,'Terminator','', 'InputBufferSize', 1024);
a = char('000');        % a-initialization for mxArray problems

a = only3(get(s,'status'));   %to check if port is already opened calling custom function 
if strncmp(a,'clo',3)==true
    fopen(s)
else
    fclose(s)
end

   y = fread(s,[2 1],'uint8'); % I have to read some data from serial. This command works fine in the matlab command window.

only3是我创建的函数。它从字符串中获取前3个字符,我需要它只比较'status'答案的三个字符:

function let = only3(string)

let = string(1:3);

我这样做是为了知道通讯是否已经打开。但是simulink会给我一个错误的窗口:

Call to MATLAB function aborted: Open failed: Port: COM12 is not available. No ports are available.

我认为它会在第一次迭代中打开端口后尝试打开端口。

编辑:我改变了我的代码:

function y = fcn(u)

coder.extrinsic('only3')
coder.extrinsic('strncmp') %like Phil say
coder.extrinsic('serial', 'fopen','fread')
coder.extrinsic('get')
persistent s a b
y = (zeros(2,1));

%%部分取自菲尔的建议:

 if isempty(s)
   % only do this the first time
    s = serial('COM12','Terminator','', 'InputBufferSize', 1024);
    a = '000';
    b = false; %without this returns mxArray error.
end 


a = only3(get(s,'status'));
b = strncmp(a,'clo',3);
if b == true
    fopen(s)
else
    fclose(s)
end


y = fread(s,[2 1],'uint8'); 

它返回错误:

Unsuccessful read: OBJ must be connected to the hardware with FOPEN. Block MATLAB Function (#24) While executing: State During Action 

高亮显示y表达式。

更新编辑: 我用以下代码解决了这个问题:

function y = fcn(u)
coder.extrinsic('only3')
coder.extrinsic('strncmp')
coder.extrinsic('serial', 'fopen','fread')
coder.extrinsic('get')
persistent s a b
y = uint8(zeros(2,1));  %signal is an uint8

 if isempty(s)
   % only do this the first time
    s = serial('COM12','Terminator','', 'InputBufferSize', 1024);
    a = '000';
    b = false;
    a = only3(get(s,'status'));
b = strncmp(a,'clo',3);

    switch double(b)
    case 1
        fopen(s);
    otherwise
        fclose(s);
    end
end

   y = uint8(fread(s,[2 1],'uint8')); 

但是,正如我在下面评论的那样,每次停止模拟时我都必须重新启动Matlab,因为它不会关闭通信。我这样说是因为如果我重新尝试开始模拟,它会返回“我的第一个错误”:

Call to MATLAB function aborted: Open failed: Port: COM12 is not available. No ports are available.

我不知道为什么。在M-code Level-1 S-functions中,每个模拟停止运行fclose(s)都会像mdlTerminate函数那样运行。一些建议?

2 个答案:

答案 0 :(得分:1)

您对持久变量的初始化是错误的。大概你真正想要的是

persistent s a
if isempty(s)
   % only do this the first time
   s = serial('COM12');
   a = '000';
end

答案 1 :(得分:0)

如果您的端口未关闭,您可以使用instrfind命令获取一系列的intruments,然后您可以使用fclose关闭通信。

q=instrfind();

%%select要关闭的索引端口。

fclose(q(x)); where x is the index

如果您需要清除所有乐器,请使用delete(q);

最好的问候。