我在做一个串口通讯的程序,发现读串口的时候特慢,有些时候居然卡在读串口函数那里,程序不往下走了,请教一下到底是怎么回事:function ReadCommFunction(ReadBuf: Pointer; Length: Cardinal): integer;
var
iLength: Cardinal;
begin
if (hCommHandle = INVALID_HANDLE_VALUE) then begin
Result := -1;
Exit;
end; if not ReadFile(hCommHandle, Buffer, Length, iLength, @OverOper) then begin
if CheckOverlappedResult() < 0 then begin
Result := -2;
Exit;
end;
end; if (Length <> iLength) then begin
Result := -3;
Exit;
end; Move(Buffer, ReadBuf^, iLength);
Result := 0;
end;这是读串口函数,我发现是卡在ReadFile上面,请问一下这是怎么回事?
var
iLength: Cardinal;
begin
if (hCommHandle = INVALID_HANDLE_VALUE) then begin
Result := -1;
Exit;
end; if not ReadFile(hCommHandle, Buffer, Length, iLength, @OverOper) then begin
if CheckOverlappedResult() < 0 then begin
Result := -2;
Exit;
end;
end; if (Length <> iLength) then begin
Result := -3;
Exit;
end; Move(Buffer, ReadBuf^, iLength);
Result := 0;
end;这是读串口函数,我发现是卡在ReadFile上面,请问一下这是怎么回事?
在ONCOMM事件里处理就可以了
注意第3个参数iLength的取值,这个值是接收到多少个数据的时候才返回,一般来说最好这个值等于串口中已接收的字节数, 该字节数可以用clearcomerror函数得到.
另外申请串口的时候有一个SetCommTimeOut函数设置, 可设置接收到每两个字符间隔多少时间以外就返回.尽量设小.你要直接用API操作串口,最好设置一个缓冲多次ReadFile读取串口数据,然后得到完整的一帧后再做处理.因为直接操作则一次ReadFile通常不能拿完一帧(字符间隔设小),而SetCommTimeOut中字符间隔参数设置过大则不容易退出ReadFile.
var
Temp : String;
inbuff : array[0..2047] of Char;
nBytesRead, dwError : DWORD;
cs : TCOMSTAT;
begin
ClearCommError(hComm, dwError, @cs);
//若未接收到数据或者接收的数据大于缓冲区大小责推出
if cs.cbInQue = 0 then Exit;
if cs.cbInQue > sizeof(inbuff) then
begin
PurgeComm(hComm, PURGE_RXCLEAR);
Exit;
end; ReadFile(hComm, inbuff, cs.cbInQue, nBytesRead, nil);
Temp := Copy(inbuff, 1, cs.cbInQue);
mReceive.Text := mReceive.Text + Temp;
//将memo组件的显示位置移到最下端
mReceive.SetFocus;
mReceive.SelStart := Length(mReceive.Text);
mReceive.SelLength := 0;end;
ClearCommError(hComm, dwError, @cs);
读的时候先调用ClearCommError获取输入缓冲区字符数,没收到数据就不要读了。或者写个线程专门读写数据
1、先开串口
2、下发报文
3、Sleep(2000);
4、读数据,判是否是需要的数据,不是就再下发请求报文(这个是规约规定发三次)
5、不管正确与否都在界面的listview显示相关数据和通讯情况
6、轮循完关闭串口我现在不会在ReadFile那里卡住了,但是发现偶而有几次会没收到报文,我想很可能是我的程序有问题,我也考虑过用线程,但是线程感觉跟我的流程好象合不在一起,当然这是我对串口通讯不熟悉也有关系,所以我还是想看看有什么好的办法,可以让我能正确的每次都收到报文.
打开串口用时30ms,关闭串口500ms.这个在执行的时候会卡那么一下才会返回.
另外你调试的时候用串口助手监控过没,先确定是没有数据上传还是上传了不接收.
从下发完成到接收完数据是需要一定时间的,视乎你设备的执行方式.
如果下发接收到就马上准备上传的话,下发完成到有数据接收是2ms左右,下发完成到数据接收完成一般在10ms内.整个过程+处理大概在15ms(119200波特率50个字符).
所以我建议你用多次读取串口的方式完成一条数据的读取.如果上传数据没问题,请检测你的接收缓冲区是否每次都能将接收到的数据存入.