剛接觸Delph,i是這樣的,我有1個按鈕,要求在3S內讀一直取串口資料,每隔1S取1次。直達3S內的資料符合要求或者時間到達3S,再進行下一步動作。現在就在3S內檢查串口資料這一步卡住。之前一直是搞單片機的,所以是單片機那種寫法。請各位大俠幫忙指點啊!
while(3S時間沒有到)
{
檢查串口資料
}
進行下一步 后來發現這種寫法不行,定時器都不能觸發了
Delay(1000);
Delay(1000);
Delay(1000);
檢查串口資料 這種寫法也不行,串口時間都不回應了。
uj5u.com熱心網友回復:
Delay(1000);Delay(1000);
Delay(1000);
檢查串口資料 這種寫法也不行,串口事件都不回應了。
uj5u.com熱心網友回復:
開個執行緒試 試 ?uj5u.com熱心網友回復:
你可能對于事件沒什么概念。直接放個TTimer組件,回應OnTimer事件就可以了。
uj5u.com熱心網友回復:
用定時器,或者執行緒都可以操作uj5u.com熱心網友回復:
你的想法錯了,不能用定時器。否則你的程式會出問題。使用Win32寫的動態庫來讀取資料,然后使用delphi呼叫這個動態庫就可以了。
因為串口有資料的時候會產生中斷,自動觸發執行緒去讀資料。
要是公司行為,你給我協議。我寫動態庫給你!
uj5u.com熱心網友回復:
我建議如下:1,delphi中串口資料的接收用控制元件(如spcomm)中的觸發事件來接收,不要主動查詢串口;在單片機中也很少用查詢方式訪問串口資料;
2,在這個觸發事件中設定一下標志位,當接收到資料的時候,標志位置1表示收到資料
3,放置定時器,時間為1s觸發,申請一個全域變數,用以計算定時器觸發的次數;
4,觸發中的程式內容是檢測是否有資料收到,如果有資料收到,判斷資料是否滿足要求;如果滿足要求,轉入你的其他操作,同時定時器停止,計數器清零,否則定時器計數器加1;
5,當定時器計數器達到3時,如果你的資料還不能滿足要求,轉入你的故障操作,然后定時器停止,計數器清零;
6,按鈕代碼中,先清零計數器,再清零串口資料接收標志位,然后開啟定時器;
7,其實自己補充一下除錯細節
uj5u.com熱心網友回復:
98年寫的接收串口資料的處理執行緒,你可以參考一下。最好是用執行緒處理,在執行緒中 使用 WaitCommEvent 監控埠狀態,并且進行資料讀取和快取。
hCom 是用CreateFile創建的埠句柄。
這個執行緒當時是掛在 ComDrv下面的,打開埠之后開始準備接收資料之后,就把這個執行緒跑起來。
你可以打開埠之后,跑起來這個執行緒,然后在主行程中等待3秒,到時間候檢查緩沖區中的資料是否符合你的要求。
// TWaitComm
constructor TWaitComm.Create( hCom:THandle;dcb:TDCB;po:POVERLAPPED;Buf:PChar;pBufState:TPPortBufState );
begin
FhCom := hCom;
FDcb := dcb;
Fpo := po;
FState := tsRun;
Priority := tpLowest;
FPortBuf := Buf;
FpPortBufState := pBufState;
inherited Create(False);
end;
procedure TWaitComm.SetState( const State:TThreadState );
begin
FState := State;
end;
procedure TWaitComm.ProcRun;
var
dwNOBR,dwErrorFlags:DWORD;
ComStat:TCOMSTAT;
iBufFreeSize:integer;
begin
if (WaitCommEvent(FhCom, FdwEvtMask, Fpo)) then
begin
if ((FdwEvtMask and EV_RXCHAR)=EV_RXCHAR) then
begin
//等待緩沖區空閑
while FpPortBufState^.NowOprt<>opIdle do Sleep(5);
//設定緩沖區為寫狀態
//取緩沖區剩余空間大小
FpPortBufState^.NowOprt := opInWrite;
iBufFreeSize := PORT_BUFFER_SIZE - FpPortBufState^.Tail;
//讀埠資料到緩沖區
// only try to read number of bytes in queue
ClearCommError( FhCom, dwErrorFlags, @ComStat ) ;
if (iBufFreeSize>ComStat.cbInQue) then
dwNOBR := ComStat.cbInQue
else
dwNOBR := iBufFreeSize;
ReadFile(FhCom,FPortBuf[FpPortBufState^.Tail],dwNOBR,dwNOBR,Fpo);
FpPortBufState^.Tail := FpPortBufState^.Tail + dwNOBR;
//恢復緩沖區為空閑
FpPortBufState^.NowOprt := opIdle;
end;
end;
end;
procedure TWaitComm.Execute;
begin
{ Place thread code here }
while True do
begin
case FState of
tsRun:
begin
ProcRun;
end;
tsPause:
begin
Sleep(10);
end;
tsEnd:
begin
Exit;
end;
end; // end case
end; // end while
end;
//=========================TWaitComm
uj5u.com熱心網友回復:
樓主好像沒有用COM口控制元件,XE建議使用CPORT,D6、D7可以使用SPCOM,使用埠觸發,一般不要用定時器轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/47733.html
