Уважаемый
cotseec,
Скажите пожалуйста, в чем может быть проблема?
Читая в очередной раз жоки на протакол и библиотеку, я наткнулся на следующее
Методы расчета контрольной суммы кадра
CHECK_NONE - 0х00 //Не проверять контрольную сумму кадра
CHECK_SUM - 0х01 //Использовать суммирование (1 байт)
CHECK_CRC16 - 0х02 //Использовать CRC16 (2 байта)
CHECK_FCS - 0х03 //Использовать FCS (2 байта)
И тут я нашел свою первую ошибку, в следствии чего программа падает в ошибку. Найти нашел, но как исправить не пойму.
изначально
W_SetProtocolParams(@t); у меня ссылался на
TComInfo;, а должен на
TProtocolInfo;
со следующей структурой.
Структура TProtocolInfo:
DisableAddress - BOOLEAN //Размер структуры, байт
CheckMode - INTEGER //Режим проверки контрольной суммы
Добавилв код следующее:
Код:
procedure TForm1.Button2Click(Sender: TObject);
var Prot: TProtocolInfo;
begin
// Prot.DisableAddress:='Это в коментах потому что не могу сообразить, как правильно заполнить'; // Размер структуры, байт
Prot.CheckMode:=03; // Режим проверки контрольной суммы
W_SetProtocolParams(@Prot)
end;
При таком раскладе, программа падает в ошибку при нажитии на эту кнопку и параметры протакола не устанавливаются.
Сейчас переписал все заново и разбил все по кускам (вывел в отдельные кнопки каждую часть - подключение. установку протакола и сам запрос)
Теперь код такой:
Код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, SyncObjs;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Edit1: TEdit;
Edit2: TEdit;
function LinkProc(ProcName: string):Pointer;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(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;
var
Form1: TForm1;
// набор импортируемых функций
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
{$R *.dfm}
{ TForm1 }
{ TForm1 }
function TForm1.LinkProc(ProcName: string): Pointer;
begin
try
result:= GetProcAddress(LibHandle,PChar(ProcName));
Win32Check(Assigned(Result))
except end
end;
// Подключаем DLL....
procedure TForm1.FormCreate(Sender: TObject);
begin
LibHandle:= LoadLibrary('dll/ProX232.dll');
Win32Check(LibHandle<>0);
W_SetPortParams:= LinkProc('W_SetPortParams');
W_IO:= LinkProc('W_IO');
end;
// Устанавливаем параметры порта и создаем подключение....
procedure TForm1.Button1Click(Sender: TObject);
var
t: TComInfo;
begin
t.Port:= 3;
t.BaudRate:= 115200;
t.WaitPortTimeout:= 200;
t.ReadTotalTimeout:= 100;
t.ReadNextByteTimeout:= 50;
t.RecordSize:= 21; // dword = 4 байтам
W_SetPortParams(@t)
end;
// Устанавливаем параметры протакола....
procedure TForm1.Button2Click(Sender: TObject);
var
Prot: TProtocolInfo;
begin
//Prot.DisableAddress:=00; // Размер структуры, байт
Prot.CheckMode:=03; // Режим проверки контрольной суммы
W_SetProtocolParams(@Prot)
end;
// Формирем и отправляем запрос....
procedure TForm1.Button3Click(Sender: TObject);
// Описываем константы....
Const
REPLY_OK = #$0;
REPLY_ACK = #$55;
var
// Выводим переменные....
Ret:char;
ReplyLen:integer;
ReplyBuffer:Pointer;
begin
//определяем размер буфера и выделяем под него память....
ReplyLen:=$FF;
ReplyBuffer:=GetMemory(ReplyLen);
// Формируем и отправляем запрос....
Ret := W_IO(#$1, #$00, 0, '', ReplyLen, ReplyBuffer);
if Ret = REPLY_OK then
begin
// Выводим ответ от считывателя...
Edit1.Text:='Команда выполнена успешно, получены данные';
Edit2.Text:=PChar(ReplyBuffer);// PChar(GetMemory(ReplyLen));
end;
// Освобождаем память...
FreeMemory(ReplyBuffer);
end;
end.
Не пойму несколько вещей.
1. Как правильно настроить параметры установки протакола
2. Почему при нажатии Button2 программа падает в ошибку"access violation at address"
3. Почему раньше параметры устанавливались, но как и сейчас прорамма падала в ошибку.