Страница 1 из 1

Обшение микроконтроллера и PC через COM порт

СообщениеДобавлено: 13.05.2012 17:40:42
Warheadfromcccp
Здравствуйте :) У меня есть хобби я занимаюсь разроботкой и програмированием устройств на мк. Программы для мк я пишу на си, но знаком и с паскалем могу и на микропаскале забацать чтонибуь :D . Так вот я хочу написать программу для PC чтобы обшятся с мк через USRT по средствам COM порта (виртуалного ком порта на FT232 но это неважно вам 8) ) вообщем мне нужна помошь: мне нужен образец кода для работы с com портом в виндовсе с коментариями или чтоб ктонибуть обяснил мне суть, я видел образец кода там какието handle-ры чото ваше нипонятное, куча какихто непонятных переменных
я так понимаю это организовывается через Win API где найти инфу про этот апи для работы с ком портом или может кто раскажет ?
Я использовал токой вот код но это бред потому как он начинает работать толко после запуска программы Terminal v1.9b (выходит она иницыализирует сом порт и только после нее он работает) воттакая вот замута :D :D

program port;

uses crt;

var
com_port : file of byte;

begin

Assign (com_port, 'COM3');
Reset (com_port);

while (true) do
begin
Write (com_port, byte('r'));
delay(25);
end;
end.

Re: Обшение микроконтроллера и PC через COM порт

СообщениеДобавлено: 13.05.2012 22:58:00
Oleg_D
Прилагаю к сему библиотеку фирмы Moxa.com
Просто и удобно, думаю, по хелпу разберетесь что к чему.

Re: Обшение микроконтроллера и PC через COM порт

СообщениеДобавлено: 14.05.2012 07:20:57
alexey38
Код: Выделить всё
Var
   ComFile: THandle;
function OpenCOMPort: Boolean;
begin
     ComFile := CreateFile(PChar(DeviceName),GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
     if ComFile = INVALID_HANDLE_VALUE then
       Result := False
     else
       Result := True;
end;
function SetupCOMPort: Boolean;
const
     RxBufferSize = 1024;
     TxBufferSize = 1024;
var
   DCB: TDCB;
   Config: string;
   CommTimeouts: TCommTimeouts;
begin
     Result:=True;
     if not SetupComm(ComFile, RxBufferSize, TxBufferSize) then
       Result:=False;
     if not GetCommState(ComFile, DCB) then
       Result:=False;
     Config:='baud='+BaudStr+'parity='+ ParityStr+'data='+DataStr+'stop='+StopStr;
     if not BuildCommDCB(@Config[1], DCB) then
       Result := False;
     if not SetCommState(ComFile, DCB) then
       Result := False;
     with CommTimeouts do
     begin
       ReadIntervalTimeout         := 0;
       ReadTotalTimeoutMultiplier  := 0;
       ReadTotalTimeoutConstant    := 350;
       WriteTotalTimeoutMultiplier := 0;
       WriteTotalTimeoutConstant   := 50;
     end;
     if not SetCommTimeouts(ComFile, CommTimeouts) then
       Result := False;
end;
procedure SendText(s: string);
var
   BytesWritten: DWORD;
begin
     WriteFile(ComFile, s[1], Length(s), BytesWritten, nil);
end;
procedure ReadText;
var
   d: array[1..512] of Char;
   BytesRead : DWORD;
   i: integer;
begin
     if not ReadFile(ComFile, d, SizeOf(d), BytesRead, nil) then
     begin
       { Raise an exception }
     end;
     sr := '';
     for i := 1 to BytesRead do
       sr := sr + d[I];
end;

Re: Обшение микроконтроллера и PC через COM порт

СообщениеДобавлено: 14.05.2012 09:06:25
Mr.Smart
Раз началась такая пьянка. Со своей стороны предложу использовать библиотеку synaser.

Re: Обшение микроконтроллера и PC через COM порт

СообщениеДобавлено: 14.05.2012 12:47:30
svk12
Ну и ещё можно использовать функции из модуля "serial".

Re: Обшение микроконтроллера и PC через COM порт

СообщениеДобавлено: 14.05.2012 19:16:22
Warheadfromcccp
Ох как все сложно, блин ну придется всетаки разбиратся :( (мда 59 строк толко чтоб COM включить :evil: :evil: :evil: :evil: :evil: :evil: :evil: )

Сасибо :D

Re: Обшение микроконтроллера и PC через COM порт

СообщениеДобавлено: 15.05.2012 16:53:09
Oleg_D
Warheadfromcccp писал(а):мда 59 строк толко чтоб COM включить

Нет тут ничего военного, вот простенькие примеры.
Код: Выделить всё
program Test_PComm;

{$APPTYPE CONSOLE}

uses  PComm;

const CSpeed = PComm.B19200;  // скорость
      CTotalTimeOut = 1000;   // таймаут общий (мс)
      CByteTimeOut = 500;     // таймаут между байтами (мс)

var PortsList : set of byte;  // список доступных портов
    PortsCount: integer;      // Количество портов

procedure PortsScan;          // сканирование всех портов
var i, status: integer;
begin
  PortsList:=[ ];
  PortsCount:=0;
  for i:=1 to 255 do begin
    status:= sio_open(i);
    if status=SIO_OK then begin
      sio_close(i);
      PortsList:= PortsList+[ i ];
      Inc(PortsCount);
    end;
  end;
end;

procedure PortsExpo;
var i : integer;
begin
  Write(PortsCount,' found :');
  for i:=1 to 255 do if i in PortsList then Write(i:4);
  Writeln;
end;

function PortOpen(aPort: byte): boolean;
begin
  // Открываем
  Result:= sio_Open(aPort) = SIO_OK;
  if not Result then Exit;
  // Настраиваем скорость, четность, длину, стоп-бит
  Result:= sio_ioctl(aPort, CSpeed, P_NONE or BIT_8 or STOP_1 )=SIO_OK;
  if not Result then Exit;
  // Настраиваем таймаут приема
  Result:= sio_SetReadTimeouts (aPort, CTotalTimeOut, CByteTimeOut)=SIO_OK;
end;

procedure SendString(aPort: byte; const aStr: string);
var i : integer;
begin
  for i:= 1 to Length(aStr) do
    if sio_putch(aPort, Ord(aStr[i])) <> SIO_OK then break;
end;

function RecvString(aPort: byte): string;
var  next: integer;
begin
  Result:='';
  repeat
    next:= sio_getch(aPort);
    if next>0 then Result:= Result + Char(next);
  until next<0;
end;

var Port: integer;
    Request, Answer : string;

begin
  Writeln('Scan com-ports... ');
  PortsScan;
  PortsExpo;
  repeat
    Write('ComPort = '); Readln(Port);
    if Port in PortsList then begin
      if PortOpen(Port) then begin
        Write('Request = '); Readln(Request);
        SendString(Port, Request);
        Answer:= RecvString(Port);
        Writeln('Answer= ', Answer);
      end;
    end;
  until Port=0;
end.

Re: Обшение микроконтроллера и PC через COM порт

СообщениеДобавлено: 16.05.2012 09:29:36
Warheadfromcccp
Чтото он ругается на модуль PCOMM :? Oткрывает окно с текстом программы модуля и предлагает исправлять ошибки :shock:
может из-за того что у меня win 7 64 и Lazarus (походу тоже 64) может модуль толко для FPC :?

Re: Обшение микроконтроллера и PC через COM порт

СообщениеДобавлено: 16.05.2012 12:34:02
Oleg_D
Warheadfromcccp писал(а):тото он ругается на модуль PCOMM Oткрывает окно с текстом программы модуля и предлагает исправлять ошибки

В дельфаке без проблем работает. Выкладывайте проблему подробней, тогда вместе покумекаем.

Re: Обшение микроконтроллера и PC через COM порт

СообщениеДобавлено: 16.05.2012 13:06:35
Mr.Smart
Warheadfromcccp, Oleg_D чтож вы хотите то, библиотека 32х разрядная. Используйте 32х разрядный компилятор.

Добавлено спустя 1 минуту 39 секунд:
И ещё. Нафига нужно внешняя библиотека, если есть кросс платформенный модуль synaser?

Re: Обшение микроконтроллера и PC через COM порт

СообщениеДобавлено: 16.05.2012 13:46:19
svk12
К сожалению, уже не кроссплатформный.
Под Линуксом(RFR-16-i386) процедура
Код: Выделить всё
TBlockSerial.Connect(comport: string);
вызывает ошибку "Bad file number".
Также не работает и
Код: Выделить всё
function SerOpen(const DeviceName: String): TSerialHandle;
из модуля serial.pp - возвращает -1.
Похоже, что разработчики FPC не учли какие-то изменения в ядрах 3.х.
Но под ХП.СП3 работает отлично, да и под Windows 7 x86_64 должно работать, во всяком случае, не ругается.

Re: Обшение микроконтроллера и PC через COM порт

СообщениеДобавлено: 16.05.2012 14:26:13
Oleg_D
Mr.Smart писал(а):чтож вы хотите то, библиотека 32х разрядная. Используйте 32х разрядный компилятор.

Так ведь автор топика не оговорил своих условий, вот и предлагаю то, что лично проверил на своих железках.
Mr.Smart писал(а):Нафига нужно внешняя библиотека, если есть кросс платформенный модуль synaser?

Да кто ж против? Спасибо. Вот скачал сейчас, открыл пример ModemDemo, немного подправил (сразу не компильнулся), получилось это.
Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
var
  ser:TBlockSerial;
begin
  ser:=TBlockSerial.Create;
  ser.RaiseExcept:=True;
  try
    // ser.Connect(Edit1.Text, StrToIntDef(Edit2.Text, 9600),8,'N',0,false,false); // было так
    ser.Connect(Edit1.Text);
    ser.Config(StrToIntDef(Edit2.Text, 9600), 8, 'N', SB1, false, false);
    memo1.lines.text:=ser.ATCommand(Edit3.Text);
  finally
    ser.free;
  end;
end;

В принципе понятно, дальше не стал пробовать, - не на чем проверить.