HiAsm - Конструктор программ

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.



COMEx Ctrl+Z

Сообщений 1 страница 3 из 3

1

https://forumupload.ru/uploads/001b/10/a7/51/t389976.png

Теги: COMEx

Описание (Данная команда необходима для записи данных в порт)

ini

Код:
[About]
Version=1.10
Author=nesco
Mail=hiasm@mail.ru

[Type]
Class=Element
Info=Асинхронный COM порт
Tab=Misc

[Property]
Port=Номер порта|4|0|Com1,Com2,Com3,Com4,Com5,Com6,Com7,Com8,Com9
BaudRate=BaudRate=Скорость порта|14|13|50,75,110,150,300,600,1200,1800,2000,2400,3600,4800,7200,9600,14400,19200,28800,38400,57600,115200,128000,256000
@DataBits=Число битов данных|4|0|7,8
@Parity=Режим проверки ошибок передачи|4|0|None,Odd,Even,Marker,Space
@StopBits=Число стоповых битов|4|0|1,2
DTR=Состояние линии DTR по умолчанию|4|0|off,on
RTS=Состояние линии RTS по умолчанию|4|0|off,on

[Methods]
doOpen=Открывает порт|1|
doClose=Закрывает порт|1|
doWrite=Записывает данные в порт|1|
doWriteAT=Записывает данные в порт c командой CTRL+Z|1|
*doRXClear=Очищает буфер RX входа|1|
*doDTR=Устанавливает/сбрасывает сигнал на линии DTR|1|
*doRTS=Устанавливает/сбрасывает сигнал на линии RTS|1|
*doSetComState=Переустанавливает параметры порта без его перезапуска. Буферы чтения и записи остаются нетронутыми|1|
onSyncWrite=В случае успешной записи выдает в синхронном режиме кол-во записанных байт, иначе - 0|2|
onRead=В случае успешного чтения выдает в асинхронном режиме прочитанную строку байт|2|
onSyncRead=В случае успешного чтения выдает в синхронном режиме прочитанную строку байт|2|
*onDSR=Событие происходит при изменении сигнала на линии DSR, выдавая в поток состяние этой линии в синхроннои режиме|2|
*onCTS=Событие происходит при изменении сигнала на линии CTS, выдавая в поток состяние этой линии в синхроннои режиме|2|
*onDCD=Событие происходит при изменении сигнала на линии DCD, выдавая в поток состяние этой линии в синхроннои режиме|2|
*onRING=Событие происходит при изменении сигнала на линии RI, выдавая в поток состяние этой линии в синхроннои режиме|2|
*onSetComState=Событие происходит после переустановки параметров порта (1 - успешная переустановка, 0 - неуспешная)|2|
Port=Номер порта (от 1 до N)|4|1
BaudRate=Скорость порта|4|1

pas

Код:
unit hiCOMEX;

interface

uses Windows, Kol, Share, Debug;

const
  _nm: string = 'NOEMS';
  dtrrts: string = 'offon ';

type
  _COMSTAT1 = record
    Flags: DWORD;
    cbInQue: DWORD;
    cbOutQue: DWORD;
  end;
  TComStat1 = _COMSTAT1;

type

  THICOMEX = class(TDebug)
   private
    hFile: THandle;
    thrd, thwr: PThread;
    OvrWr, OvrRd: TOverlapped;
    ReadStr: string;
    MaskRd: DWORD;
    SendedWr: Integer;
    procedure CloseCom;
    function SetCom(BaudRate: Integer; Parity, DataBits, StopBits: Char; DTR, RTS: string): boolean;
    function InitCom(BaudRate, PortNo: Integer; Parity, DataBits, StopBits: Char; DTR, RTS: string): boolean;
    function ExecuteRd(Sender: PThread): Integer;
    function ExecuteWr(Sender: PThread): Integer;
    procedure SyncExecRd;
    procedure SyncExecWr;
    procedure SyncExecSt;    
   public
    _prop_Port:byte;
    _prop_BaudRate:integer;
    _prop_Parity:integer;
    _prop_DataBits:integer;
    _prop_StopBits:integer;    
    _prop_DTR: byte;
    _prop_RTS: byte;    

    _event_onSyncWrite:THI_Event;
    _event_onRead:THI_Event;
    _event_onSyncRead:THI_Event;    
    _event_onDSR:THI_Event;
    _event_onCTS:THI_Event;
    _event_onDCD:THI_Event;    
    _event_onRING:THI_Event;
    _event_onSetComState:THI_Event;    
    _data_BaudRate:THI_Event;
    _data_Port:THI_Event;

    constructor Create;
    destructor Destroy; override;
    procedure _work_doOpen(var _Data:TData; Index:word);
    procedure _work_doClose(var _Data:TData; Index:word);
    procedure _work_doRXClear(var _Data:TData; Index:word);
    procedure _work_doWrite(var _Data:TData; Index:word);
    procedure _work_doWriteAT(var _Data:TData; Index:word);
    procedure _work_doDTR(var _Data:TData; Index:word);
    procedure _work_doRTS(var _Data:TData; Index:word);
    procedure _work_doSetComState(var _Data:TData; Index:word);
    procedure _work_doDataBits(var _Data:TData; Index:word);    
    procedure _work_doParity(var _Data:TData; Index:word);    
    procedure _work_doStopBits(var _Data:TData; Index:word);
  end;

implementation

constructor THICOMEX.Create;
begin
  inherited; 
  hFile := INVALID_HANDLE_VALUE;
  FillChar(OvrWr, SizeOf(TOverlapped), #0);
  OvrWr.hEvent := CreateEvent(nil, True, True, #0);
  FillChar(OvrRd, SizeOf(TOverlapped), #0);
  OvrRd.hEvent := CreateEvent(nil, false, false, #0);
end;

destructor THICOMEX.Destroy;
begin
// Этот костыль связан с некорректностью уничтожения класса в FPC
{$ifndef F_P}
  CloseCom;
  CloseHandle(OvrWr.hEvent);
  CloseHandle(OvrRd.hEvent);
{$endif}  
  inherited Destroy; 
end;

function THICOMEX.SetCom(BaudRate: Integer; Parity, DataBits, StopBits: Char; DTR, RTS: string): Boolean;
var 
  PortParam: string;
  dcb: TDCB;
  cto: _COMMTIMEOUTS;
begin 
  result := false;
  if hFile = INVALID_HANDLE_VALUE then exit;

  //установка требуемых параметров
  GetCommState(hFile, dcb); //чтение текущих параметров порта
  PortParam := 'baud='    + Int2Str(BaudRate) +
               ' data='   + DataBits +
               ' parity=' + Parity +
               ' stop='   + StopBits +
               ' dtr='    + DTR +
               ' rts='    + RTS +
               ' xon=off odsr=off octs=off idsr=off';

  FillChar(cto, sizeof(cto), #0);   // убираем все TimeOut-ы, так как будем работать с перекрытыми методами

  if BuildCommDCB(PChar(PortParam), DCB) then
    result := SetCommState(hFile, DCB) and SetCommTimeouts(hFile, cto);
end;

function THICOMEX.InitCom(BaudRate, PortNo: Integer; Parity, DataBits, StopBits: Char; DTR, RTS: string): Boolean;
var 
  FileName: string; 
  PortParam: string;
  dcb: TDCB;
  cto: _COMMTIMEOUTS;
  FModems: DWORD;  
begin 
  result := false;
  CloseCom;
  FileName := '\\.\Com' + Int2Str(PortNo); // имя файла
  hFile := CreateFile(PChar(FileName),
           GENERIC_READ or GENERIC_WRITE,
           0,
           nil,
           OPEN_EXISTING,
           FILE_FLAG_OVERLAPPED,
           0);
  if hFile = INVALID_HANDLE_VALUE then exit;

  //установка требуемых параметров
  GetCommState(hFile, dcb); //чтение текущих параметров порта
  PortParam := 'baud='    + Int2Str(BaudRate) +
               ' data='   + DataBits +
               ' parity=' + Parity +
               ' stop='   + StopBits +
               ' dtr='    + DTR +
               ' rts='    + RTS +
               ' xon=off odsr=off octs=off idsr=off';

  FillChar(cto, sizeof(cto), #0);   // убираем все TimeOut-ы, так как будем работать с перекрытыми методами

  if BuildCommDCB(PChar(PortParam), DCB) then
    result := SetCommState(hFile, DCB) and SetCommTimeouts(hFile, cto);
  if not result then
    CloseCom
  else
  begin
    thrd := {$ifdef F_P}NewThreadforFPC{$else}NewThread{$endif};
    thrd.ThreadPriority := THREAD_PRIORITY_HIGHEST;
    thrd.OnExecute := ExecuteRd;
    thwr := {$ifdef F_P}NewThreadforFPC{$else}NewThread{$endif};
    thwr.ThreadPriority := THREAD_PRIORITY_HIGHEST;
    thwr.OnExecute := ExecuteWr;
    PurgeComm(hFile, PURGE_TXCLEAR or PURGE_RXCLEAR);
    SetCommMask(hFile, EV_RXCHAR or EV_DSR or EV_CTS or EV_RLSD or EV_RING);
    if GetCommModemStatus(hFile, FModems) then
    begin
      _hi_onEvent(_event_onDSR, integer((FModems and MS_DSR_ON) = MS_DSR_ON));
      _hi_onEvent(_event_onCTS, integer((FModems and MS_CTS_ON) = MS_CTS_ON));
      _hi_onEvent(_event_onDCD, integer((FModems and MS_RLSD_ON) = MS_RLSD_ON));            
      _hi_onEvent(_event_onRING, integer((FModems and MS_RING_ON) = MS_RING_ON));
    end;      
    thrd.Resume;
  end;  
end;

procedure THICOMEX.CloseCom;
begin
  if Assigned(thrd) then
  begin
    thrd.Terminate;
    thrd.WaitFor;
    free_and_nil(thrd);    
  end;
  if Assigned(thwr) then
  begin
    thwr.Terminate;
    thwr.WaitFor;
    free_and_nil(thwr);    
  end;
  if hFile = INVALID_HANDLE_VALUE then exit;
  PurgeComm(hFile, PURGE_TXCLEAR or PURGE_RXCLEAR);
  CloseHandle(hFile);
  hFile := INVALID_HANDLE_VALUE;
end;

procedure THICOMEX._work_doOpen;
begin
   CloseCom;
   InitCom(ReadInteger(_Data,_data_BaudRate,_prop_BaudRate),
           ReadInteger(_Data,_data_Port,_prop_Port + 1),
           _nm[_prop_Parity + 1],
           Int2Str(_prop_DataBits + 7)[1],
           Int2Str(_prop_StopBits + 1)[1],
           Copy(dtrrts, _prop_DTR * 3 + 1, 3),
           Copy(dtrrts, _prop_RTS * 3 + 1, 3));
end;

procedure THICOMEX._work_doClose;
begin
  CloseCom;
end;

procedure THICOMEX._work_doRXClear;
begin
  if hFile <> INVALID_HANDLE_VALUE then
     PurgeComm(hFile, PURGE_RXCLEAR);
end;

procedure THICOMEX._work_doWrite;
var
  BufferWr: string;
  Sended: DWORD;  
begin
  if hFile = INVALID_HANDLE_VALUE then exit;
//  if (not thwr.Suspended) then exit;
  BufferWr := ToString(_Data);
  WriteFile(hFile, BufferWr[1], Length(BufferWr), Sended, @OvrWr);
  thwr.Resume;
end;

procedure THICOMEX._work_doWriteAT;
var
  BufferWr: string;
  Sended: DWORD;  
begin
  if hFile = INVALID_HANDLE_VALUE then exit;
//  if (not thwr.Suspended) then exit;
  BufferWr := ToString(_Data) + #$1A;
    WriteFile(hFile, BufferWr[1], Length(BufferWr), Sended, @OvrWr);
  thwr.Resume;
end;

function THICOMEX.ExecuteRd;
var
  Signaled, BytesTrans, Err: DWORD;
  BufferRd: string;   
  FStat: TComStat1;
begin
  while not Sender.Terminated do
  begin
    WaitCommEvent(hFile, MaskRd, @OvrRd);
    Signaled := WaitForSingleObject(OvrRd.hEvent, INFINITE);
    if (Signaled = WAIT_OBJECT_0) then
    begin 
      if GetOverlappedResult(hFile, OvrRd, BytesTrans, True) then
      begin
        if ((MaskRd and EV_RXCHAR) <> 0) then
        begin
          if ClearCommError(hFile, Err, @FStat) then
          begin
            if (FStat.cbInQue <> 0) then
            begin
              SetLength(BufferRd, FStat.cbInQue);
              ReadFile(hFile, BufferRd[1], FStat.cbInQue, BytesTrans, @OvrRd);
              if GetOverlappedResult(hFile, OvrRd, BytesTrans, True) then
              begin
                ReadStr := BufferRd + #0;
                SetLength(ReadStr, BytesTrans);
                _hi_onEvent(_event_onRead, ReadStr);
                if Assigned(_event_onSyncRead.Event) then Sender.Synchronize(SyncExecRd); 
              end;
            end;
          end;  
        end
        else
          if Assigned(_event_onDSR.Event) or
             Assigned(_event_onCTS.Event) or
             Assigned(_event_onDCD.Event) or
             Assigned(_event_onRING.Event) then
            Sender.Synchronize(SyncExecSt);
      end;
    end;        
  end;
  PurgeComm(hFile, PURGE_RXCLEAR);
  Result := 0; 
end;

procedure THICOMEX.SyncExecRd;
begin
  _hi_onEvent(_event_onSyncRead, ReadStr);
end;

procedure THICOMEX.SyncExecSt;
var
  FModems: DWORD;
begin
  if GetCommModemStatus(hFile, FModems) then
    if ((MaskRd and EV_DSR) <> 0) then
      _hi_onEvent(_event_onDSR, integer((FModems and MS_DSR_ON) = MS_DSR_ON));
    if ((MaskRd and EV_CTS) <> 0) then
      _hi_onEvent(_event_onCTS, integer((FModems and MS_CTS_ON) = MS_CTS_ON));
    if ((MaskRd and EV_RLSD) <> 0) then
      _hi_onEvent(_event_onDCD, integer((FModems and MS_RLSD_ON) = MS_RLSD_ON));            
    if ((MaskRd and EV_RING) <> 0) then
      _hi_onEvent(_event_onRING, integer((FModems and MS_RING_ON) = MS_RING_ON));
end;

function THICOMEX.ExecuteWr(Sender: PThread): Integer;
var
  Sended, Signaled: DWORD;
begin
  while not Sender.Terminated do
  begin
    SendedWr := 0;
    Signaled := WaitForSingleObject(OvrWr.hEvent, 500);
    if (Signaled = WAIT_OBJECT_0) then
      if GetOverlappedResult(hFile, OvrWr, Sended, True) then
        SendedWr := integer(Sended);
    if Assigned(_event_onSyncWrite.Event) then Sender.Synchronize(SyncExecWr);     
    Sender.Suspend;
  end;
  PurgeComm(hFile, PURGE_TXCLEAR);
  Result := 0;
end;

procedure THICOMEX.SyncExecWr;
begin
  _hi_onEvent(_event_onSyncWrite, SendedWr);
end;

procedure THICOMEX._work_doDTR;
begin
  if hFile = INVALID_HANDLE_VALUE then exit;
  if ReadBool(_Data) then
    EscapeCommFunction(hFile, SETDTR)
  else
    EscapeCommFunction(hFile, CLRDTR);
end;

procedure THICOMEX._work_doRTS;
begin
  if hFile = INVALID_HANDLE_VALUE then exit;
  if ReadBool(_Data) then
    EscapeCommFunction(hFile, SETRTS)
  else
    EscapeCommFunction(hFile, CLRRTS);
end;

procedure THICOMEX._work_doSetComState;
begin
  if not SetCom(ReadInteger(_Data,_data_BaudRate,_prop_BaudRate),
                _nm[_prop_Parity + 1],
                Int2Str(_prop_DataBits + 7)[1],
                Int2Str(_prop_StopBits + 1)[1],
                Copy(dtrrts, _prop_DTR * 3 + 1, 3),
                Copy(dtrrts, _prop_RTS * 3 + 1, 3)) then
    _hi_onEvent(_event_onSetComState, 0)
  else
    _hi_onEvent(_event_onSetComState, 1);
end;

procedure THICOMEX._work_doDataBits;    
begin
  _prop_DataBits := ToInteger(_Data);
end;

procedure THICOMEX._work_doParity;    
begin
  _prop_Parity := ToInteger(_Data);
end;

procedure THICOMEX._work_doStopBits;
begin
  _prop_StopBits := ToInteger(_Data);
end;

end.

0

2

Отрадно что кто то пытается ещё что то делать для HiAsm
Есть мой порт юнита BComPort С хелпом тут Ссылка

0

3

Чёт не вставляется в hiasm твой код

0



Рейтинг форумов | Создать форум бесплатно