你是正確的,問題是時機。錯誤消息表示串行端口沒有收到儘可能多的字節,因爲它需要用超時前指定的格式創建一個值。對於簡單的例子,你的代碼工作正常,但正如你發現的那樣,它不健壯。
你必須知道兩件事情在你開始之前:
- 請問您的串口設備在「行」發送數據時,使用行 終止符,或不?
- 您每次從串口讀取數據時,您希望讀取多少個字節 ?
然後有兩種做法:
A)程序等待(更方便,更健壯):添加代碼中的聲明,等待已接收的字節一定數量,然後讀取它們。
numBytes = 10; % read this many bytes when ready
% make sure serial object input buffer is large enough
serialport = serial('COM100','InputBufferSize',numbytes*10);
fopen(serialport);
while 1
ba = serialport.BytesAvailable;
if ba > numBytes
mydata = fread(serialport, numBytes);
% do whatever with mydata
end
drawnow;
end
fclose(serialport);
B)對象的回調(更先進/複雜,可能更健壯):定義每當特定條件被滿足時執行的回調函數。回調函數處理來自串行設備的數據。該執行條件可以是:
- a)使用字節的一定數目的已接收
- b)一種線路終端 字符已經被接收
下面的示例使用條件A)。它需要兩個函數,一個用於主程序,另一個用於回調。
function useserialdata
% this function is your main program
numBytes = 10; % read this many bytes when ready
% make sure serial object input buffer is large enough
serialport = serial('COM100','InputBufferSize',numbytes*10);
% assign the callback function to the serial port object
serialport.BytesAvailableFcnMode = 'byte';
serialport.BytesAvailableFcnCount = numBytes;
serialport.BytesAvailableFcn = {@getmydata,numBytes};
serialport.UserData.isnew = 0;
fopen(serialport);
while 1
if serialport.UserData.isnew > 0
newdata=ar.UserData.newdata; % get the data from the serial port
serialport.UserData.isnew=0; % indicate that data has been read
% use newdata for whatever
end
end
fclose(serialport);
function getmydata(obj,event,numBytes)
% this function is called when bytes are ready at the serial port
mydata = fread(obj, numBytes);
% return the data for plotting/processing
if obj.UserData.isnew==0
obj.UserData.isnew=1; % indicate that we have new data
obj.UserData.newdata = mydata;
else
obj.UserData.newdata=[obj.UserData.newdata; mydata];
end
顯然,這些都是玩具的例子,你將有很多其他細節,如超時,錯誤處理,程序響應速度等考慮,根據不同的串行設備是如何工作的細節。有關更多信息,請參閱「串行端口對象屬性」的matlab幫助文件。