天天看點

序列槽程式設計

這是序列槽程式設計的第三篇, 也是最後一篇.

為客戶開發一個程式, 是個機加工工廠, 他們有個量測儀器, 能将量測值通過序列槽列印機列印出來, 勞工拿着這個紙條, 再加工中心上輸入量測值. 在機床上輸入東西比較麻煩, 也容易出錯, 需要做些改造, 因為量測裝置的作業系統是一個嵌入式系統, 也沒有源碼, 無法直接修改量測軟體. 我給的方案如下:  

方案:加一個PC機, 抓取序列槽列印機接收的資料, 提起其中的量測值, 然後将量測值以檔案的形式發送到加工中心上.

現場條件不允許安裝.Net Framework, 是以我選擇使用Delphi開發序列槽程式, 通訊用額是Turbo Power的 TApdComPort 元件,該元件功能非常強大. 但我感覺做為類庫, 在程式設計接口上有些地方反人類, 瑕不掩瑜吧.  

=============================

TApdComPort 相關資料

=============================

本文主要參考:

TApdComPort 使用說明, 

最重要的資料是源碼, TApdComPort 的核心代碼在 AdPort.pas 中.

官方的Faq 必須要學習, Reference文檔名副其實, 僅做reference用吧.

http://tpapro.sourceforge.net/Faq.html

http://tpapro.sourceforge.net/docs/APRO_ReferenceGuide.pdf

-----------------------------

基本屬性, 必須在序列槽打開之前設定

-----------------------------

**********

1》ComNumber屬性

  ComNumber:設定或傳回序列槽号,值為 1、2時分别設定coml、com2。ComNumber并不驗證序列槽号的有效性。當打開序列槽時,Windows驅動程式将決定序列槽号是否有效,如果無效,則出錯。  

**********

2》Baud屬性

Baud屬性決定端口使用的波特率。

通常可接受的波特率值包括:300、1200、2400、4800、9600、19200、38400、57600、115200。

當波特率被改變時,如果端口已打開,線路參數立即更新。把Baud屬性傳遞給通信驅動程式之前,Baud不校驗所賦予的值,驅動程式可能拒絕這個值,并将導緻一個異常。異常:ENotSupported.

**********

3》StopBits屬性

決定端口的停止位的個數,可接受的值為1和2。如果DataBits等于5,一個請求2個停止位被解釋為一個請求1.5個停止位。

當改變StopBits屬性時,如果端口已打開,線路參數立即更新。在把StopBit屬性傳遞給通信驅動程式之前,StopBits不校驗所賦予的值, 驅動程式可能拒絕這個值,并将導緻一個異常。異常:EBadArgument、EBadHandle。

**********

4》DataBits屬性

決定端口的資料位的個數。可接受值是:5、6、7、8。

當改變DataBits屬性時,如果端口已打開,線路參數立即更新。把DataBit屬性傳遞給通信驅動程式之前,DataBits不校驗所賦予的值,驅 動程式可能拒絕這個值,并将導緻一個異常。異常:ENotSupported.

**********

5》Parity屬性

決定端口的奇偶校驗模式。

當Parity被改變時,如果端口已打開,線路參數立即更新。把Parity屬性傳遞給通信驅動程式之前,Parity不校驗所賦予的值,驅動程式可能拒 絕這個值,并将導緻一個異常。異常:EBadHandle、ENotSupported.

**********

-----------------------------

其它控制屬性

-----------------------------

1》AutoOpen:決定端口是否按要求自動打開。當然我總是禁掉AutoOpen, 另外PromptForPort也禁掉

**********

2》Open屬性:決定是否打開端口,是否用目前端口的所有屬性初始化該端口。控件發送或接收字元前,Open必須設定為True. 将Open屬性設為True後, 并不表示序列槽就被打開了, 序列槽真正打開後, 會觸發OnOpen事件, 關閉也類似.

**********

3》OutPut屬性:向輸出緩沖區中寫入資料,在設計時無效,運作時隻讀。

**********

4》流控設定, 初始化COM時, 可設定如下流控參數

    ApdComPort.HWFlowOptions

    ApdComPort.SWFlowOptions

    ApdComPort.XOffChar

    ApdComPort.XOnChar

設計時和運作時, 可通過設定DTR屬性為True, 表示高電平, DTR為False, 為低電平; 但如要進行切換高低電平, 中間必須要sleep一下. CTS屬性類似.   

-----------------------------

捕獲底層的log, 這在抓取序列槽資料時非常有用

-----------------------------

TApdComPort能捕獲到一些底層的資訊, 并可将這些資料自動記錄到對應的log檔案中, 需要作的是開啟Logging功能, 與Logging相關的還有Tracing, 但Tracing抓出的資訊不如Logging全, 是以我僅僅使用Logging功能.

--初始化Logging設定

procedure TDataModule1.InitLogSettings(ApdComPort: TApdComPort);

begin

    ApdComPort.LogAllHex:=True;

    ApdComPort.LogName:=ExtractFilePath(Application.ExeName)+'_COM.log' ;

    ApdComPort.Logging:=tlOn ;

end;

--我寫了個FlushLog(), 看看寫法, 就能體會到 ApdComPort 反人類之處了.  

procedure TDataModule1.FlushLog(ApdComPort: TApdComPort);

begin

    ApdComPort.Logging:=tlAppend; //save to file then ture off Logging

    ApdComPort.Logging:=tlOn;     //at last turn on Logging  

end;

另外, 可以使用AddStringToLog(), 将任意字元串寫到Log檔案中, 當然序列槽必須先打開.    

-----------------------------

發送資料

-----------------------------

PutString()和PutChar(),PutBlock()可以發送, 也可以通過設定OutPut屬性來寫.

-----------------------------

接收資料, 都是以事件的方式接收資料

-----------------------------

1. OnTriggerAvail事件介紹, 我認為這個方法最好用了.

一旦有資料接收到, 就會觸發OnTriggerAvail事件, 代碼一般為,

procedure TForm_Main.ApdComPort_1BTriggerAvail(CP: TObject; Count: Word);

var

   I : Word;

begin

     for I := 1 to Count do

         globalString := globalString + ApdComPort_1B.GetChar;

end;

2.OnTriggerData事件, 有時候需要判斷是否接收到指定的資料, DataTrigger提供了一個簡單的方式

增加 DataTrigger 後, 當TApdComPort接受到指定的字元串後, 即觸發OnTriggerData事件, 我們可以在這個事件中針對不同的dataTriggerHandle做不同的處理.

//建立dataTrigger 的handle(WORD類)

connectDataHandle=ApdComPort_1B.AddDataTrigger('connect server', true)

disconnectDataHandle=ApdComPort_1B.AddDataTrigger('disconnect server', true)

//在OnTriggerData事件, 判斷 TriggerHandle, 是等于 connectDataHandle還是 disconnectDataHandle, 做相應的處理

procedure TForm_Main.ApdComPort_1BTriggerData(CP: TObject;

  TriggerHandle: Word);

begin

  //比較TriggerHandle和connectDataHandle/disconnectDataHandle值, 做進一步處理

end;

3. DataTrigger是一個簡單的data match trigger, 要實作更複雜的比對條件, 可以使用TApdDataPacket元件, 它可以設定起始字元串, 結束字元串等比對條件, 一旦接受到滿足條件的資料, 會觸發OnPacket事件

-----------------------------

為 TApdComPort 增加 TimerTrigger

-----------------------------

增加 TimerTrigger, 需要兩步, 第一步先擷取handle, 第2步設定timer的interval

//建立timerTrigger 的handle

timerHandle:= ApdComPort_1B.AddTimerTrigger;

ApdComPort_1B.SetTimerTrigger(timerHandle, 100, True); //interval為100,并啟用這個trigger

4. 删除方法RemoveTrigger(), 參數是triggerHandle.

-----------------------------

ApdComport, ApdSLController, ApdStatuslight配合使用

-----------------------------

ApdSLController是Statuslight的管理器, 可以為8個不同的信号事件配置各自的statuslight(顯示紅綠燈). 在将ApdSLController和指定的ApdComport元件綁定, 就可以通過這8個 statuslight來反映ApdComport的狀态.

上一篇: 序列槽開發
下一篇: 序列槽助手

繼續閱讀