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!!!