RS COM PORT

7 отговора 185 прегледа
#1

RS COM PORT

Някой мозе ли да ми каже
как се чете(пише) на COM порт 1 или 2 и как се настройват скорост, четност и т.н.

10х

Отговор
в отговор на Lizard #2

Re: RS COM PORT

Прегледай в SDK темите About Communications.

Отговор
в отговор на Lizard #3

Чрез API - CreateFile

Виж в хелпа за CreateFile, ReadFile и WriteFile.

За да отвориш порта, правиш следното (примерно):

var
Handle : THandle;
PortName : string;
ComState : TDCB; { Device Control Block }

begin
Handle:=createfile(PChar(PortName),GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,0,0);

{ където PortName е съответно 'COM1', 'COM2' и т.н.
Можеш да провериш Handle - ако е равно на INVALID_HANDLE_VALUE, значи има грешка (порта е зает, не съществува или др. )

За да установиш настройките:}

getcommstate(Handle,ComState);
with ComState do
begin
BaudRate:=9600;
ByteSize:=8;
Parity:=NOPARITY;
StopBits:=TWOSTOPBITS
end;
setcommstate(Handle,ComState);
end;

Използвай ReadFile или WriteFile за да четеш или пишеш байт по байт. Можеш да четеш и пишеш и чрез потоци, като им подаваш хендъла, създаден от CreateFile. Виж в API-то и GetCommState, SetCommState, GetCommTimeouts и SetCommTimeouts. Ако не ти се занимава с API функциите, има и готови компоненти за работа със серийни и паралелни портове, но не и в стандартния пакет на Delphi (поне аз не съм ги срещал в документацията или в хелпа). Горното е орязана част от моя подпрограма за комуникация през серийните портове и гарантирано работи под Win 95/98/NT/2000.

Успех :)

P.S. Пиши ми ако искаш да ти пратя сорса на друга моя програма за нещо като чат през COM портовете. Писах я специално за да разбера как се работи с тях преди година-две.

Mixy

Редактирано от Mixy на

Отговор
в отговор на Mixy #4

Re: Чрез API - CreateFile

Много ти благодаря!
Сега ще го пробвам :)
ще съм ти много благодарен ако ми дадеш още код (ако искаш ползвай [email protected] или ICQ#14048238)

още веднъж: 10х

Отговор
в отговор на Lizard #5

Re: Чрез API - CreateFile

Написах това, но нещо не работи?!
Някаква идея къде е проблема?


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

function OpenPort( PortName : string): THandle;
var
Handle : THandle;
ComState : TDCB; { Device Control Block }
begin
Handle:=CreateFile(PChar(PortName),GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,0,0);
Result := Handle;
if Result <> INVALID_HANDLE_VALUE then begin
GetCommState(Handle,ComState);
with ComState do begin
BaudRate:=9600;
ByteSize:=8;
Parity:=NOPARITY;
StopBits:=1;
end;
SetCommState(Handle,ComState);
end else begin
Result :=0;
end;
end;




procedure TForm1.Button1Click(Sender: TObject);
begin
Close;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
fh : THandle;
ch : char;
rdsize: Cardinal;
begin
fh:=OpenPort('COM1');
if fh=0 then begin
ShowMessage('Error!');
exit;
end;
while ch<>#1 do begin
ReadFile(fh,ch, 1, rdsize, nil);
Memo1.Lines.Add('>'+ch);
end;
end;

end.


Отговор
в отговор на Lizard #6

Re: Чрез API - CreateFile

В момента нямам време да гледам къде е проблема, затова ти пратих на мейла обещания примерен код. Компилирай го и стартирай SilPr.exe два пъти. Свържи си серийните портове с обърнат кабел (или копирай SilPr.exe на друг компютър, ако нямаш два порта на своя). Настрой едното приложение за изпращач а другото за получател и го пробвай. При мен няма проблеми. Разгледай сорса и ако не можеш да се оправиш пиши отново по-подробно какво се опитваш да направиш и ще гледам да ти помогна.

Ха със здраве! :)

Mixy
Отговор
в отговор на Lizard #7

Re: Чрез API - CreateFile

COM порта трябва да работи асинхронно.
Пробвай със следните корекции:

var TimeOuts:TCommTimeOuts;
o:TOverlapped;
Ro:cardinal;
....
Handle:=CreateFile(PChar(PortName),GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);
...
SetCommState(Handle,ComState);
// Създаване на overlapped
o.hEvent:=CreateEvent(nil,False,False,nil);
// Установяване на TimeOuts
GetCommTimeOuts(Handle,TimeOuts);
TimeOuts.ReadIntervalTimeout:=60; // Примерно
TimeOuts.ReadTotalTimeoutConstant:=500; // Примерно
TimeOuts.ReadTotalTimeoutMultiplier:=60; // Примерно
SetCommTimeOuts(Handle,TimeOuts);
...

ReadFile(fh,ch, 1, rdsize, @o);
GetOverlappedResult(fh ,o,Ro,True);

Успех!
И не забравяй да погледнеш в Help-a

Отговор
в отговор на NDeu #8

Re: Чрез API - CreateFile

Вярно, че съм пропуснал да сложа кода за TimeOuts. При мен всички интервали са нула, т.е. не се проверяват. Но програмата ми работи и без FILE_FLAG_OVERLAPPED, така, както съм го постнал.

Mixy
Отговор