2016-03-14 40 views
1

如何在delphi中發送多個十六進制代碼?例如, ,我需要發送到串行端口的十六進制碼是1B和40.如何將它發送到串行端口?我可以將十六進制代碼發送到串行端口,但只有一個十六進制代碼(如1B),我無法發送多個十六進制代碼。提前致謝。在delphi中發送多個十六進制代碼

我的代碼:

unit uSample; 

interface 

uses 
    System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, 
    FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, 
    FMX.Controls.Presentation, FMX.ScrollBox, FMX.Memo, Winsoft.Android.ComPort, 
    FMX.Edit, FMX.StdCtrls; 

type 
    TForm1 = class(TForm) 
    AComPort1: TAComPort; 
    Memo1: TMemo; 
    Timer1: TTimer; 
    Button1: TButton; 
    Edit1: TEdit; 
    Open: TButton; 
    procedure Timer1Timer(Sender: TObject); 
    procedure Button1Click(Sender: TObject); 
    procedure OpenClick(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.fmx} 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    AComPort1.Active := False; 
    AComPort1.DeviceName := Edit1.Text; 
    AComPort1.Active := True; 

    AComPort1.WriteUtf8(Memo1.Text); 
    AComPort1.WriteByte(Byte($0A)); 
end; 

procedure TForm1.OpenClick(Sender: TObject); 
begin 

end; 

procedure TForm1.Timer1Timer(Sender: TObject); 
var Text: string; 
begin 

end; 

end. 
+0

您必須先清楚地瞭解問題,才能說明問題。你正在發送十六進制?這是文字。以16爲底的值的表示。或者您是否發送二進制字節?你明白'16 = 10美元'嗎?那麼,你是發送文本還是二進制文件?如何?你的代碼在哪裏? –

+1

所以你不是試圖發送十六進制,你試圖發送二進制。如果你可以發送一個字節,你不能發送多個。很難看到你的問題是什麼。 –

+0

我試過用$ 1B + $ 40和$ 1B $ 40發送它,但如果它只是一個像$ 0A這樣的代碼,它就可以工作。順便說一句,謝謝你的答案。 – dembers

回答

6

根據該意見,該組件包含以下簽名的方法:

procedure Write(Buffer: Pointer; Count: Integer; WaitForCompletion: Boolean); 

這大概是低級別的方法,使所有其他的寫入方法通過。你可能與接受字節數組的高級方法包裝這件事:

procedure TForm1.WriteBytes(const Buffer: array of Byte); 
begin 
    if Length(Buffer) > 0 then begin 
    AComPort1.Write(@Buffer[0], Length(Buffer), True); 
    end; 
end; 

我假設你會通過True的最後一個參數,並撥打電話同步。

然後,您可以這樣調用方法:

WriteBytes([$1B, $40]); 

如果你是舒服類幫手,您可以添加這樣的方法,一類幫手TComport

請注意,在真正的十六進制問題上存在一些混淆。您不會嘗試將十六進制發送到設備。十六進制是表示的值。這些值也可以用十進制表示。所以上面的代碼就相當於:

WriteBytes([27, 64]); 

十六進制只是衆多方法來寫下第一。基礎值是相同的。那麼,16 = $0A。您可以將值作爲十進制,十六進制或其他表示形式寫入。您不發送十六進制,您正在發送字節。通俗地說,你正在發送二進制數據。

+0

謝謝。我確實理解你在發送二進制而不是十六進制代碼時所說的話。 – dembers

1

如果您想將字符串1B40解釋爲兩個字節$1B$40,然後將其發送到COM端口。首先,你需要「1B40`成單獨的十六進制的文本,如‘分割字符串1B’和‘40’,例如(代碼從this question

procedure StrToStringList(const aSource: String; 
         const aList: TStrings; 
         const aFixedLen: Integer); 
var 
    idx: Integer; 
    srcLen: Integer; 
begin 
    aList.Capacity := (Length(aSource) div aFixedLen) + 1; 

    idx := 1; 
    srcLen := Length(aSource); 

    while idx <= srcLen do 
    begin 
    aList.Add(Copy(aSource, idx, aFixedLen)); 
    Inc(idx, aFixedLen); 
    end; 
end; 

然後調用

aHexStrings = TStringList.create(); 
StrToStringList(Memo1.Text, aHexStrings,2);  

到字符串分割成字符串列表,每個字符串由2個字符長度組成。對於字符串列表中的每個項目,通過使用StrToInt()將其十六進制字符串轉換爲其字節表示並將其寫入COM端口。請注意,StrToInt()會將字符串'$ 1B'解釋爲整數$ 1B。

for i:=0 to aHexStrings.count-1 do 
begin 
    AComPort1.writeByte(Byte(StrToInt('$'+aHexStrings[i]))); 
end; 

這段代碼肯定不是那麼快,因爲字符串拆分任務的開銷並且一次寫入一個字節。

如果你的輸入字符串是$ 1B $ 40,那麼你可以在writeByte()期間避免與'$'字符串連接,如上例所示,但是你需要爲每個3個字符長度拆分字符串。