RS COM PORT
7 отговора
185 прегледа
RS COM PORT
Някой мозе ли да ми каже
как се чете(пише) на COM порт 1 или 2 и как се настройват скорост, четност и т.н.
10х
как се чете(пише) на COM порт 1 или 2 и как се настройват скорост, четност и т.н.
10х
Чрез 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
За да отвориш порта, правиш следното (примерно):
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 на
Re: Чрез API - CreateFile
Много ти благодаря!
Сега ще го пробвам :)
ще съм ти много благодарен ако ми дадеш още код (ако искаш ползвай [email protected] или ICQ#14048238)
още веднъж: 10х
Сега ще го пробвам :)
ще съм ти много благодарен ако ми дадеш още код (ако искаш ползвай [email protected] или ICQ#14048238)
още веднъж: 10х
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.
Някаква идея къде е проблема?
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.
Re: Чрез API - CreateFile
В момента нямам време да гледам къде е проблема, затова ти пратих на мейла обещания примерен код. Компилирай го и стартирай SilPr.exe два пъти. Свържи си серийните портове с обърнат кабел (или копирай SilPr.exe на друг компютър, ако нямаш два порта на своя). Настрой едното приложение за изпращач а другото за получател и го пробвай. При мен няма проблеми. Разгледай сорса и ако не можеш да се оправиш пиши отново по-подробно какво се опитваш да направиш и ще гледам да ти помогна.
Ха със здраве! :)
Mixy
Ха със здраве! :)
Mixy
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
Пробвай със следните корекции:
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
Re: Чрез API - CreateFile
Вярно, че съм пропуснал да сложа кода за TimeOuts. При мен всички интервали са нула, т.е. не се проверяват. Но програмата ми работи и без FILE_FLAG_OVERLAPPED, така, както съм го постнал.
Mixy
Mixy