При помощи функции ClearCommError можно узнать, сколько байт данных находится в буфере приёма (и буфере передачи) последовательного интерфейса.

 

В Delphi  записывать и считывать из портов можно через глобальный массив 'ports'. Однако данная возможность отсутствует в '32-битном' Delphi.

 Следующие две функции можно использовать в любой версии delphi:

 

 

Code:

unit TestRosh;

 

interface

 

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls,

Forms, Dialogs, StdCtrls, ExtCtrls;

 

type

TForm1 = class(TForm)

Panel1: TPanel;

Label1: TLabel;

PortCombo: TComboBox;

Label2: TLabel;

BaudCombo: TComboBox;

Label3: TLabel;

ByteSizeCombo: TComboBox;

Label4: TLabel;

ParityCombo: TComboBox;

Label5: TLabel;

StopBitsCombo: TComboBox;

Label6: TLabel;

Memo1: TMemo;

Edit1: TEdit;

Button1: TButton;

Memo2: TMemo;

Edit2: TEdit;

Label7: TLabel;

Button2: TButton;

Label8: TLabel;

Edit3: TEdit;

procedure Button1Click(Sender: TObject);

procedure Memo2Change(Sender: TObject);

procedure Memo1Change(Sender: TObject);

procedure FormDestroy(Sender: TObject);

procedure Button2Click(Sender: TObject);

procedure PortComboChange(Sender: TObject);

procedure FormShow(Sender: TObject);

procedure Memo1DblClick(Sender: TObject);

end;

 

var

Form1: TForm1;

 

implementation

 

{$R *.DFM}

 

uses

Registry;

 

var

hPort: THandle;

 

procedure TForm1.Memo1Change(Sender: TObject);

var

i: Integer;

begin

Edit1.Text := '';

for i := 1 to Length(Memo1.Text) do

   Edit1.Text := Edit1.Text + Format('%x', [Ord(Memo1.Text[i])]) + ' '

end;

 

procedure TForm1.Memo2Change(Sender: TObject);

var

i: Integer;

begin

Edit2.Text := '';

for i := 1 to Length(Memo2.Text) do

   Edit2.Text := Edit2.Text + Format('%x', [Ord(Memo2.Text[i])]) + ' '

end;

 

procedure TForm1.Button1Click(Sender: TObject);

var

S, D: array[0..127] of Char;

actual_bytes: Integer;

DCB: TDCB;

begin

 

FillChar(S, 128, #0);

FillChar(D, 128, #0);

 

DCB.DCBlength := SizeOf(DCB);

 

if not GetCommState(hPort, DCB) then

begin

   ShowMessage('Can not get port state: ' + IntToStr(GetLastError));

   Exit;

end;

 

try

   DCB.BaudRate := StrToInt(BaudCombo.Text);

except

   BaudCombo.Text := IntToStr(DCB.BaudRate);

end;

 

try

   DCB.ByteSize := StrToInt(ByteSizeCombo.Text);

except

   ByteSizeCombo.Text := IntToStr(DCB.ByteSize);

end;

 

if ParityCombo.ItemIndex > -1 then

   DCB.Parity := ParityCombo.ItemIndex

else

   ParityCombo.ItemIndex := DCB.Parity;

 

if StopBitsCombo.ItemIndex > -1 then

   DCB.StopBits := StopBitsCombo.ItemIndex

else

   StopBitsCombo.ItemIndex := DCB.StopBits;

 

if not SetCommState(hPort, DCB) then

begin

   ShowMessage('Can not set new port settings: ' + IntToStr(GetLastError));

   Exit;

end;

 

PurgeComm(hPort, PURGE_TXABORT or PURGE_RXABORT or PURGE_TXCLEAR or PURGE_RXCLEAR);

 

StrPCopy(S, Memo1.Text);

 

if not WriteFile(hPort, S, StrLen(S), actual_bytes, nil) then

begin

   ShowMessage('Can not write to port: ' + IntToStr(GetLastError));

   Exit;

end;

 

if not ReadFile(hPort, D, StrToInt(Edit3.Text), actual_bytes, nil) then

   ShowMessage('Can not read from port: ' + IntToStr(GetLastError))

else

   ShowMessage('Read ' + IntToStr(actual_bytes) + ' bytes');

Memo2.Text := D;

end;

 

procedure TForm1.FormDestroy(Sender: TObject);

begin

with TRegistry.Create do

begin

   OpenKey('Shkila', True);

   WriteString('Port', PortCombo.Text);

   WriteString('Baud Rate', BaudCombo.Text);

   WriteString('Byte Size', ByteSizeCombo.Text);

   WriteString('Parity', IntToStr(ParityCombo.ItemIndex));

   WriteString('Stop Bits', IntToStr(StopBitsCombo.ItemIndex));

   Destroy;

end;

if not CloseHandle(hPort) then

begin

   ShowMessage('Can not close port: ' + IntToStr(GetLastError));

   Exit;

end;

end;

 

procedure TForm1.Button2Click(Sender: TObject);

begin

hPort := CreateFile(PChar(PortCombo.Text),

GENERIC_READ + GENERIC_WRITE,

0,

nil,

OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL,

0);

 

if hPort = INVALID_HANDLE_VALUE then

   ShowMessage('Can not open ' + PortCombo.Text + ': ' + IntToStr(GetLastError))

else

   Button2.Hide;

end;

 

procedure TForm1.PortComboChange(Sender: TObject);

begin

FormDestroy(Sender);

Button2.Show;

end;

 

procedure TForm1.FormShow(Sender: TObject);

begin

with TRegistry.Create do

begin

   OpenKey('Shkila', True);

   PortCombo.Text := ReadString('Port');

   BaudCombo.Text := ReadString('Baud Rate');

   ByteSizeCombo.Text := ReadString('Byte Size');

   ParityCombo.ItemIndex := StrToInt(ReadString('Parity'));

   StopBitsCombo.ItemIndex := StrToInt(ReadString('Stop Bits'));

   Destroy;

end;

end;

 

procedure TForm1.Memo1DblClick(Sender: TObject);

begin

Memo1.Lines.Clear;

Memo2.Lines.Clear;

Edit1.Text := '';

Edit2.Text := '';

end;

 

end.

 

 

Компонент, который представлен здесь, выполняет функции синхронного чтения и записи в последовательный интерфейс RS232.

В цикле выполняется Application.ProcessMessages, чтобы все сообщения от основной программы обрабатывались.

 

 

Простой пример работы с последовательными портами.

Код содержит интуитивно понятные комментарии и строки на шведском языке,

нецелесообразные для перевода.

 

 

 

Code:

unit U_Usb;

 

interface

 

uses

Windows, Messages, SysUtils, Classes, Forms;

 

type

 

PDevBroadcastHdr  = ^DEV_BROADCAST_HDR;

DEV_BROADCAST_HDR = packed record

   dbch_size: DWORD;

   dbch_devicetype: DWORD;

   dbch_reserved: DWORD;

end;

 

PDevBroadcastDeviceInterface  = ^DEV_BROADCAST_DEVICEINTERFACE;

DEV_BROADCAST_DEVICEINTERFACE = record

   dbcc_size: DWORD;

   dbcc_devicetype: DWORD;

   dbcc_reserved: DWORD;

   dbcc_classguid: TGUID;

   dbcc_name: short;

end;

 

const

GUID_DEVINTERFACE_USB_DEVICE: TGUID = '{A5DCBF10-6530-11D2-901F-00C04FB951ED}';

DBT_DEVICEARRIVAL          = $8000;          // system detected a new device

DBT_DEVICEREMOVECOMPLETE   = $8004;          // device is gone

DBT_DEVTYP_DEVICEINTERFACE = $00000005;      // device interface class

 

type

 

TComponentUSB = class(TComponent)

private

   FWindowHandle: HWND;

   FOnUSBArrival: TNotifyEvent;

   FOnUSBRemove: TNotifyEvent;

   procedure WndProc(var Msg: TMessage);

   function USBRegister: Boolean;

protected

   procedure WMDeviceChange(var Msg: TMessage); dynamic;

public

   constructor Create(AOwner: TComponent); override;

   destructor Destroy; override;

published

   property OnUSBArrival: TNotifyEvent read FOnUSBArrival write FOnUSBArrival;

   property OnUSBRemove: TNotifyEvent read FOnUSBRemove write FOnUSBRemove;

end;

 

implementation

 

constructor TComponentUSB.Create(AOwner: TComponent);

begin

inherited Create(AOwner);

FWindowHandle := AllocateHWnd(WndProc);

USBRegister;

end;

 

destructor TComponentUSB.Destroy;

begin

DeallocateHWnd(FWindowHandle);

inherited Destroy;

end;

 

procedure TComponentUSB.WndProc(var Msg: TMessage);

begin

if (Msg.Msg = WM_DEVICECHANGE) then

begin

   try

     WMDeviceChange(Msg);

   except

     Application.HandleException(Self);

   end;

end

else

   Msg.Result := DefWindowProc(FWindowHandle, Msg.Msg, Msg.wParam, Msg.lParam);

end;

 

procedure TComponentUSB.WMDeviceChange(var Msg: TMessage);

var

devType: Integer;

Datos: PDevBroadcastHdr;

begin

if (Msg.wParam = DBT_DEVICEARRIVAL) or (Msg.wParam = DBT_DEVICEREMOVECOMPLETE) then

begin

   Datos := PDevBroadcastHdr(Msg.lParam);

   devType := Datos^.dbch_devicetype;

   if devType = DBT_DEVTYP_DEVICEINTERFACE then

   begin // USB Device

     if Msg.wParam = DBT_DEVICEARRIVAL then

     begin

       if Assigned(FOnUSBArrival) then

         FOnUSBArrival(Self);

     end

     else

     begin

       if Assigned(FOnUSBRemove) then

         FOnUSBRemove(Self);

     end;

   end;

end;

end;

 

function TComponentUSB.USBRegister: Boolean;

var

dbi: DEV_BROADCAST_DEVICEINTERFACE;

Size: Integer;

r: Pointer;

begin

Result := False;

Size := SizeOf(DEV_BROADCAST_DEVICEINTERFACE);

ZeroMemory(@dbi, Size);

dbi.dbcc_size := Size;

dbi.dbcc_devicetype := DBT_DEVTYP_DEVICEINTERFACE;

dbi.dbcc_reserved := 0;

dbi.dbcc_classguid  := GUID_DEVINTERFACE_USB_DEVICE;

dbi.dbcc_name := 0;

 

r := RegisterDeviceNotification(FWindowHandle, @dbi,

   DEVICE_NOTIFY_WINDOW_HANDLE

   );

if Assigned(r) then Result := True;

end;

 

end.

 

Взаимодействие с мобильными телефонами

Вы, наверное, не раз видели или даже пользовались программами, которые отображают любую информацию о вашем телефоне. Сейчас вы узнаете, как самим сделать такую программу!

 Для начала положим на форму Memo, CheckBox "Соединиться», кнопку «Послать команду», Edit.

 

При печати Dos-файла в порт напрямую можно это сделать.

 

  Например, напечатать за 2 прохода:

  ESC @ - инициализация принтера

  ESC G - включение режима печати за 2 прохода

  ESC H - выключение режима печати за 2 прохода

 

Автор Дмитрий Кузан, Известно что в компьютере очень много собрано различных устройств , возникает вопрос как операционная система общается с ними. Для этого и служит порт, то есть эта «дверь» через которую программа (операционная система) может управлять данным устройством (считывать данные, заносить их).Причем я разделяю порты на две категории (это чисто мое разделение) - порты общеизвестные (COM LPT) и порты внутренние ,служащие для связи с внутренними устройствами ЭВМ. 2.Некоторые правила для работы с портами Следует иметь в виду что при разработке программ для работы с портами следует учитывать следующие факторы :

Ниже представлен класс для работы с COM-портом.  Класс выдернут из контекста, так что не ручаюсь в компиляции с первого раза, однако все функции работы с COM очевидны.

 

Введение

Код и данные: основной принцип работы процессора

Итак, если не пытаться изложить здесь «кратенько» курс информатики для средней школы, то единственное что хотелось бы напомнить это то, что процессор (за редкими исключениями) исполняет не программы, написанные на каком-нибудь языке программирования (один из которых, вы, возможно, даже знаете), а некий «машинный код». То есть командами для него являются последовательности байтов, находящихся в памяти компьютера.