- LiTime Speicher und Akkus         
Ergebnis 1 bis 7 von 7

Thema: Zeichenkette über UART empfangen

  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    17.08.2005
    Alter
    39
    Beiträge
    685

    Zeichenkette über UART empfangen

    Anzeige

    Powerstation Test
    Hallo,

    ich werde noch wahnisinnig bei dieser Programmiersprache. Aber naja, wollte es ja unbedingt wissen....

    Zu meiner Frage:

    Es geht darum, eine Zeichenkette auf einem LCD auszugeben.
    Das senden vom Controller funktioniert mittlerweile einwandfrei (Dank an das Forum und an izaseba).
    Wenn ich nun vom PC zB. "Hallo" sende, kann ich mit dem "Echo-Code" vom Wiki dies problemlos zurückschicken.
    Mich wundert da erstmal schon die Deklaration von bZeichen als char. Wobei "Hallo" ja eigentlich aus 5 Zeichen besteht.

    Die Lib von Peter Fleury ist die Grundlage für's Display und hier ist der wichtige Code-Teil:

    Code:
    void usart_init(void);
    char receive_UART[20]; 
    
    
    int main(void)
    {
         usart_init();
    	 lcd_init(LCD_DISP_ON);        
    	 lcd_clrscr();
    	 while (1) 
    	 { 
    		while ( !(UCSRA & (1 << RXC)) ) 
    		{}	
    		receive_UART[0] = UDR;
    		receive_UART[19] = '\0';
    		lcd_clrscr();
            lcd_gotoxy(0,0);
            lcd_puts(receive_UART);
    	 }
    }
    Ich habe somit in der Variable "receive_UART" Platz für 19 Zeichen, das 20. und somit letzte (19. Stelle) beschließt das Ende der Zeichenkette.

    Jedoch wird nur das letzte empfangene Zeichen ausgegeben.
    Wie funktioniert das UDR - Register, als was wird der Inhalt gespeichert.
    Wenn ein ASCII Code gesendet wurde, müsste dieser ja auch sich dort befinden, zumal ja im Echo Programm mit einer char Variable darauf zugegriffen werden konnte.


    Was mache ich nur falsch, es ist deprimierend.
    Kann mir jemand helfen?

    Gruß
    Stefan

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Beiträge
    2.731
    Hallo,

    ich würde sagen es werden schon alle Zeichen ausgegeben, nur kannst du nicht so schnell schauen, wie die angezeigt werden

    Wie bei einer seriellen Übertragung üblich, kommen die Zeichen eins nach dem anderen, evtl. sollten die Zeichen erst alle in das Array, nach ende der Übertragung auf das LCD geschrieben werden.

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    17.08.2005
    Alter
    39
    Beiträge
    685
    OK, dann werde ich mich mal daran machen.
    Merke, dass das LCD eh sehr langsam ist und meine ganzen Timings durcheinander bringt (muss wirklich vorher die Interrupts ausschalten).

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    17.08.2005
    Alter
    39
    Beiträge
    685
    So, habe arg rumprobiert.
    Heraus gekommen ist ein Teilerfolg.
    Die 1.Eingabe bis '#' wird korrekt ausgegeben.


    Code:
    // includes
    //-----------------------------------------------------
    //-----------------------------------------------------
    
    #include <avr/io.h>
    #include <string.h>
    #include <stdint.h>
    #include <stdlib.h> 
    #include <stdio.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #include "lcd.h"
    
    // Variable
    //-----------------------------------------------------
    //-----------------------------------------------------
    
    char data[20];    // für alle Fälle ausreichend groß
    char c;
    int a=0, s=0, i;
    
    // Prototypen
    //-----------------------------------------------------
    //-----------------------------------------------------
    
    void usart_init(void);
    void string_senden(char *string);
    void zeichen_senden(char zeichen);
    void USART_interrupt (char temp);
    void str_uebergabe (char data[], int a);
    
    // Main
    //-----------------------------------------------------
    //-----------------------------------------------------
    
    int main(void)
    {
         usart_init();
    	 lcd_init(LCD_DISP_ON);        
    	 lcd_clrscr();
    	 lcd_gotoxy(0,0);
    	 DDRA |= (1<<2);
    	 while (1) 
    	 { 
    		 sei();
    		 if (c=='1')
             { 
    		     c=0;
                 zeichen_senden(c);   
    	         lcd_putc(c);
    			 PORTA |= (1<<2);
    		 }
    		 if(c=='2')
             { 
    		     c=0;
                 zeichen_senden(c);   
    	         lcd_putc(c);
    			 PORTA &=~ (1<<2);
    		 }
    		 cli();
    	 }
    }	
    
    //-----------------------------------------------------
    //-----------------------------------------------------	
    
    
    ISR(USART_RXC_vect)
    {
         char temp;
         temp = UDR;              // speichere UDR-Wert in temp
    	 USART_interrupt(temp);
    }
    
    //-----------------------------------------------------
    
    void USART_interrupt (char temp)
    {
         data[a]+=temp;          // hänge neues byte an data an
         a++;                    // erhöhe Index a (Stelle) um 1
    	 if (temp=='#')
    	 {
    	     str_uebergabe(data,a);
         }
    }
    
    //-----------------------------------------------------
    
    void str_uebergabe (char data[], int a)
    {
    	 while(s!=a)
    	 {
    	     zeichen_senden(data[s]);
    		 lcd_putc(data[s]);
    		 s++;
    	 }
    	 for(i=0; i<a; i++)
         {
             data[i] = '\0';
         }
    	 s=0;
    	 a=0;
    }
    
    //-----------------------------------------------------
    	
    void usart_init(void)
    {
         UBRRH  = 0;                               
         UBRRL  = 7;
    	 UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN); 
    	 UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);                             
    }
    
    
    //-----------------------------------------------------
    //-----------------------------------------------------
    
    void string_senden(char *string) 
    { 
         while (*string) 
         { 
             while (!(UCSRA & (1<<UDRE))) 
             {} 
             UDR = *string++; 
         } 
    }
    
    //-----------------------------------------------------
    
    void zeichen_senden(char zeichen)
    	 { 
             while (!(UCSRA & (1<<UDRE))); 
             UDR = zeichen; 
         }  
    
    //-----------------------------------------------------
    //-----------------------------------------------------
    (Wenn man den Code kopiert, wird dieser korrekt und nicht verschoben dargestellt).

    Müsste die Zeichenkette "data" nicht wieder überschrieben werden, wenn der Index "a" genullt wird?

    Mit dieser Schleife wird die Zeichenkette geleert.

    Code:
    for(i=0; i<a; i++)
         {
             data[i] = '\0';
         }
    Warum wird die Zeichenkette nicht überschrieben und gibt es bessere Lösungen (auch für das Leeren von Zeichenketten)?

    Das LCD ist nun wesentlich schneller, wenn man die R/W Leitung benutzt und nicht nur kurz wartet .

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Beiträge
    2.731
    Hallo,

    wenn Du die Ausgabe auf dem LCD löschen willst, heisst Das eigentlich, das dort lauter Leerzeichen hin müssen.
    Wenn Du einen String erstellst, der nur \0 hat, ist dieser eigentlich leer, denn das \0 ist das Endekennzeichen.
    Du musst hier Leerzeichen in den String schreiben, und am Ende das \0.

    Edit:
    wegen dem String löschen:
    Code:
    strcpy(data, "ichwilldarein");
    Das \0 wird auch mit angehängt.

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    17.08.2005
    Alter
    39
    Beiträge
    685
    Das komische ist halt, dass der String nicht geleert wird.
    Die Zeichen werden zwar gelöscht, doch dahinter werden die neuen geschrieben.
    ZB. Hallo und als zweites wieso:
    Code:
    Hallo
          wieso
    So sieht das aus (auf dem Hyperterminal, sowie dem LCD). Wenn jedoch der Laufindex der Zeichenkette (bei mir "a") genullt wird, müsste die Zeichenkette doch wieder überschrieben (wieder beu null anfangen) und nicht fortgesetzt werden.?

  7. #7
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    17.08.2005
    Alter
    39
    Beiträge
    685
    Habe es hinbekommen:

    Code:
    ISR(USART_RXC_vect)
    {
         temp = UDR;                 // speichere UDR-Wert in temp
    	 data[a]=temp;         
    	 if (temp=='#')
    	 {
    	     str_uebergabe(data,a);
    		 a=-1;                   // Zeichen '\0' weg
         }
    	 a++;
    }
    
    //-----------------------------------------------------
    
    void str_uebergabe (char data[],int a)
    {
         s=0;
    	 while(s!=a)
    	 {
    	     zeichen_senden(data[s]);
    		 lcd_putc(data[s]);
    		 s++;
    	 }
    	 for (i=0; i<100; i++)
    	 {
             _delay_ms(10);
    	 }
    	 lcd_clrscr();
    	 strcpy(data,"");            // String löschen bzw. leeren
    }
    @ linux_80

    Ja, strcpy ist wesentlich besser geeignet

Berechtigungen

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

LiTime Speicher und Akkus