📄 lcdmain.pas
字号:
unit LCDMain;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, Forms,
StdCtrls, Buttons, Dialogs, JvHidControllerClass;
const
cCodeMercenariesVID = $07C0;
cIOWarrior40PID = $1500;
cIOWarrior24PID = $1501;
cLCDEnableReportID = $04;
cLCDWriteReportID = $05;
cLCDReadReportID = $06;
cEnable = $01;
cDisable = $00;
type
TIOWarriorOutputReport = packed record
ReportID: Byte;
LCDBytes: array [1..7] of Byte;
end;
TLCDMainForm = class(TForm)
HidCtl: TJvHidDeviceController;
IOWarriorAvailable: TLabel;
HistoryListBox: TListBox;
EnableChk: TCheckBox;
WriteBtn: TSpeedButton;
Write1: TEdit;
Write2: TEdit;
Write3: TEdit;
Write4: TEdit;
Write5: TEdit;
Write6: TEdit;
Write7: TEdit;
ReadBtn: TSpeedButton;
Read1: TEdit;
SaveBtn: TSpeedButton;
SaveDialog: TSaveDialog;
RSBit: TCheckBox;
procedure FormCreate(Sender: TObject);
procedure HidCtlDeviceChange(Sender: TObject);
procedure EnableChkClick(Sender: TObject);
procedure WriteBtnClick(Sender: TObject);
procedure ReadBtnClick(Sender: TObject);
procedure SaveBtnClick(Sender: TObject);
procedure HidCtlDeviceData(HidDev: TJvHidDevice; ReportID: Byte;
const Data: Pointer; Size: Word);
public
Edits: array [1..7] of TEdit;
IOWarrior: TJvHidDevice;
end;
var
LCDMainForm: TLCDMainForm;
implementation
{$R *.dfm}
procedure TLCDMainForm.FormCreate(Sender: TObject);
var
I: Integer;
begin
// place the edit controls in an array for easy access
if not Assigned(Edits[Low(Edits)]) then
for I := Low(Edits) to High(Edits) do
Edits[I] := TEdit(FindComponent(Format('Write%d', [I])));
// otherwise the Edits are not assigned yet
HidCtl.OnDeviceChange := HidCtlDeviceChange;
end;
function FindLcdIOWarrior(HidDev: TJvHidDevice): Boolean; stdcall;
begin
// the IO-Warrior shows up as two devices
// we want access to the IO-Warrior device for the LCD module
// the other one with a InputReportByteLength of 5 is for access to
// the IO pins
// It is quite interesting to use the IO-WarriorDemo in parallel!
Result := (HidDev.Attributes.VendorID = cCodeMercenariesVID) and
((HidDev.Attributes.ProductID = cIOWarrior40PID) and
(HidDev.Caps.InputReportByteLength = 8)) or
((HidDev.Attributes.ProductID = cIOWarrior24PID) and
(HidDev.Caps.InputReportByteLength = 8));
end;
procedure TLCDMainForm.HidCtlDeviceChange(Sender: TObject);
begin
// Free the device object if it has been unplugged
if Assigned(IOWarrior) and not IOWarrior.IsPluggedIn then
begin
FreeAndNil(IOWarrior);
// throw away the log (better save it before unplugging)
HistoryListBox.Items.Clear;
EnableChk.Checked := False;
EnableChk.Enabled := False;
end;
// if no IO-Warrior in use yet then search for one
if not Assigned(IOWarrior) then
if HidCtl.CheckOutByCallback(IOWarrior, FindLcdIOWarrior) then
begin
EnableChk.Enabled := True;
EnableChk.Checked := True;
end;
if Assigned(IOWarrior) then
begin
if IOWarrior.Attributes.ProductID = cIOWarrior24PID then
IOWarriorAvailable.Caption := 'IOWarrior 24 found'
else
IOWarriorAvailable.Caption := 'IOWarrior 40 found';
end
else
IOWarriorAvailable.Caption := 'No IOWarrior found';
end;
procedure TLCDMainForm.HidCtlDeviceData(HidDev: TJvHidDevice; ReportID: Byte;
const Data: Pointer; Size: Word);
var
I: Integer;
Str: string;
P: PChar;
begin
P := Data;
// show all bytes of the report in hex
Str := Format('R %.2x ', [ReportID]);
for I := 0 to Size-1 do
Str := Str + Format('%.2x ', [Byte(P[I])]);
Str := Str + ' "';
// only show the net content as letters
for I := 1 to (Integer(P[0]) and $07) - 1 do
if Byte(P[I]) >= Byte(' ') then
Str := Str + P[I]
else
Str := Str + '.';
Str := Str + '"';
HistoryListBox.ItemIndex := HistoryListBox.Items.Add(Str);
end;
procedure TLCDMainForm.EnableChkClick(Sender: TObject);
var
I: Integer;
BytesWritten: Cardinal;
IOWarriorOutputReport: TIOWarriorOutputReport;
begin
if Assigned(IOWarrior) then
with IOWarriorOutputReport do
begin
// initialize the output report to enable/disable the LCD module
ReportID := cLCDEnableReportID;
for I := Low(LCDBytes) to High(LCDBytes) do
LCDBytes[I] := $00;
if EnableChk.Checked then
LCDBytes[Low(LCDBytes)] := cEnable
else
LCDBytes[Low(LCDBytes)] := cDisable;
// write the bits to the IO-Warrior to enable/disable the LCD
IOWarrior.WriteFile(IOWarriorOutputReport, SizeOf(IOWarriorOutputReport), BytesWritten);
WriteBtn.Enabled := EnableChk.Checked;
ReadBtn.Enabled := EnableChk.Checked;
end;
end;
procedure TLCDMainForm.WriteBtnClick(Sender: TObject);
var
I: Integer;
Written: Cardinal;
Str: string;
IOWarriorOutputReport: TIOWarriorOutputReport;
begin
with IOWarriorOutputReport do
begin
ReportID := cLCDWriteReportID;
// get the input from the user
for I := Low(Edits) to High(Edits) do
begin
LCDBytes[I] := StrToIntDef('$' + Edits[I].Text, 0);
Edits[I].Text := Format('%.2x', [LCDBytes[I]]);
end;
// reset unused bits in first byte
LCDBytes[1] := LCDBytes[1] and $07;
// add the RS bit from the checkbox
if RSBit.Checked then
LCDBytes[1] := LCDBytes[1] or $80;
IOWarrior.WriteFile(IOWarriorOutputReport, 8, Written);
// show the data in the history listbox
Str := Format('W %.2x ', [ReportID]);
for I := 1 to Written-1 do
Str := Str + Format('%.2x ', [LCDBytes[I]]);
HistoryListBox.ItemIndex := HistoryListBox.Items.Add(Str);
end;
end;
procedure TLCDMainForm.ReadBtnClick(Sender: TObject);
var
I: Integer;
Written: Cardinal;
Str: string;
IOWarriorOutputReport: TIOWarriorOutputReport;
begin
// tell the device to send back the requested amount of bytes
// the read thread of OnData event will pick up the answer
// it would be easier to read after write, but a thread is fail safe
with IOWarriorOutputReport do
begin
// clear the report
ReportID := cLCDReadReportID;
for I := Low(LCDBytes) to High(LCDBytes) do
LCDBytes[I] := $00;
// get number of bytes to read, ensure the max of 63 and reset unused bits
LCDBytes[1] := StrToIntDef('$' + Read1.Text, 0) and $3F;
// add the RS bit from the checkbox
if RSBit.Checked then
LCDBytes[1] := LCDBytes[1] or $80;
IOWarrior.WriteFile(IOWarriorOutputReport, 8, Written);
// show the data in the history listbox
Str := Format('W %.2x ', [ReportID]);
for I := 1 to Written-1 do
Str := Str + Format('%.2x ', [LCDBytes[I]]);
HistoryListBox.ItemIndex := HistoryListBox.Items.Add(Str);
end;
end;
procedure TLCDMainForm.SaveBtnClick(Sender: TObject);
begin
if SaveDialog.Execute then
HistoryListBox.Items.SaveToFile(SaveDialog.FileName);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -