COM(RS-232) Schnittstelle!!!



  • Ich habe folgendes Problem....

    Ich versuche mit der RS232 Schnittstelle Daten von einem Gerät zu empfangen.
    Was auch fast 😉 wunderbar klappt.
    Das Datenprotokoll vom Gerät:
    -ein kontinuierlicher Datenstrom
    -8 Datenbits(das erste Bit gibt an ,ob es sich um ein Low-Byte handelt oder um ein High-Byte)
    -Baud 9600
    -keine Parität
    -1 Stopp Bit.

    Die Informationen sind auf 2 Bytes verteilt... und da liegt auch das Problem ich empfange jeweils nur das low-Byte von dem Datenstrom. Aber ich weiß ,dass das Gerät funktioniert ,weil das HyperTerminal(Windows-Programm) den richtigen Datenstrom bekommt ,also low und high Byte.

    Meine Frage ist jetzt ,ob vielleicht jemand weiß warum ich nur ein low-Byte von den 2 Bytes empfange. Und das ich nur die RS232-Konfiguration ändern muss.

    Jetzige Konfiguration

    dcb.BaudRate          = CBR_9600 ;
    dcb.ByteSize          = 8;
    dcb.Parity            = NOPARITY;
    dcb.StopBits          = ONESTOPBIT;
    

    MFG



  • Zunächst mal musst Du den DCB vollständig initialisieren, eben so, wie Du es benötigst. Wenn es dann noch immer nicht funktioniert, machst Du beim Lesen oder der folgenden Auswertung einen Fehler.



  • Hallo,

    also ein bißchen mehr Code als nur die Initialisierung um den dcb-Block herum wäre nicht schlecht, meinst Du nicht auch?
    Hier ist glaube ich noch keiner als Hellseher aufgefallen. 🙄



  • klar bekommt ihr mehr Code 😉

    also falls ihr den Code vollständig haben wollt, ich hab ihn von folgender URL heruntergeladen "http://www.tutorials.de/forum/attachments/visualstudio-mfc/10936d1093967000-serial.zip"

    Hier erstmal die Receivefunktion

    int CSerial::ReadData( void *buffer, int limit )//limit gibt die Maximale Anzahl der zulesenden Bits an 
    {
    	if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );
    
    	BOOL bReadStatus;
    	DWORD dwBytesRead, dwErrorFlags;
    	COMSTAT ComStat;
    
    	ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
    	if( !ComStat.cbInQue ) return( 0 );
    
    	dwBytesRead = (DWORD) ComStat.cbInQue;
    	if( limit < (int) dwBytesRead ) dwBytesRead = (DWORD) limit;
    
    	bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
    	if( !bReadStatus )
    	{
    		if( GetLastError() == ERROR_IO_PENDING )
    		{
    			WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
    			return( (int) dwBytesRead );
    		}
    		return( 0 );
    	}
    	return( (int) dwBytesRead );
    }
    

    und nun der Teil der Erstellung/Konfiguration der Schnittstelle

    BOOL CSerial::Open( int nPort, int nBaud )
    {
    
    	if( m_bOpened ) return( TRUE );
    
    	char szPort[15];
    	char szComParams[50];
    	DCB dcb;
    
    	wsprintf( szPort, "COM%d", nPort );
    
    	m_hIDComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );
    	if( m_hIDComDev == NULL ) return( FALSE );
    
    	memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
     	memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
    
    	COMMTIMEOUTS CommTimeOuts;
    	CommTimeOuts.ReadIntervalTimeout = 200;
    	CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
    	CommTimeOuts.ReadTotalTimeoutConstant = 0;
    	CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
    	CommTimeOuts.WriteTotalTimeoutConstant = 5000;
    	SetCommTimeouts( m_hIDComDev, &CommTimeOuts );
    
    	wsprintf( szComParams, "COM%d:%d,n,8,1", nPort, nBaud );
    
    	m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
    	m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
    
    	dcb.DCBlength = sizeof( DCB );
    	GetCommState( m_hIDComDev, &dcb );
        dcb.BaudRate          = CBR_9600 ;
    	dcb.ByteSize          = 8;
    	dcb.Parity            = NOPARITY;
    	dcb.StopBits          = ONESTOPBIT;
    
    	dcb.fDtrControl = DTR_CONTROL_DISABLE;
        dcb.fRtsControl = RTS_CONTROL_DISABLE;
    
    	if( !SetCommState( m_hIDComDev, &dcb ) ||
    		!SetupComm( m_hIDComDev, 1000, 1000 ))
    	{
    
    		DWORD dwError = GetLastError();
    		if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
    		if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
    		CloseHandle( m_hIDComDev );
    
    		cout << "dwError:" << dwError << endl;
    		return( FALSE );
    	}
    
    	m_bOpened = TRUE;
        cout << szPort <<"wurde geoeffnet" << endl;
    	return( m_bOpened );
    
    }
    

    Zum Schluss der Teil ,mit dem ich die ankommenden Daten verarbeite

    if( Serial.Open(1,9600) == 0)
    	{
            system("pause");	
    		return 0;
    	}
    	while(!abbruch)
    	{
    		//Sleep(100);
    	  Serial.ReadDataWaiting();
    	  Serial.ReadData(&Data,8);
    	  if(Data)
    	  {
    		  if(flag == false)
    		   {
                  if((Data & 0x01) == 0)
    			  {
    				  cout << "LOW" << endl;
                      Messwert = (Data & 0xFE) >> 1;
    			      flag = true;
    			  }
    		   }
    		   else
    		   {
    		      if((Data & 0x01) == 1) //Diesen Teil hat es leider noch nie erreicht  :( 
    			  {
    				  cout << "HIGH" << endl;
                      Messwert |= ((Data & 0xFE) << 6);
    				  Output = Messwert ;
    				  cout << "Output:" << Output << endl;
    
    				  //system("pause");
    				  Sleep(100);
    				  flag = false;
    				  Messwert = 0;
    			  }
    
    		   }
    	  }
       }
    

    Danke für den Tipp Gästchen gleich mal ausprobieren!!!!!



  • Hallo,

    ich denke, dass Dein Beitrag unter MFC besser aufgehoben wäre.



  • Okay ich habe jetzt alle Ellemente der Struktur initalisiert!!!

    dcb.BaudRate          = CBR_9600 ;
    	dcb.ByteSize          = DATABITS_8;
    	dcb.Parity            = NOPARITY;
    	dcb.StopBits          = ONESTOPBIT;
        dcb.fBinary           = true;/* Binary Mode (skip EOF check)    */
        dcb.fParity           = 0x00;/* Enable parity checking          */
        dcb.fOutxCtsFlow      = 0x00;/* CTS handshaking on output       */
        dcb.fOutxDsrFlow      = 0x00;/* DSR handshaking on output       */
        dcb.fDtrControl       = 0x00;/* DTR Flow control                */
        dcb.fDsrSensitivity   = 0x00;/* DSR Sensitivity              */
        dcb.fTXContinueOnXoff = 0x00;/* Continue TX when Xoff sent */
        dcb.fOutX             = 0x00;/* Enable output X-ON/X-OFF        */
        dcb.fInX              = 0x00;/* Enable input X-ON/X-OFF         */
        dcb.fErrorChar        = 0x00;/* Enable Err Replacement          */
        dcb.fNull             = 0x00;/* Enable Null stripping           */
        dcb.fRtsControl       = 0x00;/* Rts Flow control                */
        dcb.fAbortOnError     = 0x00;/* Abort all reads and writes on Error */
        dcb.fDummy2           = 0x00;/* Reserved                        */
        dcb.wReserved         = 0x00;/* Not currently used              */
        dcb.XonLim            = 0x00;/* Transmit X-ON threshold         */
        dcb.XoffLim           = 0x00;/* Transmit X-OFF threshold        */
        dcb.XonChar           = 0x00;/* Tx and Rx X-ON character        */
        dcb.XoffChar          = 0x00;/* Tx and Rx X-OFF character        */
        dcb.ErrorChar         = 0x00;/* Error replacement char          */
        dcb.EofChar           = 0x00;/* End of Input character          */
        dcb.EvtChar           = 0x00;/* Received Event character        */
        dcb.wReserved1        = 0x00;/* Fill for now.                   */
    

    funktioniert leider noch nicht ,trotzdem danke!!!!

    Könnte ein Admin bitte den Thread in das MFC Forum verschieben. Danke!!!!

    MFG



  • EDIT: sorry, war unsinn



  • Versuchsaufbau:

    - 1:1-Kabel SubD9 (= PC) auf SubD25 (= Peripherie)
    - Schnittstellentester
    - eine aufgebogene Büroklammer von Pin 2 auf Pin 3
    - ein PC

    Das Alles ist noch nicht ganz fertig, aber rennt schon gut.

    Die Klasse:

    Der Header (*.h):

    #pragma once
    
    #include "windows.h"
    
    //buffer and protocol sizes
    #define	SIZE_DATA			(const DWORD)(65536)
    #define	SIZE_HEADER			(const DWORD)(4)
    #define	SIZE_BUFFER			(const DWORD)(SIZE_DATA + SIZE_HEADER + 2) 
    
    //thread exitcodes
    #define	NUM_COMPORTS		(const DWORD)(30)
    #define EXIT_NORMAL			(const DWORD)(0)
    #define	EXIT_TERMINATE		(const DWORD)(1)
    #define EXIT_SUSPENDED		(const DWORD)(2)
    #define	EXIT_EVENT			(const DWORD)(3)
    #define	EXIT_FUNCTION		(const DWORD)(4)
    
    //statemachine code/decode packet
    //protocol: SOH | CMD | NUMH | NUML | Data0 |...| DataN | CRC | EOT 
    //crc = 0 - (CMD + NumHigh + NumLow + Data0 + ... + DataN)
    
    #define	STATE_IDLE			(const DWORD)(0)
    #define	STATE_HEADER		(const DWORD)(1)
    #define	STATE_DATA			(const DWORD)(2)
    #define	STATE_CRC_EOT		(const DWORD)(3)
    #define STATE_ERROR			(const DWORD)(4)
    #define	STATE_SUCCESS		(const DWORD)(5)
    
    //control bytes
    #define	SOH					(const BYTE)(0x01)
    #define	EOT					(const BYTE)(0x04)
    
    //----------------------------------------
    
    class ComPort
    {
    private:
    
    	struct TOverlapped : OVERLAPPED
        {
            TOverlapped(ComPort* instance) : m_instance(instance) { }
            ComPort* m_instance;
        }; 
    
    	TOverlapped				*m_ovlRead,*m_ovlWrite;
    	HANDLE					m_hCom;
    	HANDLE					m_hReader, m_hWriter;	//threads
    	COMMCONFIG				m_cc, m_ccBackup;
    	COMMTIMEOUTS			m_cto, m_ctoBackup;
    	DWORD					m_idReader, m_idWriter;
    	DWORD					m_exitReader, m_exitWriter;
    	DWORD					m_stateRead;
    	BOOL					m_runReader, m_runWriter;
    	LPVOID					m_bufferWrite;
    	BYTE					m_headerPreRead[4],m_headerPostRead[2];
    	BYTE					m_crcRead;
    	BYTE					*m_dataRead, *m_dataWrite;
    	BYTE					m_cmdRead;
    	ULONG					m_numRead, m_numWrite;
    
    	static DWORD WINAPI		Reader(LPVOID instance);
    	static DWORD WINAPI		Writer(LPVOID instance);
    
        static void CALLBACK	CompletionReader(DWORD error,DWORD received,OVERLAPPED* ovl);
    	static void CALLBACK	CompletionWriter(DWORD error,DWORD transfered,OVERLAPPED* ovl);
    
    public:
    	ComPort(void);
    	~ComPort(void);
    	BOOL				Open(VOID);
    	BOOL				Close(VOID);
    	BOOL				Write(void *bufferWrite,USHORT *numWrite);
    	BOOL				Read(void *bufferRead,USHORT *numRead, BYTE cmd);
    };
    

    Die Implementation (*.cpp):

    #include "comport.h"
    #include "string.h"
    #include "stdio.h"
    
    //--------------------------------------------------------
    
    DWORD WINAPI ComPort::Writer(LPVOID instance)
    {
    	TOverlapped *ovlWrite = static_cast<TOverlapped*>(instance);
    
    	printf("writer thread enter\n");
    
    	PurgeComm(ovlWrite->m_instance->m_hCom, PURGE_TXCLEAR|PURGE_TXABORT);
    
    	SuspendThread(ovlWrite->m_instance->m_hWriter);
    
    	while (ovlWrite->m_instance->m_runWriter)
    	{
    		ovlWrite->Internal = 0;
    		ovlWrite->InternalHigh = 0;
    		ovlWrite->Offset = 0;
    		ovlWrite->OffsetHigh = 0;
    
    		WriteFileEx(ovlWrite->m_instance->m_hCom,
    					ovlWrite->m_instance->m_bufferWrite,
    					ovlWrite->m_instance->m_numWrite,
    					static_cast<OVERLAPPED*>(ovlWrite),
    					ovlWrite->m_instance->CompletionWriter);
    
    		SleepEx(INFINITE,true);
    
    		SuspendThread(ovlWrite->m_instance->m_hWriter);
    	}
    
    	printf("writer thread leave\n");
    
    	return EXIT_NORMAL;
    }
    
    //--------------------------------------------------------------------------
    
    VOID CALLBACK ComPort::CompletionWriter(DWORD error,DWORD transferred,OVERLAPPED *ovl)
    {
    	printf("writer completion transferred: %d\n",transferred);
    
    }
    
    //--------------------------------------------------------------------------
    
    BOOL ComPort::Write(LPVOID bufferWrite, USHORT *numWrite)
    {
    	if (  (m_hWriter == NULL)
    		||(bufferWrite == NULL)
    		||(*numWrite == 0)	)
    	{
    		*numWrite = 0;
    		return false;
    	}
    
    	m_bufferWrite = bufferWrite;
    	m_numWrite = *numWrite;
    
    	return ResumeThread(m_hWriter);
    }
    
    //--------------------------------------------------------------
    
    VOID CALLBACK ComPort::CompletionReader(DWORD error,DWORD received,OVERLAPPED *ovl)
    {
    	TOverlapped	*ovlRead = static_cast<TOverlapped*>(ovl);
    	DWORD		i;
    
    	printf("reader completion received: %d\n",received);
    
    	switch (ovlRead->m_instance->m_stateRead)
    	{
    		case STATE_HEADER:
    			printf("reader completion header\n");
    
    			if (ovlRead->m_instance->m_headerPreRead[0] == SOH)
    			{
    				ovlRead->m_instance->m_cmdRead = ovlRead->m_instance->m_headerPreRead[1];	//load CMD-Byte
    				ovlRead->m_instance->m_numRead = ovlRead->m_instance->m_headerPreRead[2];	//load NUMH-Byte
    				ovlRead->m_instance->m_numRead <<= 8;
    				ovlRead->m_instance->m_numRead += ovlRead->m_instance->m_headerPreRead[3];	//load NUML-Byte
    				ovlRead->m_instance->m_dataRead = new BYTE[ovlRead->m_instance->m_numRead];
    				ovlRead->m_instance->m_crcRead = (BYTE)(0 - (  ovlRead->m_instance->m_headerPreRead[1]
    															 + ovlRead->m_instance->m_headerPreRead[2]
    															 + ovlRead->m_instance->m_headerPreRead[3] ) );
    				ovlRead->m_instance->m_stateRead = STATE_DATA;
    			}
    			else
    			{
    				ovlRead->m_instance->m_stateRead = STATE_ERROR;
    			}
    			break;
    
    		case STATE_DATA:
    			printf("reader completion data\n");
    
    			for (i=0; i<ovlRead->m_instance->m_numRead; i++)
    			{
    				ovlRead->m_instance->m_crcRead -= (BYTE) ovlRead->m_instance->m_dataRead[i];
    			}
    			ovlRead->m_instance->m_stateRead = STATE_CRC_EOT;
    
    			break;
    
    		case STATE_CRC_EOT:
    			printf("reader completion crc/eot\n");
    
    			if (ovlRead->m_instance->m_headerPostRead[0] != ovlRead->m_instance->m_crcRead)
    			{
    				printf("reader completion error crc\n");
    			}
    
    			if (ovlRead->m_instance->m_headerPostRead[1] != EOT)
    			{
    				printf("reader completion error eot\n");
    			}
    
    			ovlRead->m_instance->m_stateRead = STATE_HEADER;
    
    			delete[] ovlRead->m_instance->m_dataRead; 
    
    			break;
    
    		default: 
    			printf("reader completion error\n");
    	}
    }
    
    //-------------------------------------------------------
    
    DWORD WINAPI ComPort::Reader(LPVOID instance)
    {
    	TOverlapped *ovlRead = static_cast<TOverlapped*>(instance);
    	COMSTAT		cs;
    	DWORD		eventMask = 0;
    	DWORD		wait = 0;
    	BOOL		result;
    
    	printf("reader thread enter\n");
    
    	PurgeComm(ovlRead->m_instance->m_hCom, PURGE_RXABORT|PURGE_RXCLEAR);
    
    	while (ovlRead->m_instance->m_runReader)
    	{
    		ClearCommError(ovlRead->m_instance->m_hCom,NULL,&cs);
    		if (cs.cbInQue > 0)
    		{
    			ovlRead->Internal = 0;
    			ovlRead->InternalHigh = 0;
    			ovlRead->Offset = 0;
    			ovlRead->OffsetHigh = 0;
    
    			switch (ovlRead->m_instance->m_stateRead)
    			{
    				case STATE_HEADER:
    					printf("reader thread state header\n");
    
    					result = ReadFileEx(ovlRead->m_instance->m_hCom,
    										ovlRead->m_instance->m_headerPreRead,
    										SIZE_HEADER,
    										static_cast<OVERLAPPED*>(ovlRead),
    										ovlRead->m_instance->CompletionReader);
    					break;
    
    				case STATE_DATA:
    					printf("reader thread state data\n");
    
    					ReadFileEx(	ovlRead->m_instance->m_hCom,
    								ovlRead->m_instance->m_dataRead,
    								ovlRead->m_instance->m_numRead,
    								static_cast<OVERLAPPED*>(ovlRead),
    								ovlRead->m_instance->CompletionReader);
    					break;
    
    				case STATE_CRC_EOT:
    					printf("reader thread state crc/eot\n");
    
    					ReadFileEx(	ovlRead->m_instance->m_hCom,
    								&ovlRead->m_instance->m_headerPostRead,
    								2,
    								static_cast<OVERLAPPED*>(ovlRead),
    								ovlRead->m_instance->CompletionReader);
    					break;
    
    				default: ;
    			}
    			result = SleepEx(INFINITE,true);
    		}
    	}
    
    	printf("reader thread leave\n");
    
    	return EXIT_NORMAL;
    }
    
    //-------------------------------------------------------
    
    ComPort::ComPort(void)
    {
    	m_ovlRead = new TOverlapped(this);
    	m_ovlWrite = new TOverlapped(this);
    
    	m_hReader = NULL;
    	m_runReader = true;
    	m_numRead = 0;
    	m_stateRead = STATE_HEADER;
    	m_hWriter = NULL;
    	m_runWriter = true;
    	m_bufferWrite = NULL;
    	m_numWrite = 0;
    
    	m_cc.dcb.DCBlength = sizeof(DCB);
    	m_cc.dcb.BaudRate = CBR_115200;
    	m_cc.dcb.ByteSize = 8;
    	m_cc.dcb.EofChar = '\0';
    	m_cc.dcb.ErrorChar = 'b';//'\0';
    	m_cc.dcb.EvtChar = '\0';
    	m_cc.dcb.fAbortOnError = false;//true;
    	m_cc.dcb.fBinary = true;
    	m_cc.dcb.fDsrSensitivity = false;//true;
    	m_cc.dcb.fDtrControl = DTR_CONTROL_DISABLE;//DTR_CONTROL_HANDSHAKE;
    	m_cc.dcb.fErrorChar = false;
    	m_cc.dcb.fInX = false;
    	m_cc.dcb.fNull = false;
    	m_cc.dcb.fOutX = false;
    	m_cc.dcb.fOutxCtsFlow = false;//true;
    	m_cc.dcb.fOutxDsrFlow = false;//true;
    	m_cc.dcb.fParity = false;//true;
    	m_cc.dcb.fRtsControl = RTS_CONTROL_DISABLE;//RTS_CONTROL_TOGGLE;
    	m_cc.dcb.fTXContinueOnXoff = true;
    	m_cc.dcb.Parity = NOPARITY;
    	m_cc.dcb.StopBits = ONESTOPBIT;
    	m_cc.dcb.XoffChar = '\0';
    	m_cc.dcb.XoffLim = 0;
    	m_cc.dcb.XonChar = '\0';
    	m_cc.dcb.XonLim = 0;
    
    	m_cto.ReadIntervalTimeout = 50;
    	m_cto.ReadTotalTimeoutConstant = 100;
    	m_cto.ReadTotalTimeoutMultiplier = 50;
    	m_cto.WriteTotalTimeoutConstant = 100;
    	m_cto.WriteTotalTimeoutMultiplier = 50;
    }
    
    ComPort::~ComPort(void)
    {
    	delete m_ovlRead;
    	delete m_ovlWrite;
    }
    
    //---------------------------------------------------
    
    BOOL ComPort::Open(void)
    {
    	char	com[NUM_COMPORTS][sizeof("COM99")] = {	"COM1","COM2","COM3","COM4","COM5","COM6",
    													"COM7","COM8","COM9","COM10","COM11","COM12",
    													"COM13","COM14","COM15","COM16","COM17","COM18",
    													"COM19","COM20","COM21","COM22","COM23","COM24",
    													"COM25","COM26","COM27","COM28","COM29","COM30"};
    	int		i;
    	DWORD	size;
    
    	//find port
    	for (i=0; i<NUM_COMPORTS; i++)
    	{
    		m_hCom = CreateFileA(	com[i],
    								GENERIC_READ | GENERIC_WRITE,
    								0,
    								NULL,
    								OPEN_EXISTING,
    								FILE_FLAG_OVERLAPPED,
    								NULL);
    
    		if (m_hCom != INVALID_HANDLE_VALUE)	//take this one
    		{
    			break;
    		}
    	}
    
    	if (m_hCom == INVALID_HANDLE_VALUE)	//found comport?
    	{
    		return false;
    	}
    
    	//Save former config settings
    	m_ccBackup.dwSize = sizeof(COMMCONFIG);
    	m_ccBackup.dcb.DCBlength = sizeof(DCB);
    	if (!GetCommConfig(m_hCom,&m_ccBackup,&size))
    	{
    		return false;
    	}
    
    	if (m_ccBackup.dwProviderSubType != PST_RS232)	//not a RS232 provider
    	{
    		return false;
    	}
    
    	m_cc.dwProviderOffset = m_ccBackup.dwProviderOffset;
    	m_cc.dwProviderSize = m_ccBackup.dwProviderSize;
    	m_cc.dwProviderSubType = m_ccBackup.dwProviderSubType;
    	m_cc.dwSize = sizeof(COMMCONFIG);
    	strcpy_s((char*)m_cc.wcProviderData,sizeof(m_cc.wcProviderData),(char*)&m_ccBackup.wcProviderData);
    	m_cc.wReserved = m_ccBackup.wReserved;
    	m_cc.wVersion = m_ccBackup.wVersion;
    
    	m_cc.dcb.DCBlength = sizeof(DCB);
    	if (!SetCommConfig(m_hCom,&m_cc,sizeof(COMMCONFIG)))
    	{
    		return false;
    	}	
    
    	//save former timeout settings
    	if (!GetCommTimeouts(m_hCom,&m_ctoBackup))
    	{		
    		return false;		
    	}	
    
    	if (!SetCommTimeouts(m_hCom,&m_cto))
    	{
    		return false;
    	}	
    
    	//create workerthread write
    	m_hWriter = CreateThread(	NULL,
    								0,
    								ComPort::Writer,
    								(LPVOID)m_ovlWrite,
    								0,
    								&m_idWriter);
    	if (m_hWriter == NULL)
    	{
    		return false;
    	}
    
    	//create workerthread read
    	m_hReader = CreateThread(	NULL,
    								0,
    								ComPort::Reader,
    								(LPVOID)m_ovlRead,
    								0,
    								&m_idReader);
    	if (m_hReader == NULL)
    	{
    		return false;
    	}
    
    	return true;
    }
    
    //-----------------------------------------
    
    BOOL ComPort::Close(void)
    {
    	DWORD	wait;
    
    	//evtl. warten bis threadaktionen abgeschlossen sind
    
    	//close writer thread
    	m_runWriter = false;
    	ResumeThread(m_hWriter);
    
    	wait = WaitForSingleObject(m_hWriter, 10000);
    	switch (wait)
    	{
    		case WAIT_OBJECT_0:
    		case WAIT_ABANDONED:
    			break;
    		case WAIT_TIMEOUT:
    			TerminateThread(m_hWriter,EXIT_TERMINATE);
    			break;
    		default: ;//WAIT_FAILED
    	}
    
    	GetExitCodeThread(m_hWriter,&m_exitWriter);
    
    	switch (m_exitWriter)
    	{
    		case EXIT_NORMAL:
    			printf("writer exit normal\n");
    			break;
    		case EXIT_SUSPENDED:
    			printf("writer exit suspended\n");
    			break;
    		case EXIT_TERMINATE:
    			printf("writer exit terminate\n");
    			break;
    		case EXIT_EVENT:
    			printf("writer exit event\n");
    			break;
    		case EXIT_FUNCTION:
    			printf("writer exit function\n");
    			break;
    		default:;
    	}
    
    	CloseHandle(m_hWriter);
    	m_hWriter = NULL;
    
    	//close reader thread
    	m_runReader = false;
    	ResumeThread(m_hReader);
    
    	wait = WaitForSingleObject(m_hReader, 10000);
    	switch (wait)
    	{
    		case WAIT_OBJECT_0:
    		case WAIT_ABANDONED:
    			break;
    		case WAIT_TIMEOUT:
    			TerminateThread(m_hReader,EXIT_TERMINATE);
    			break;
    		default: ;//WAIT_FAILED
    	}
    
    	GetExitCodeThread(m_hReader,&m_exitReader);
    
    	switch (m_exitReader)
    	{
    		case EXIT_NORMAL:
    			printf("reader exit normal\n");
    			break;
    		case EXIT_SUSPENDED:
    			printf("reader exit suspended\n");
    			break;
    		case EXIT_TERMINATE:
    			printf("reader exit terminate\n");
    			break;
    		case EXIT_EVENT:
    			printf("reader exit event\n");
    			break;
    		case EXIT_FUNCTION:
    			printf("reader exit function\n");
    			break;
    		default:;
    	}
    
    	CloseHandle(m_hReader);
    	m_hReader = NULL;
    
    	//restore COMMCONFIG
    	if (!SetCommConfig(m_hCom,&m_ccBackup,sizeof(m_ccBackup)))
    	{
    		MessageBoxA(NULL,"Restoring settings failed","COM",MB_OK);
    		return false;
    	}
    
    	//restore COMMTIMEOUTS
    	if (!SetCommTimeouts(m_hCom,&m_ctoBackup))
    	{
    		MessageBoxA(NULL,"Restoring timeouts failed","COM",MB_OK);
    		return false;
    	}
    
    	//close "classglobal" handle
    	CloseHandle(m_hCom);
    	m_hCom = INVALID_HANDLE_VALUE;
    
    	return true;
    }
    

    Die Test-Konsole (VS08 EE):

    // test.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
    //
    
    #include "stdafx.h"
    #include "../../classes/comport.h"
    
    UCHAR	g_bufRead[1024] = {0};
    UCHAR	g_bufWrite[1024] = {0};
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	USHORT	num = 8;
    	ComPort	*com = new ComPort();
    
    	com->Open();
    
    	Sleep(2000);
    
    	g_bufWrite[0] = 1;		//SOH
    	g_bufWrite[1] = 12;		//CMD
    	g_bufWrite[2] = 0;		//NUMH
    	g_bufWrite[3] = 2;		//NUML
    	g_bufWrite[4] = 0;
    	g_bufWrite[5] = 1;
    	g_bufWrite[6] = 241;	//CRC
    	g_bufWrite[7] = 4;		//EOT
    
    	com->Write((LPVOID)g_bufWrite,&num);
    
    	Sleep(5000);
    
    	com->Close();
    
    	printf("prog end\n");
    	getchar();
    	return 0;
    }
    

    Wenn es konstruktive Kritik an dem, was schon fertig ist geben sollte, bin ich für jeden Denkanstoss dankbar!

    Gruss

    Lars



  • gargamel schrieb:

    wsprintf( szPort, "COM%d", nPort );
    

    Dieser Teil ist schon mal falsch. Richtig muss es heißen:

    wsprintf( szPort, "\\\\COM%d", nPort );
    

    Das Problem tritt zwar erst mit nummern > 9 auf, aber da kommt man dank zahlreicher USB <-> RS232 Umsetzern, Bluetooth und was weiß ich schnell hin. Siehe: HOWTO: Specify Serial Ports Larger than COM9

    gargamel schrieb:

    Serial.ReadData(&Data,8);
    	  if(Data)
    	  {
    		  if(flag == false)
    		   {
                  if((Data & 0x01) == 0)
    

    Ich habe keine Iddee, was Data ist. Ein einzelnes Byte kann es nicht sein, da Du ja Platz für bis zu 8 Zeichen hast (int limit = 8). So, wie es aussieht, ist es ein Pointer auf die gelesenen Daten. Von daher denke ich, dass das so sinnvoller ist:

    if((*Data & 0x01) == 0)
    
    // Oder
    
    if((Data[0] & 0x01) == 0)
    

    Dann wirst Du Data auch irgendwann einmal inkrementieren müssen, um an das nächste empfangende Byte zu kommen. Ansonsten fragst Du grunsätzlich nur das erste Byte ab und landest dann selbstverständlich nie in Deinem zweiten Teil.

    Allerdings ignorierst Du den Rückgabewert von ReadData. Woher weißt Du denn jetzt eigentlich, wie viele der 8 Bytes für Dich interessant sind?



  • Gästchen schrieb:

    gargamel schrieb:

    wsprintf( szPort, "COM%d", nPort );
    

    Dieser Teil ist schon mal falsch. Richtig muss es heißen:

    wsprintf( szPort, "\\\\COM%d", nPort );
    

    Das Problem tritt zwar erst mit nummern > 9 auf, ...

    "\\\COM%d" ist genauso falsch, richtig muss es "\\\.\\COM%d" heissen.



  • hustbaer schrieb:

    "\\\COM%d" ist genauso falsch, richtig muss es "\\\.\\COM%d" heissen.

    Auweia, das ist natürlich richtig. Immerhin habe ich den Link richtig gesetzt, damit wiegt der Bock hoffentlich nicht mehr ganz so schwer. 🙂



  • ^^ okay hab den Fehler gefunden ... mal wieder ein sch... Fehler , ich hab immer nur ein char also ein Byte in die Read-Funktion gegeben...

    Musste einfach nur char Data[2] in die Funktion geben und tada die richtigen Daten

    Vielen Dank ... durch eure Hilfe wär ich nie auf das Problem gestossen 😃


Anmelden zum Antworten