Senden und empfangen mit serieller Schnittstelle



  • Hallo,

    ich versuche ein Programm zu schreiben, dass auf der seriellen Schnittstelle auf eine Nachricht wartet und Sie beantwortet. Die Quelle ist hierbei eine selbstgebaute ATmega8 Schaltung. Da ich nur senden und empfangen will habe ich das ganze Geraffel wie Handshake etc. komplett ignoriert und nur die Sende- und Empfangsleitung und Masse verbunden.
    Was muss ich mit den anderen Leitungen machen?

    Das Programm funktioniert, wenn ich mit HyperTerminal sende. Ich bekomme auch die korrekte Antwort. Verwende ich meine ATmega bekomme ich die Antwort mehrmals.

    Weiß jemand Rat?

    Grüße



  • wie kommunizierst du mit dem atmega ? direkt oder über infrarot, wie realisierst du das senden auf dem atmega ? ich spiel hier atm mit nem asuro roboter (atmega8) rum, aber wenn ich den atmega nach dem senden nicht die chance gebe den puffer zu leeren, kann es sein ds das letzte gesendete zeichen gleich wieder im empfang landet ... komm mal mit mehr informationen, dann könnt ich dir evtl. helfen



  • Ich sende die einfach das Programm. Wenn ich auf den angeschlossenen Taster drücke sendet er mir die Zustände des Tasters über die Schnittstelle. Die angeschlossenen LEDs werden über zwei Zeichen geschaltet die er als Antwort erwartet.

    Programm ATmega:

    /*************************************************************************
    Title:    example program for the Interrupt controlled UART library
    Author:   Peter Fleury <pfleury@gmx.ch>   http://jump.to/fleury
    File:     $Id: test_uart.c,v 1.4 2005/07/10 11:46:30 Peter Exp $
    Software: AVR-GCC 3.3
    Hardware: any AVR with built-in UART, tested on AT90S8515 at 4 Mhz
    
    DESCRIPTION:
    This example shows how to use the UART library uart.c
    
    *************************************************************************/
    /* define CPU frequency in Mhz here if not defined in Makefile */
    #ifndef F_CPU
    #define F_CPU 7372800UL
    #endif
    
    #include <stdlib.h>
    #include <avr/io.h>
    #include <avr/interrupt.h>
    //#include <avr/signal.h>
    #include <avr/pgmspace.h>
    
    #include <uart/uart.h>
    #include <GPACheader.h>
    #include <util/delay.h>
    
    /* 9600 baud */
    #define UART_BAUD_RATE      9600
    
    int main(void)
    {
    
    	unsigned int c;
    	unsigned int T2 = 0, T3 = 0;
    
    	unsigned int byte = 0;
    	unsigned char a,b,d;
    
    	DDRB &= ~( 1<< PB2);
    
    	DDRB = 0xB9;//PORTB als Ausgang setzen
    	DDRC = 0xaf;//PORTC als Ausgang setzen
    	DDRD = 0xfc;//PORTD als Ausgang setzen
    
    	innen(0,0,0,0,0,0);
    	aussen(0,0,0,0,0,0);
    	LEDred(0);
    	LEDyellow(0);
    	LEDgreen(0);
    
    	//char buffer[7];
    	//int  num=134;
    
    	/*
    	*  Initialize UART library, pass baudrate and AVR cpu clock
    	*  with the macro 
    	*  UART_BAUD_SELECT() (normal speed mode )
    	*  or 
    	*  UART_BAUD_SELECT_DOUBLE_SPEED() ( double speed mode)
    	*/
    	uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
    
    	/*
    	* now enable interrupt, since UART library is interrupt controlled
    	*/
    	sei();
    
    	/*
    	*  Transmit string to UART
    	*  The string is buffered by the uart library in a circular buffer
    	*  and one character at a time is transmitted to the UART using interrupts.
    	*  uart_puts() blocks if it can not write the whole string to the circular 
    	*  buffer
    	*/
    	//uart_puts("String stored in SRAM\n");
    
    	/*
    	* Transmit string from program memory to UART
    	*/
    	uart_puts_P("\nGPAC Steuerung bereit\n");
    
    	/* 
    	* Use standard avr-libc functions to convert numbers into string
    	* before transmitting via UART
    	*/     
    	//itoa( num, buffer, 10);   // convert interger into string (decimal format)         
    	//uart_puts(buffer);        // and transmit string to UART
    
    	/*
    	* Transmit single character to UART
    	*/
    	uart_putc('\r');
    
    	for(;;)
    	{
    		//Taster 2 entprellen
    		if (debounce(&PINB, PB2))             //Taster 2, Falls Taster an PIN PB2 gedrueckt..
    		{
    			T2 = !T2;
    			LEDred(T2 & 0x0001);
    		}
    		else{}
    
    		//Taster 3 entprellen
    		if( debounce(&PINB,PB1))
    		{
    			T3 = !T3;
    			LEDgreen(T3 & 0x0001);
    			uart_putc(PINB & 0x06);
    
    		}
    		else
    		{}
    
    		/*
    		* Get received character from ringbuffer
    		* uart_getc() returns in the lower byte the received character and 
    		* in the higher byte (bitmask) the last receive error
    		* UART_NO_DATA is returned when no data is available.
    		*
    		*/
    		c = uart_getc();
    		if ( c & UART_NO_DATA )
    		{
    			/* 
    			* no data available from UART 
    			*/
    		}
    		else
    		{
    			/*
    			* new data available from UART
    			* check for Frame or Overrun error
    			*/
    			if ( c & UART_FRAME_ERROR )
    			{
    				/* Framing Error detected, i.e no stop bit detected */
    				uart_puts_P("UART Frame Error: ");
    			}
    			if ( c & UART_OVERRUN_ERROR )
    			{
    				/* 
    				* Overrun, a character already present in the UART UDR register was 
    				* not read by the interrupt handler before the next character arrived,
    				* one or more received characters have been dropped
    				*/
    				uart_puts_P("UART Overrun Error: ");
    			}
    			if ( c & UART_BUFFER_OVERFLOW )
    			{
    				/* 
    				* We are not reading the receive buffer fast enough,
    				* one or more received character have been dropped 
    				*/
    				uart_puts_P("Buffer overflow error: ");
    			}
    			/* 
    			* send received character back
    			*/
    			if( ( c & 0xff00 ) == 0 )
    			{
    
    				if( PINB & (1 << PB1) )
    				{
    
    					if( ((unsigned char)c & 0x00ff) == 0x007e)
    					{
    						byte = 0;
    						innen(1,1,1,1,1,1);
    						aussen(1,1,1,1,1,1);
    //						LEDred(1);
    //						LEDyellow(1);
    //						LEDgreen(1);
    					}
    					else
    					{
    
    						if(byte == 0)
    						{			
    							a = (unsigned char)c;
    							byte++;
    							c = 0;
    						}
    						/*					else if(byte == 1)
    						{
    
    						byte++;
    						c = 0;
    						}*/
    						else if(byte == 1)
    						{
    							b = (unsigned char)c;
    							d = (unsigned char)c;
    
    							innen(a & 0x0001,a & 0x0002,a & 0x0004,a & 0x0008,a & 0x0010,a & 0x0020);
    							aussen(b & 0x0001,b & 0x0002,b & 0x0004,b & 0x0008,b & 0x0010,b & 0x0020);
    							//LEDred(d & 0x0001);
    							//LEDyellow(d & 0x0002);
    							//LEDgreen(d & 0x0004);
    
    							//uart_putc(':');
    							//uart_putc(a);
    							//uart_putc(b);
    							uart_putc(PINB & 0x06);
    							//uart_putc( (0x00c0) | (PINB & (1 << PB1)) | (PINB & (1 << PB2)) );
    							//uart_putc(':');
    
    							byte = 0;
    							a = 0;
    							b = 0;
    							c = 0;
    							d = 0;
    						}
    						else{}
    
    					}
    				}
    				else{}
    
    			}
    		}
    
    	}
    
    }
    

    Programm PC. Das seltsame ist, dass das Programm so wie es hier steht funktioniert. Wird die Markierte ZEile (->) aktiviert enpfängt das Programm alles doppelt.

    // GPAC Steuerung.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
    //
    #include "windows.h"
    #include <string>
    #include "iostream"
    //#include "schltxt.h"
    #include "Serial.h"
    #include <tchar.h>
    
    using namespace std;
    
    int main()
    	{
    	CSerial RS;
    
    	struct Stange
    		{
    		double Position;//An welcher Winkelposition liegt die Probe
    		double Stellung;//Ist die Probe aus oder eingefahren
    		bool fertig;//Probe bereit. Probe in oberer Position
    		bool benutzt;//Wurde die Probe schon genommen
    		};
    
    	Stange Probe[6];
    
    	std::string Port("COM5");
    
    	HANDLE RS232;//Handle für die serielle Schnittstelle
    	DWORD dwEvtMask;//Ereignismaske der seriellen Schnittstelle. Was ist passiert
    
    	RS232 = RS.HoleHandle();//Der Handle auf die serielle Schnittstelle wird abgeholt
    	SetCommMask(RS232,EV_RXCHAR);//Windows achtet auf ein neues Zeichen im Datenpuffer der seriellen Schnittstelle EV_RXCHAR
    
    	int portr=1,
    		baudr=9600,
    		bitsr=8,
    		error=0,
    		status = 0;
    
    	long bytesw = 0;
    
    	char rsraw = 0x00;//Rohdaten auf der seriellen Schnittstelle
    	unsigned char rsdata = 0x00;//Daten der Seriellen Schnittstelle
    
    	//Den Datenstring erstellen
    	string data("\xc0\xc0\x00");
    
    	status = RS.Open(portr,baudr,bitsr,NOPARITY,TWOSTOPBITS);
    
    	// Register only for the receive event
    
    	RS232 = RS.HoleHandle();//Der Handle auf die serielle Schnittstelle wird geholt
    	SetCommMask(RS232,EV_RXCHAR);//Windows achtet auf ein neues Zeichen im Datenpuffer der seriellen Schnittstelle EV_RXCHAR
    
    	//system("PAUSE");
    
    	char dataraw = '\x00';
    	if(RS.IsOpen()==TRUE)
    		{
    		cout << "Konfiguration" << endl << "Port: " << portr << endl << "Baudrate: " << baudr << endl << "Bits: " << bitsr << endl << "keine Paritaet, zwei Stoppbits" << endl;
    		do
    			{
    ->			//RS.SendData( data.c_str(),int( strlen( data.c_str() ) ) );
    			data[1]++;
    			data[0]++;
    			if (WaitCommEvent(RS232, &dwEvtMask, NULL)) 
    				{
    				if (dwEvtMask & EV_RXCHAR)
    					{
    					RS.ReadData(&dataraw,1);
    					std::cout << dataraw;
    					//if(!bytesw)
    					//	{
    					//	cout << "Senden OK";
    					//	}
    					//else//!bytesw
    					//	{
    					//	cout << "Fehler beim Senden: " << bytesw << endl;
    					//	}
    
    					}
    				else//(dwEvtMask & EV_RXCHAR)
    					{}
    				}
    			else//(WaitCommEvent(hComm, &dwEvtMask, NULL))
    				{}
    
    			}while(1);
    		}
    	else//RS.open()
    		{
    		std::cout << "Konnte den Port " << portr << " nicht \x94 \bffnen" << std::endl;
    		}
    
    	system("PAUSE");
    	return 0;
    	}
    

    Ich hoffe ich konnte Dir helfen

    Grüße



  • also die atmega seite sieht gut aus ... stellt sich nur die frage, ob du mit IR sendest ?! oder verkabelt arbeitest

    ich weis jetzt nichtgenau was
    uart_putc(PINB & 0x06);

    macht, aber versuch doch auch mal einen string zu senden so von wegen "meine antwort ist: (das zeichen das empfangen wurde)"

    dann sag nochmal was doppelt kommt, die "antwort" oder das "zeichen"

    EDIT: welche lib verwendest du ? ich verwende die mitgelieferte asuro lib, die stellt nur eine methode zur verfügung um ein array zu senden und zu empfangen, deine scheint beides zu können, bytes senden und empfangen als auch arrays


Anmelden zum Antworten