Mój problem jest następujący. Próbuję się skomunikować ze sterownikiem po RS po protokole MODBUS.
Mój sterownik jeden znak zapisuje na 4 bitach. Interesują mnie adresy pamięci powyżej adresu 3000h. Handshaking chyba mam sprzętowy. To co wymyśłiłem do tej pory zapisałem poniżej. $ ostanie znaki to obliczenia z CRC16. Na razie liczyłem je osobno w innym programie. Chociaz procedure też mam rozpisaną.
Kod: Zaznacz cały
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;
type
TForm1 = class(TForm)
OpenComm: TButton;
Send: TButton;
Receive: TButton;
CloseComm: TButton;
RichEdit1: TRichEdit;
procedure CloseCommClick(Sender: TObject);
procedure OpenCommClick(Sender: TObject);
procedure SendClick(Sender: TObject);
procedure ReceiveClick(Sender: TObject);
private
{ Private declarations }
procedure Write_Comm(hCommDev: THANDLE;
nNumberOfBytesToWrite: DWORD);
procedure Read_Comm(hCommDev: THANDLE; Buf_Size: DWORD);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
const
// -- wartości znaczników sterujących portu szeregowego --
dcb_fBinary = True;
dcb_fParity = False;
DTR_CONTROL_HANDSHAKE = False;
RTS_CONTROL_HANDSHAKE = True;
dcb_fOutXCts = True;
dcb_fInX = False;
dcb_fErrorChar = False;
dcb_fNull = False;
dcb_AbortOnError = False;
cbInQueue = 15;
cbOutQueue = 15;
var
query : PChar = '0503300000018A8E'; // przykładowe zapytanie
Buffer_O : ARRAY[0..cbOutQueue] of Char; // bufor wyjściowy
Buffer_I : ARRAY[0..cbInQueue] of Char; // bufor wejściowy
Number_Bytes_Read : DWORD;
hCommDev : THANDLE;
lpFileName : PChar;
fdwEvtMask : DWORD;
Stat : TCOMSTAT;
Errors : DWORD;
dcb : TDCB;
procedure TForm1.Write_Comm(hCommDev: THANDLE;
nNumberOfBytesToWrite: DWORD);
var
NumberOfBytesWritten : DWORD;
begin
WriteFile(hCommDev, Buffer_O, nNumberOfBytesToWrite,
NumberOfBytesWritten, NIL);
WaitCommEvent(hCommDev, fdwEvtMask, NIL);
end;
//--------------------------------------------------------------------
procedure TForm1.Read_Comm(hCommDev: THANDLE; Buf_Size: DWORD);
var
nNumberOfBytesToRead: DWORD;
begin
ClearCommError(hCommDev, Errors, @Stat);
if (Stat.cbInQue > 0) then
begin
if (Stat.cbInQue > Buf_Size) then
nNumberOfBytesToRead := Buf_Size
else
nNumberOfBytesToRead := Stat.cbInQue;
ReadFile(hCommDev, Buffer_I, nNumberOfBytesToRead,
Number_Bytes_Read, NIL);
end
else
Number_Bytes_Read := 0;
end;
//--------------------------------------------------------------------
procedure TForm1.CloseCommClick(Sender: TObject);
begin
CloseHandle(hCommDev);
Application.Terminate();
end;
procedure TForm1.OpenCommClick(Sender: TObject);
begin
lpFileName := 'COM1';
hCommDev := CreateFile(lpFileName, GENERIC_READ or GENERIC_WRITE,0,
NIL, OPEN_EXISTING, 0, 0);
if (hCommDev <> INVALID_HANDLE_VALUE) then
begin
SetupComm(hCommDev, cbInQueue, cbOutQueue);
// dcb.DCBlength := sizeof(dcb);
GetCommState(hCommDev, dcb);
dcb.BaudRate := CBR_9600;
//-- przykładowe ustawienia znaczników sterujących DCB --
// dcb.Flags := RTS_CONTROL_DISABLE or dcb_fParity;
dcb.Parity := NOPARITY;
dcb.StopBits := ONESTOPBIT;
dcb.ByteSize := 4;
SetCommState(hCommDev, dcb);
GetCommMask(hCommDev, fdwEvtMask);
SetCommMask(hCommDev, EV_TXEMPTY);
end
else
case hCommDev of
IE_BADID: MessageDlg('Niewłaściwa nazwa portu '+lpFileName+
' lub jest on aktywny ',
mtError, [mbOk], 0);
end;
end;
procedure TForm1.SendClick(Sender: TObject);
begin
StrCopy(Buffer_O, query);
RichEdit1.Text := Buffer_O;
Write_Comm(hCommDev, StrLen(Buffer_O));
FlushFileBuffers(hCommDev);
end;
procedure TForm1.ReceiveClick(Sender: TObject);
begin
Read_Comm(hCommDev, SizeOf(Buffer_I));
RichEdit1.Text := Buffer_I;
end;
end.
Pomocy