Komunikcja RS-232 w C++ Builder

0

Witam,
Pisze program, który pobiera wartość z liczników przesunięcia podłączonych do kompa przez RS-232.
Mam zrobioną tą komunikację w Delphi, ale w ogóle nie mogę tego przerobić na C++.

Udało mi się zrobić łączenia z portem a potem rozłączanie, ale nie mam pojęcia jak pobrać wartość.

Obecnie mój program wygląda tak:


//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit3.h"
#include "CCommPort.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm3 *Form3;



DWORD cbOutQueue = 32 ; //rozmiar bufora danych wyjściowych
DWORD cbInQueue = 32 ; //rozmiar bufora danych wejściowych


char*Buffer_O = new char[cbOutQueue] ;
char*Buffer_I = new char[cbInQueue] ;

//char Buffer_O[cbOutQueue]; // bufor danych wyjściowych
// char Buffer_I[cbInQueue]; // bufor danych wejściowych
DWORD Number_Bytes_Read; // liczba bajtów do czytania
HANDLE hCommDev; // identyfikator portu
DWORD fdwEvtMask;
COMSTAT Stat;
DWORD Errors;

//BOOL bResult = TRUE;
//int hThread_SR;
//unsigned ThreadID_SR;
//Cardinal intVar; // licznik pomiaru

LPCTSTR sbuffer1 = "Uwaga !";
LPCTSTR sbuffer2 = "Błąd !";
LPCTSTR sbuffer3 = "Niewłaściwa nazwa portu lub port jest"
" aktywny.";
LPCTSTR sbuffer4 = " Port nie został otwarty do transmisji.";
LPCTSTR sbuffer5 = " Działanie aplikacji zostanie zakończone.";
//-------------------------------------------------
//--------------------------------------------------
BOOL __fastcall Write_Comm(HANDLE hCommDev,
DWORD nNumberOfBytesToWrite)
{
DWORD NumberOfBytesWritten;

//if (WriteFile(hCommDev, &Buffer_O[0], nNumberOfBytesToWrite,
//&NumberOfBytesWritten , NULL) == TRUE)

if (WriteFile(hCommDev,Buffer_O,nNumberOfBytesToWrite,
&NumberOfBytesWritten , NULL)>0)
{
WaitCommEvent(hCommDev, &fdwEvtMask, NULL);
return True ;
}
else
return FALSE;
}
//--------------------------------------------------
BOOL __fastcall Read_Comm(HANDLE hCommDev,
LPDWORD lpNumberOfBytesRead, DWORD Buf_Size)
{
DWORD nNumberOfBytesToRead;

*lpNumberOfBytesRead = 0;

ClearCommError(hCommDev, &Errors ,&Stat);

if (Stat.cbInQue > 0)
{
if (Stat.cbInQue > Buf_Size)
nNumberOfBytesToRead = Buf_Size;
else
nNumberOfBytesToRead = Stat.cbInQue;
}
return ReadFile(hCommDev, &Buffer_I[0],
nNumberOfBytesToRead,
lpNumberOfBytesRead, NULL);
}
//---------------------------------------------------------------------------
__fastcall TForm3::TForm3(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm3::Button1Click(TObject *Sender)
{
  LPCTSTR lpFileName;
DCB dcb;

lpFileName = "COM1";

hCommDev = CreateFile(lpFileName, GENERIC_READ |
GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, 0);

if (hCommDev != INVALID_HANDLE_VALUE)
// sprawdza, czy port jest otwarty prawidłowo
{
SetupComm(hCommDev, cbInQueue, cbOutQueue);
dcb.DCBlength = sizeof(dcb);
GetCommState(hCommDev, &dcb);

dcb.BaudRate = CBR_9600;


dcb.Parity = NOPARITY; // ustawienie parzystości
dcb.StopBits = ONESTOPBIT; // bity stopu
dcb.ByteSize = 8; // bity danych

//-przykładowe ustawienia flag sterujących DCB-
dcb.fParity = TRUE; // sprawdzanie parzystości
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDsrSensitivity = FALSE;
dcb.fAbortOnError = FALSE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
dcb.fErrorChar = FALSE;
dcb.fNull = FALSE;

SetCommState(hCommDev, &dcb);
GetCommMask(hCommDev, &fdwEvtMask);
SetCommMask(hCommDev, EV_TXEMPTY);
}
else
{
switch ((int)hCommDev)
{
case IE_BADID:
MessageBox(NULL, sbuffer3, sbuffer2, MB_OK);
break;
};
}

ShowMessage("Polaczono");

}
//---------------------------------------------------------------------------
void __fastcall TForm3::Button2Click(TObject *Sender)
{
Buffer_O = "X+#13";
char* b="X"+13; // wyslanie znaku "A" do buffora wyj.
uC odpowiada na ten znak pomiarem nr.1
Write_Comm(hCommDev,StrLen(b)); // wyslanie znaku z buffora do uC

memset(Buffer_I,0,cbOutQueue); //czyszczenie bufora wyjsciowego

FlushFileBuffers(hCommDev);

Read_Comm(hCommDev,&Number_Bytes_Read,sizeof(Buffer_I)); //odczytanie pomiaru1 z bufora wejsciowego
RichEdit1->Text = Buffer_I; // wyswietlenie pomiaru
FlushFileBuffers(hCommDev);

}
//---------------------------------------------------------------------------

void __fastcall TForm3::Button3Click(TObject *Sender)
{
switch(MessageBox(NULL, sbuffer5, sbuffer1,
MB_YESNO | MB_ICONQUESTION))
{
case ID_YES :
{
//SuspendThread((HANDLE)hThread_SR);
CloseHandle(hCommDev);

}
case ID_NO :
Abort();
break;
}
}
//---------------------------------------------------------------------------


Z kolei w Delphi to wygląda tak:



// deklaracje stalych wymaganych do nawiazania polaczenia przez port RS232

  const
  // -- wartości znaczników sterujących portu szeregowego --
  dcb_fBinary = $0001;
  dcb_fParity = $0002;
  dcb_fOutxCtsFlow = $0004;
  dcb_fOutxDsrFlow = $0008;

  // -- fDtrControl --
  DTR_CONTROL_ENABLE = $0010;
  DTR_CONTROL_HANDSHAKE = $0020;

  dcb_fDsrSensitivity = $0040;
  dcb_fTXContinueOnXoff = $0080;
  dcb_fOutX = $0100;
  dcb_fInX  = $0200;
  dcb_fErrorChar = $0400;
  dcb_fNull = $0800;

  // -- fRtsControl --
  RTS_CONTROL_ENABLE = $1000;
  RTS_CONTROL_HANDSHAKE = $2000;
  RTS_CONTROL_TOGGLE = $3000;

  dcb_fAbortOnError = $4000;

  cbInQueue = 256;
  cbOutQueue = 256;

  var
  queryX : PChar = 'X'+#13; // zapytanie o X
  queryY : PChar = 'Y'+#13; // zapytanie o Y
  Buffer_O : ARRAY[0..cbOutQueue] of Char; // bufor wyjściowy
  Buffer_I : ARRAY[0..cbInQueue] of Char;  // bufor wejściowy

  Number_Bytes_Read : DWORD;
  hCommDev : THANDLE;
  lpFileName : PChar;
  fdwEvtMask : DWORD;
  Stat : TCOMSTAT;
  Errors : DWORD;
  dcb    : TDCB;

......

// funkcje pomocnicze nawiązania polaczenia przez port RS232

function TForm1.Write_Comm(hCommDev: THANDLE;
                           nNumberOfBytesToWrite: DWORD): Integer;
  var
    NumberOfBytesWritten : DWORD;

begin
  WriteFile(hCommDev, Buffer_O, nNumberOfBytesToWrite,
            NumberOfBytesWritten, NIL);
  if (WaitCommEvent(hCommDev, fdwEvtMask, NIL) = TRUE) then
      Write_Comm := 1
      else
        Write_Comm := 0;
end;

function TForm1.Read_Comm(hCommDev: THANDLE;
                           Buf_Size: DWORD): Integer;
  var
     nNumberOfBytesToRead: DWORD;
begin
   ClearCommError(hCommDev, Errors, @Stat);
   if (Stat.cbInQue > 0) then
     begin
        if (Stat.cbInQue > Buf_Size) then
          nNumberOfBytesToRead := Buf_Size
          else
             nNumberOfBytesToRead := Stat.cbInQue;
         ReadFile(hCommDev, Buffer_I, nNumberOfBytesToRead,
                  Number_Bytes_Read, NIL);
         Read_Comm := 1;
     end
       else
          begin
            Number_Bytes_Read := 0;
            Read_Comm := 0;
          end;
end;

........



// ------- OTWORZENIE PORTU RS232C

  lpFileName := 'COM1';

  hCommDev:= CreateFile(lpFileName, GENERIC_READ or GENERIC_WRITE, 0,
                         NIL, OPEN_EXISTING, 0, 0);

  if (hCommDev <> INVALID_HANDLE_VALUE) then
    begin
      SetupComm(hCommDev, cbInQueue, cbOutQueue);
      dcb.DCBlength := sizeof(dcb);
      GetCommState(hCommDev, dcb);
      dcb.BaudRate := CBR_9600;

        //ustawienia znaczników sterujących DCB-
       dcb.Flags := DTR_CONTROL_ENABLE or dcb_fParity;

         dcb.Parity := NOPARITY;
         dcb.StopBits := ONESTOPBIT;
         dcb.ByteSize := 8;

         SetCommState(hCommDev, dcb);
         GetCommMask(hCommDev, fdwEvtMask);
         SetCommMask(hCommDev, EV_TXEMPTY);
    end
      else
         case hCommDev of
           IE_BADID: MessageDlg('Port '+lpFileName+
                                ' jest już aktywny! ',
                                 mtError, [mbOk], 0);
         end;
end;

.......................



// obsluga przyciskow funkcyjnych - wczytanie danych z licznikow

procedure TForm1.Button6Click(Sender: TObject);
var sx, sy: String;
    i:integer;
    sczytx, sczyty: Boolean;
    start: Boolean;
    x,y: real;
    zx, zy: real;

begin

start:=true;

   //-- sczytanie X
   Repeat
     StrCopy(Buffer_O, queryX);
     FlushFileBuffers(hCommDev);
   Until (Write_Comm(hCommDev, StrLen(Buffer_O)) <> 0);

   Sleep (50);

   if (Read_Comm(hCommDev, SizeOf(Buffer_I)) > 0) then
      begin
        Beep();
        sx:= Buffer_I;
        Delete(sx, 1, 1);
        Delete(sx, Pos(#13, sx), 10);
        sczytx:=true;
      end
        else
      begin
        sczytx:=false;
        Beep();
      end;

    //--sczytanie Y

   Repeat
     StrCopy(Buffer_O, queryY);
     FlushFileBuffers(hCommDev);
   Until (Write_Comm(hCommDev, StrLen(Buffer_O)) <> 0);

   Sleep (50);

   if (Read_Comm(hCommDev, SizeOf(Buffer_I)) > 0) then
      begin
        Beep();
        sy:= Buffer_I;
        Delete(sy, 1, 1);
        Delete(sy, Pos(#13, sy), 10);
        sczyty:=true;
      end
        else
      begin
        sczyty:=false;
        Beep();
      end;

POMOCY!!!

0

Mógłbyś zawęzić kod do fragmentu, którego nie potrafisz przetłumaczyć, albo który nie działa?

1 użytkowników online, w tym zalogowanych: 0, gości: 1