PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Fehlermeldungen beim Ansteuern von RS232



Uwe Osslowsky
05.11.2004, 15:10
Hallo allerseits. Ich habe folgendes Problem: Beim Starten des Programms erhalte ich einige Fehlermeldungen, die mich schon zuviel Zeit und Nerven gekostet haben.
1.Create File: COM5 -> "Zugriff verweigert"
2.GetCommState -> "Handle ist ungültig"
3.SetCommState -> "Handle ist ungültig"
4.GetCommState -> "Handle ist ungültig"
5.SetCommTimeouts -> "Handle ist ungültig"

Danach erst startet das eigentliche Programm. Ich lege den Code mal bei und wäre für Hilfe sehr dankbar.

//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
// #pragma link "ComPort"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}

void ShowLastError(AnsiString where)
{
// In der VCL einfach mit SysErrorMessage:
MessageBox(NULL,SysErrorMessage(GetLastError()).c_ str(),where.c_str(),MB_OK|MB_ICONERROR);
/* Ohne SysErrorMessage:
LPTSTR lpMsgBuf; // char*
FormatMessage( // siehe Online-Hilfe zu Win32
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR)&lpMsgBuf, // Adresse des nullterminierten Meldungstextes
0,
NULL);
MessageBox( NULL, lpMsgBuf,where.c_str(),MB_OK|MB_ICONERROR);
LocalFree( lpMsgBuf ); // Free the buffer.
*/
}


void ShowTextAndValue(TMemo* t,AnsiString s,int Value)
{
t->Lines->Add(s+IntToStr(Value));
}

HANDLE OpenComm(char* Port)//
{
// Öffnet den Port und gibt sein Handle zurück
HANDLE hCom = CreateFile("COM5", // z.B. "COM1",
GENERIC_READ | GENERIC_WRITE, // Zum Senden und Empfangen
0, // Für comm devices exclusive-access notwendig
NULL, // Keine security attributes
OPEN_EXISTING, // Für comm devices OPEN_EXISTING notwendig
0, // In den folgenden Beispielen kein overlapped I/O
NULL); // Für comm devices muß hTemplate NULL sein
if (hCom == INVALID_HANDLE_VALUE)
ShowLastError("CreateFile: "+AnsiString(Port));
return hCom;
}

void showDCB(TMemo* M,HANDLE hCom)
{
DCB dcb; // Device Control Block
BOOL fSuccess = GetCommState(hCom, &dcb); // DCB lesen
if (!fSuccess) ShowLastError("GetCommState");
// DWORD DCBlength; // sizeof(DCB)
// DWORD BaudRate; // current baud rate
ShowTextAndValue(M,"baud rate: ",dcb.BaudRate);
ShowTextAndValue(M,"parity: ",dcb.fParity);
ShowTextAndValue(M,"CTS output flow control: ",dcb.fOutxCtsFlow);
ShowTextAndValue(M,"DSR output flow control: ",dcb.fOutxDsrFlow);
ShowTextAndValue(M,"DTR flow control type: ",dcb.fDtrControl);
ShowTextAndValue(M,"DSR sensitivity: ",dcb.fDsrSensitivity);
ShowTextAndValue(M,"RTS flow control: ",dcb.fRtsControl);
}


void SetDCB(HANDLE hCom)
{
DCB dcb; // Device Control Block
BOOL fSuccess = GetCommState(hCom, &dcb); // DCB lesen
if (!fSuccess) ShowLastError("GetCommState");

// Setze die Baudrate=9600, 8 Datenbits, keine Parity, 1 Stopbit:
dcb.BaudRate = 9600; // Baudrate=9600
dcb.ByteSize = 8; // 8 Datenbits
dcb.Parity = NOPARITY; // keine Parity
dcb.StopBits = ONESTOPBIT; // 1 Stopbit

bool NoFlowControl=false,
HardwareFlowControl=false,
SoftwareFlowControl=true;
// Oft spricht man auch von Hardware- bzw. Software-Handshake
// Die folgenden Ausführungen nach dem MSDN-Artikel

if (NoFlowControl)
{
// kein Hardware Flowcontrol:
dcb.fOutxCtsFlow=false;
dcb.fOutxDsrFlow=false;
// kein Software Flowcontrol:
dcb.fInX=false; // für Empfänger
dcb.fOutX=false; // für Sender

dcb.fDsrSensitivity=false;
}
else
{
if (HardwareFlowControl)
{
dcb.fOutxCtsFlow=true;
dcb.fOutxDsrFlow=true;
}
// Hier kein else: Software- und HardwareFlowControl sind
// gleichzeitig möglich, auch wenn das nicht üblich ist
if (SoftwareFlowControl)
{
dcb.fInX=true; // für Empfänger
dcb.fOutX=true; // für Sender
// Die folgenden Elemente steuern SoftwareFlowControl,
// Sie müssen aber nicht gesetzt werden. Oft reichen die
// Voreinstellungen.
// dcb.fTXContinueOnXoff=false;
// dcb.XonLim = ...;
// dcb.XoffLim = ...;
// dcb.XoffChar = ...;
// dcb.XonChar = ...;
}
}

// SetCommState konfiguriert die serielle Schnittstelle
fSuccess = SetCommState(hCom, &dcb);
if (!fSuccess) ShowLastError("SetCommState");
showDCB(Form1->Memo1,hCom);
}


void SetReadTimeouts(HANDLE hCom)
{ // Der Aufruf von SetCommTimeouts ist notwendig,
// da ohne diesen die Ergebnisse von Readfile undefiniert sind
COMMTIMEOUTS t;
// Alle Wert in Millisekunden
// Werte für ReadFile:
t.ReadIntervalTimeout=100; // Timeout zwischen zwei Zeichen
t.ReadTotalTimeoutMultiplier=10; // pro Zeichen
t.ReadTotalTimeoutConstant=1; //
// Wenn mit ReadFile n Zeichen gelesen werden sollen, tritt ein Timeout
// nach ReadTotalTimeoutMultiplier*n+ReadTotalTimeoutConst ant ms ein.

// Werte für WriteFile: wenn beide 0 sind,
// kein Timeout beim Schreiben
t.WriteTotalTimeoutMultiplier=0;
t.WriteTotalTimeoutConstant=0;
if (!SetCommTimeouts(hCom,&t))
ShowLastError("SetCommTimeouts");
}


void showCommProp(TMemo* M, HANDLE hCom)
{
/*typedef struct _COMMPROP{ // cmmp
WORD wPacketLength; // packet size, in bytes
WORD wPacketVersion; // packet version
DWORD dwServiceMask; // services implemented
DWORD dwReserved1; // reserved
DWORD dwMaxTxQueue; // max Tx bufsize, in bytes
DWORD dwMaxRxQueue; // max Rx bufsize, in bytes
DWORD dwMaxBaud; // max baud rate, in bps
DWORD dwProvSubType; // specific provider type
DWORD dwProvCapabilities; // capabilities supported
DWORD dwSettableParams; // changable parameters
DWORD dwSettableBaud; // allowable baud rates
WORD wSettableData; // allowable byte sizes
WORD wSettableStopParity; // stop bits/parity allowed
DWORD dwCurrentTxQueue; // Tx buffer size, in bytes
WORD dwCurrentRxQueue; // Rx buffer size, in bytes
DWORD dwProvSpec1; // provider-specific data
DWORD dwProvSpec2; // provider-specific data
WCHAR wcProvChar[1]; // provider-specific data
} COMMPROP;
*/
_COMMPROP CP;
GetCommProperties(hCom,&CP);
ShowTextAndValue(M,"max Tx bufsize, in bytes: ",CP.dwMaxTxQueue);
ShowTextAndValue(M,"max Rx bufsize, in bytes: ",CP.dwMaxRxQueue);
ShowTextAndValue(M,"Tx buffer size, in bytes: ",CP.dwCurrentTxQueue);
ShowTextAndValue(M,"Rx buffer size, in bytes: ",CP.dwCurrentRxQueue);
}


HANDLE hComSend,hComReceive;
void __fastcall TForm1::FormCreate(TObject *Sender)
{
BEmpfangClick(Sender);
hComSend=OpenComm("COM5");
hComReceive=OpenComm("COM5");

SetDCB(hComSend);
SetDCB(hComReceive);
SetReadTimeouts(hComReceive);
showCommProp(Form1->Memo1,hComSend);
showCommProp(Form1->Memo1,hComReceive);
}

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
CloseHandle(hComSend);
CloseHandle(hComReceive);
}


int SendData(char Data[],int n)
{
DWORD NumberOfBytesWritten; // Anzahl der gesendeten Bytes
bool b=WriteFile(hComSend,
Data,
n, // Anzahl der zu sendenden Bytes
&NumberOfBytesWritten, // Adresse, an die der Wert geschrieben wird
0); // kein overlapped I/O

if (!b)
ShowLastError("SendData");
return NumberOfBytesWritten;
}


void __fastcall TForm1::BSendenClick(TObject *Sender)
{
// int n=SendData("abcdefghijklmno",10);
int n=SendData(Edit1->Text.c_str(),Edit1->Text.Length());
Memo1->Lines->Add("Written: "+IntToStr(n));
}

DWORD ReceiveData(char* Data,int n)
{
DWORD NumberOfBytesRead; // Anzahl der gelesenen Bytes
bool b=ReadFile(hComReceive, // handle des Com-Ports
Data, // Adresse des Datenpuffers
n, // Anzahl der zu lesenden Bytes
&NumberOfBytesRead, // Adresse, an die der Wert geschrieben wird
0); // kein overlapped I/O

if (!b)
ShowLastError("ReceiveData");
return NumberOfBytesRead;
}


void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
const int BufSize = 3;
char Buffer[BufSize]; // address of buffer that receives data
DWORD NumberOfBytesRead=ReceiveData(Buffer,BufSize);
if (NumberOfBytesRead > 0)
{
AnsiString s;
for (DWORD i=0;i<NumberOfBytesRead;i++)
s=s+Buffer[i];
Memo1->Lines->Add("Gelesen n="+IntToStr(NumberOfBytesRead)+" ch="+s);
}
else
{
Memo1->Lines->Add("Nichts empfangen");
}
}

void __fastcall TForm1::BEmpfangClick(TObject *Sender)
{
if (Timer1->Enabled)
{
Timer1->Enabled =false;
BEmpfang->Caption="Read-Timer disabled";
}
else
{
Timer1->Enabled=true;
BEmpfang->Caption="Read-Timer aktiv";
};
}

05.11.2004, 17:06
Welcher Compiler?

Könnte dir bei VC++ aushelfen, andernfalls sieht es mau aus. Schon mal bei codeproject.com nach Inspiration gesucht oder die MSDN konsultiert?

Der Vorteil an einem PHP Forum ist, dass man den Code NICHT als Text einfügen muss, sondern Codeabschnitte definieren kann. Das gestaltet dank Syntax-Highlighting die Fehlersuche ungemein.

05.11.2004, 18:19
XP ist bei COM und LPT zugriffen etwas happig (privilegien)
Versuchs mal mit W98 oder so. :-)

05.11.2004, 21:48
Das ist falsch, mit einer geeigneten Klasse stellt das überhaupt kein Problem ein. Diese stellt die benötigten Funktionen zur Verfügung. Das ist die Programmierung auf dem PC genauso einfach wie auf dem MC!
Im Jahr 2004 anzufangen, ein Programm in Richtung DOS auszurichten, halte ich für den falschen Weg.

NumberFive
07.11.2004, 16:09
Hallo Ehrlich gesagt kann ich kein fehler ent denken ?

Hänge dir mal mein VC++ code an die post der Tut.

Hast du vielleicht an der Com noch was anderes dran hängen Modem oder so was zum test zeit punkt benutzt wird ? Fax Software ?

Gruß

Das projeckt schike ich dir nicht da es ein VC++ projekt ist