-         

Ergebnis 1 bis 4 von 4

Thema: Befehle per USART empfangen

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    29.05.2004
    Ort
    Zuhause
    Alter
    30
    Beiträge
    28

    Befehle per USART empfangen

    Anzeige

    Hi,
    ich versuche grad meinen µC(ATmega169, butterfly) per USART zu steuern, dabei sollen die Befehle nach jeder neuen Zeile interpretiert werden.
    Ich habe dass problem dass in meinem Code anscheinend die Bedingung
    Code:
    if(data == '\n')
    nie erfüllt wird, hat jemand eine Idee woran dass liegen könnte?

    Code:
    SIGNAL( SIG_USART_RECV )
    {
    	unsigned char data;
    	data = UDR;
    	
    	/* echo */
    	UDR = data; 
    
    	usart_pos++;
    	
    	if(data == '\n')
    	{
    		usart_buffer[usart_pos] = '\0';
    		LCD_puts(usart_buffer,0);
    		
    		/* Parse command */
    		if(sscanf(usart_buffer, "INTERVAL %d", &interval) == 0 )
    				USART_puts("COMMAND NOT UNDERSTOOD\r\n");
    	
    		
    		/* reset the buffer & pos */
    		usart_buffer[0] = '\0';
    		usart_pos = 0;
    	} else {
    		usart_buffer[usart_pos] = data; /* append received char*/
    	}
    }
    P.S. Ich verwende als Terminal minicom.

  2. #2
    Neuer Benutzer Öfters hier
    Registriert seit
    29.05.2004
    Ort
    Zuhause
    Alter
    30
    Beiträge
    28
    Hat sich erledigt, der fehler lag darin dass usart_buffer[0] nie etwas anderes als '\0' zugewiesen bekam (das usart_pos++ gehört ans ende des unteren else

    thx trotzdem

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.01.2005
    Ort
    Bayern
    Alter
    31
    Beiträge
    795
    Hallo,

    Zum Thema USART Befehle Empfangen habe ich mir Folgendes Ausgedacht:

    Man überlegt sich zunächst wie man seine Befehle Sendet.
    Also eine art Protokoll.

    Bei mir ist das Folgendermaßen:

    1. Ein Zeichen, welches für den Beginn eines neuen Befehlspaketes symbolisiert
    2. die länge der Nachfolgenden Bytes
    4. X-Bytes

    Als Startzeichen habe ich mit ESC ausgesucht. Hat den ASCII-Code 0x1B.



    Allgemein ist bekannt, dass es nicht so hinhaut die einkommenden Befehle direkt zu bearbeiten. also schreibe ich die empfangenen Zeichen in einen Puffer.
    Da das Befehlspaket ein Startzeichen hat ( ESC hier ), und mir dann gleich die Länge übermittelt ist das ja ein Kinderspiel, die Daten in einen Puffer zu schreiben.

    Hier der Code. Ich verwende 5 Puffer:

    Code:
    uint8_t UART_buffer0[8];
    uint8_t UART_buffer1[8];
    uint8_t UART_buffer2[8];
    uint8_t UART_buffer3[8];
    uint8_t UART_buffer4[8];
    
    uint8_t *UART_pointer;
    
    
    
    void UART_receive( uint8_t data ){
    	if ( data == ESC ){
    		uint8_t gotone = 0;
    		UART_buffer0[1] = 0;													// Unvollständige verwerfen
    		UART_buffer1[1] = 0;													// Unvollständige verwerfen
    		UART_buffer2[1] = 0;													// Unvollständige verwerfen
    		UART_buffer3[1] = 0;													// Unvollständige verwerfen
    		UART_buffer4[1] = 0;													// Unvollständige verwerfen
    		
    		if( ! UART_buffer4[0] ){ UART_pointer = UART_buffer4; gotone = 1; }	// Nimm Puffer 4 wenn er frei ist
    		if( ! UART_buffer3[0] ){ UART_pointer = UART_buffer3; gotone = 1; }	// Nimm Puffer 3 wenn er frei ist
    		if( ! UART_buffer2[0] ){ UART_pointer = UART_buffer2; gotone = 1; }	// Nimm Puffer 2 wenn er frei ist
    		if( ! UART_buffer1[0] ){ UART_pointer = UART_buffer1; gotone = 1; }	// Nimm Puffer 1 wenn er frei ist
    		if( ! UART_buffer0[0] ){ UART_pointer = UART_buffer0; gotone = 1; }	// Nimm Puffer 0 wenn er frei ist
    		
    		if( gotone ){ 
    			UART_pointer[1] = 1; 												// Markiere den gewählten Puffer
    			UART_pointer[2] = 0; 												// Leeren
    			UART_pointer[3] = 0; 												// Leeren
    			UART_pointer[4] = 0; 												// Leeren
    			UART_pointer[5] = 0; 												// Leeren
    			UART_pointer[6] = 0; 												// Leeren
    			UART_pointer[7] = 0; 												// Leeren
    		}	
    	} else {
    		if( UART_pointer[1] ){													// Nur in Puffer schreiben, wenn er in Bearbeitung ist!
    			
    			UART_pointer[ UART_pointer[2] + 3 ] = data;
    			
    			UART_pointer[2]++;													// Füllzähler hochaddieren
    			if( UART_pointer[3] && (UART_pointer[2] > (UART_pointer[3]+1)) ){
    				UART_pointer[1] = 0;											// Puffer aus Bearbeitung entfernen
    				UART_pointer[0] = 1;											// Puffer als VOLL markieren
    			}
    		}
    	}
    }
    [0] = Puffer ist Volol
    [1] = Puffer in Arbeit
    [2] = Selbstgezählte
    [3] = Empfangene Längenangabe
    [4] = Databyte 1
    [5] = Databyte 2
    [6] = Databyte 3
    [7] = Databyte 4


    Die routine wird mit UART-Interrupt ausgeführt.

    Als erstes wird nach einem Freien bzw. schon gelesenen Puffer gesucht
    ( schaun ob BufferXXX[0] = 0 ist. )

    Wurde einer gefunden, dann wird einen zeiger Drauf!

    Dann wird dieser als "in Bearbeitung markiert." und eventuell vorher fehlerhafte IN BEARBEITUNG werden verworfen.
    demnach gibt es immer nur EINEN Puffer, der in bearbeitung ist.


    sind so viele Bytes empfangen wie es das Längenbyte angab, so wird der pufer aus der Bearbeitung entfernt BufferXX[1]=0 und als VOLL markiert: BuufferXX[0] = 1.




    Dieser kann dann bequem von einer anderen Funktion Verarbeitet werden. Das ganze verschafft mehr zeit zum verarbeiten!
    Funktioniert bei mir einwandfrei. Hab diesen code ein wenig zugeschnitten, da ich selbst ein bisschen ein anderes "Protokoll"habe, aber dieses ist das beste meiner meinung nach.

    Ich hoffe jemand findet Gebrauch dafür!
    Gruß,
    Franz

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    27.10.2005
    Beiträge
    48
    Hallo !

    Ich habe ein ähnliches Problem in
    http://www.roboternetz.de/phpBB2/viewtopic.php?t=14408
    gepostet.
    Vielleicht kann jemand helfen ?

    Grüsse,

    Markus

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •