Тоесть получается, что
Код:
function W_IO(Address, Cmd: char; BodyLen: integer; const CmdBody; var ReplyLen: integer; var Reply-Buffer): char;
Это сам запрос к считывателю, а
Код:
char W_IO(char Address, char Cmd, int BodyLen, void *CmdBody, int *ReplyLen, void *ReplyBuffer);
Это непосредственно обработчик ответа?
на данный момент код выглядет так:
Код:
unit Main_form;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, SyncObjs, ExtCtrls;
type
TMain = class(TForm)
Button1: TButton;
Button2: TButton;
Edit1: TEdit;
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
function LinkProc(ProcName: string):Pointer;
procedure Read;
procedure PortSetup;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
PComInfo = ^ TComInfo;
TComInfo = record
RecordSize: DWORD; // Размер структуры, байт
Port: BYTE; // Номер порта. 1 - COM1 и т.д.
BaudRate: DWORD; // Скорость обмена
WaitPortTimeout: DWORD; // Время ожидания доступности порта, мс
ReadTotalTimeout: DWORD; // Время ожидания ответа считывателя, мс
ReadNextByteTimeout: DWORD; // Время ожидания поступления очередного
// байта при условии, что обнаружено начало
// валидного кадра, мс.
end;
type
PProtocolInfo = ^ TProtocolInfo;
TProtocolInfo = record
DisableAddress: BOOLEAN; // Размер структуры, байт
CheckMode: INTEGER; // Режим проверки контрольной суммы
end;
// Описываем константы...
const
// Коды ответа оборудования
REPLY_OK = #$00; //Команда выполнена успешно, получены данные
REPLY_ACK_NACK = #$2A; //Признак кадра ACK/NACK, вне библиотеки не используется
REPLY_ACK = #$55; //Получен ответ ACK
REPLY_NACK1 = #$01; //Получен ответ NACK1
REPLY_NACK2 = #$02; //Получен ответ NACK2
REPLY_NACK3 = #$03; //Получен ответ NACK3
REPLY_NACK4 = #$04; //Получен ответ NACK4
REPLY_NACK5 = #$05; //Получен ответ NACK5
REPLY_NACK6 = #$06; //Получен ответ NACK6
// Коды ошибок при работе с портом
REPLY_MISS = #$FF; //Ответ не получен (отсутствует считыватель)
REPLY_ERR_OPENPORT = #$FE; //Ошибка открытия порта
REPLY_ERR_WRITEPORT = #$FD; //Ошибка записи в порт
REPLY_ERR_READPORT = #$FC; //Ошибка чтения из порта
REPLY_ERR_LOCKPORT = #$FB; //Истек таймаут при попытке захватить порт
REPLY_ERR_PORTNOTSET = #$FA; //Параметры порта не установлены
REPLY_ERR_INVALIDANSWER = #$F9; //Ответ не удалось правильно интерпретировать
REPLY_ERR_CRC = #$F8; //Ошибка контрольной суммы
REPLY_ERR_INVALIDFRAME = #$F7; //Неверный идентификатор кадра
// Методы расчета контрольной суммы кадра
CHECK_NONE = #$00; //Не проверять контрольную сумму кадра
CHECK_SUM = #$01; //Использовать суммирование (1 байт)
CHECK_CRC16 = #$02; //Использовать CRC16 (2 байта)
CHECK_FCS = #$03; //Использовать FCS (2 байта)
var
Ret: char;
ReplyLen: integer;
ReplyBuffer: char;
Main: TMain;
t: TComInfo;
p: TProtocolInfo;
W_SetPortParams: procedure(PortCfgPtr: PComInfo); stdcall;
W_SetProtocolParams: procedure(ProtocolInfoPtr: PProtocolInfo); stdcall;
W_IO: function (Address, Cmd: char;
BodyLen: integer;
const CmdBody;
var ReplyLen: integer;
var ReplyBuffer): char; stdcall;
LibHandle: THandle;
implementation
uses StrUtils;
{$R *.dfm}
{ TForm1 }
function TMain.LinkProc(ProcName: string): Pointer;
begin
result:= GetProcAddress(LibHandle,PChar(ProcName));
end;
// Устанавливаем параметры порта...
procedure TMain.PortSetup;
begin
t.Port:=3; // Номер порта. 1 - COM1 и т.д.
t.BaudRate:=115200; // Скорость обмена
t.WaitPortTimeout:= 200; // Время ожидания доступности порта, мс
t.ReadTotalTimeout:= 100; // Время ожидания ответа считывателя, мс
t.ReadNextByteTimeout:= 50;// Время ожидания поступления очередного
// байта при условии, что обнаружено начало
// валидного кадра, мс.
t.RecordSize:= 21; // Размер структуры, байт
end;
// Подключаем библиотеку...
procedure TMain.FormCreate(Sender: TObject);
begin
LibHandle:= LoadLibrary('dll/ProX232.dll');
W_SetPortParams:= LinkProc('W_SetPortParams');
W_SetProtocolParams:= LinkProc('W_SetProtocolParams');
W_IO:= LinkProc('W_IO');
end;
//Формируем запрос...
procedure TMain.Read;
begin
Ret := W_IO(#$1, #$00, 0, '', ReplyLen, ReplyBuffer);
if Ret = REPLY_OK then begin
Edit1.Text:='Команда выполнена успешно, получены данные';
Edit2.Text:=(ReplyBuffer);
end;
if Ret= REPLY_ACK then begin
Edit1.Text:='Получен ответ ACK';
Edit2.Text:=(ReplyBuffer);
end;
if Ret= REPLY_NACK6 then begin
Edit1.Text:='Получен ответ NACK6';
Edit2.Text:=(ReplyBuffer);
end;
end;
// Создаем подключение, Устанавливаем параметры протакола и отправляем запрос...
procedure TMain.Button1Click(Sender: TObject);
begin
PortSetup;
W_SetPortParams(@t);
W_SetProtocolParams(@t);
read;
end;
// Закрываем программу...
procedure TMain.Button2Click(Sender: TObject);
begin
close;
end;
end.
При таком раскладе программа корректно отправляет запрос, в сниффере видно, что ответ от ридера есть.
В Edit1 все вписывается, так, как должно ( «Константы» REPLY_XXXXX определяются верно и ответ выводится верно), вот только в Edit2 вписывается 1.
А вот с ответом в Edit1 у меня проюлемы.
Я так понимаю, что необходимо использовать
Код:
char W_IO(char Address, char Cmd, int BodyLen, void *CmdBody, int *ReplyLen, void *ReplyBuffer);
но как его использовать и где его необходино прикрутить, я понять не могу.
Общение со считывателем осуществляется в щеснадцатиричной кодировке.
С ini я вроде разобрался, спасибо.