- 12V Akku mit 280 Ah bauen         
Seite 1 von 4 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 36

Thema: String über UART ausgeben

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    19.04.2005
    Ort
    Minden
    Alter
    39
    Beiträge
    227

    String über UART ausgeben

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo,

    ich bin gerade dabei mich in C einzuarbeiten. Doch ich komme leider an einer Stelle nicht weiter.
    Ich habe es hinbekommen ein Byte über den UART auszugeben. Nun möchte ich gerne einen ganzen String ausgeben. In dem Tutorial von mikrocontroller.net habe ich einen Beispielcode gefunden. Nur leider kann ich diesen nicht nachvollziehen. Es wäre schön wenn jemand mir mal ein Beispiel geben könnte wo alles genau beschrieben ist, so das ich das nachvollziehen kann.

    Vielen Dank im Voraus

    gruß ceekay

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.11.2003
    Beiträge
    991
    Moin,

    vielleicht hilft dir ja folgends weiter:
    http://www.kreatives-chaos.com/index.php?seite=avr_b

    MfG Kjion

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    19.04.2005
    Ort
    Minden
    Alter
    39
    Beiträge
    227
    falls du das "Beispiel zur Ansteuerung des UART" meinst. dann nein.

    Denn das hab ich schon verstanden nur ich möchte zum beispiel folgende Bytes nacheinander ausgeben: 'a' 'b' 'c' 'd'
    ohne das ich nacheinander jeden Buschstaben manuell in das UDR schreiben muss.
    Wie müsste es aussehen wenn diese Bytes nacheinander übertragen werden.

    gruß ceekay

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    19.04.2005
    Ort
    Minden
    Alter
    39
    Beiträge
    227
    ah sorry du meintest: Beispiel: "Strings aus dem Flash ausgeben"

    sorry hab ich eben erst gesehen. Das sieht gut aus. ich werd mir das morgen mal genau ansehen und denn nochmal konkrete Fragen stellen.
    Vielen Dank erstma.

    gruß ceekay

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    19.04.2005
    Ort
    Minden
    Alter
    39
    Beiträge
    227
    Hi,
    ich habe das Programm von kreatives-chaos.com mal compiliert und auf meinen Controller geladen. Vorher habe ich noch ein paar Dinge angepasst.
    baudrate auf 9600 und Systemclock auf 16000000.
    Leider funktioniert es nicht. Ich bekomme nur diese Zeichen permanent:

    ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ
    ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ
    ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ ÀÀÀÀÀÀÀÀÀÀÀÀÀÀ

    ich hoffe ihr könnt mir helfen.

    Vielen Dank schonmal für die Mühen.

    gruß ceekay

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.11.2003
    Beiträge
    991
    Hört sich nach einem falsch initialisiertem UART an. Hast du BAUD wie im Beispiel als "unsigned long" definiert ??
    Code:
    #define SYSCLK		16000000
    #define BAUD		9600UL
    Ansonsten sollte das eigentlich funktionieren...

    MfG Kjion

  7. #7
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Für mich schaut das mehr nach Durcheinender von address-of und value
    aus (weil die Zeichen alle gleich sind. bei Baudfehlern ist das selten)
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.11.2003
    Beiträge
    991
    Hi,

    versuch mal folgendes:

    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    #include <avr/pgmspace.h>
    
    #define SYSCLK		16000000
    #define BAUD		9600UL
    #define UBRR_BAUD	((SYSCLK/(16*BAUD))-1)
    
    #define	TRUE	1
    #define	FALSE	0
    
    /* USART initialisieren */
    void uart_init(void);
    
    volatile const prog_char *p_string;
    
    /* Zeichenkette im Flashspeicher */
    prog_char daten[] = "Hello World!\n";
    
    int main(void)
    {
    	// USART initialisieren
    	uart_init();
    	
    	sei();
    	
    	// Pointer zeigt auf die Daten im Flashspeicher
    	p_string = daten;
    	
    	// erstes Byte senden
    	UDR = pgm_read_byte( p_string++ );
    	
    	// Interrupt aktivieren
    	UCSRB |= (1<<UDRIE);
    	
    	for(;;);
    }
    
    void uart_init(void)
    {
    	/* Baudrate einstellen ( Normaler Modus ) */
    	UBRRH = (unsigned char) (UBRR_BAUD>>8);
    	UBRRL = (unsigned char) (UBRR_BAUD & 0x00FF);
    	
    	/* Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts */
    	UCSRB = (1<<TXEN);
    	
    	/* Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit */
    	UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
    }
    
    /* Interrupt wird ausgelöst sobald der Sendepuffer leer ist */
    SIGNAL(SIG_UART_DATA)
    {
    	char buffer = pgm_read_byte( p_string++ );
    	
    	/* Wenn nicht das Ende der Zeichenkette erreicht wurde, weiteres Zeichen senden */
    	if ( buffer != '\0' ) {
    		UDR = buffer;
    	
    	} else {
    		// Interrupt deaktivieren
    		UCSRB &= ~(1<<UDRIE);
    	}
    }
    Warum das andere Beispiel nicht funktioniert weiß ich im Moment auch noch nicht so genau.
    Wenn man sich das Assemblerlisting anschaut, dann sieht man, dass er den Pointer p_string nicht neu lädt. Es wird also nach und nach der gesamte Inhalt des Flashspeichers ausgegeben.
    Fügt man aber irgendeine Delayroutine hinter die Abfrage ein, so funktioniert auf einmal alles, auch der Pointer wird wieder richtig initialisiert.

    Mit Delay:
    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    #include <avr/pgmspace.h>
    
    #define SYSCLK		7372800
    #define BAUD		9600UL
    #define UBRR_BAUD	((SYSCLK/(16*BAUD))-1)
    
    #define	TRUE	1
    #define	FALSE	0
    
    /* USART initialisieren */
    void uart_init(void);
    
    void delay_ms(uint16_t ms);
    
    volatile unsigned char daten_gesendet = TRUE;
    volatile const prog_char *p_string;
    
    /* Zeichenkette im Flashspeicher */
    prog_char daten[] = "Hello World!\n";
    
    int main(void)
    {
    	// USART initialisieren
    	uart_init();
    	
    	sei();
    	
    	while (1)
    	{
    		if (daten_gesendet)
    		{
    			// Flag zurücksetzen
    			daten_gesendet = FALSE;
    			
    			// Pointer zeigt auf die Daten im Flashspeicher
    			p_string = daten;
    			
    			// erstes Byte senden
    			UDR = pgm_read_byte( p_string++ );
    			
    			// Interrupt aktivieren
    			UCSRB |= (1<<UDRIE);
    		}
    		
    		delay_ms(1);
    	}
    }
    
    void uart_init(void)
    {
    	/* Baudrate einstellen ( Normaler Modus ) */
    	UBRRH = (unsigned char) (UBRR_BAUD>>8);
    	UBRRL = (unsigned char) (UBRR_BAUD & 0x00FF);
    
    	/* Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts */
    	UCSRB = (1<<RXEN)|(1<<TXEN);
    	
    	/* Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit */
    	UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);	
    }
    
    /* Interrupt wird ausgelöst sobald der Sendepuffer leer ist */
    SIGNAL(SIG_UART_DATA)
    {
    	char buffer = pgm_read_byte( p_string++ );
    	
    	/* Wenn nicht das Ende der Zeichenkette erreicht wurde, weiteres Zeichen senden */
    	if ( buffer != '\0' ) {
    		UDR = buffer;
    		
    	} else {
    		// Flag setzen, das der String gesendet wurde
    		daten_gesendet = TRUE;
    		
    		// Interrupt deaktivieren
    		UCSRB &= ~(1<<UDRIE);
    	}
    }
    
    /*
     *	eine kleine Warteschleife ( fürs debugging )
     */
    void delay_ms(uint16_t ms)
    {
    	uint16_t zaehler;
    	
    	while (ms) 
    	{
    		zaehler = F_CPU / 5000;
    		while (zaehler) 
    		{
    			asm volatile ("nop"::);
    			zaehler--;
    		}
    		ms--;
    	}
    }
    MfG Kjion

  9. #9
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Zitat Zitat von Kjion
    volatile const prog_char *p_string;
    Das mutet etwas seltsam an. Wenn etwas const ist, ist es kaum flüchtig (volatile).
    Du meinst wohl eher:
    const prog_char * volatile p_string;
    p_string ist volatile und das, worauf er zeigt, ist unveränderlich.

    Übrigens brauchst du nicht UDR zu schreiben, um das Senden anzustoßen. Da genügt ein UCSRB |= (1<<UDRIE); und man landet in der ISR, sobalt UDR bereit ist. Dort wird dann mit dem 1. Zeichen begonnen und nicht erst mit dem 2.
    Spart Platz und ist klarer
    Disclaimer: none. Sue me.

  10. #10
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.11.2003
    Beiträge
    991
    Zitat Zitat von SprinterSB
    const prog_char * volatile p_string;
    p_string ist volatile und das, worauf er zeigt, ist unveränderlich.
    So wars eigentlich auch gemeint. Damit funktioniert es dann natürlich auch.

    Wie war das noch, der Computer macht das was man ihm sagt, nicht das was man meint ...

    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    #include <avr/pgmspace.h>
    
    #define SYSCLK		7372800
    #define BAUD		9600UL
    #define UBRR_BAUD	((SYSCLK/(16*BAUD))-1)
    
    #define	TRUE	1
    #define	FALSE	0
    
    // USART initialisieren
    void uart_init(void);
    
    volatile unsigned char daten_gesendet = TRUE;
    const prog_char* volatile p_string;
    
    // Zeichenkette im Flashspeicher
    prog_char daten[] = "Hello World!\n";
    
    int main(void)
    {
    	// USART initialisieren
    	uart_init();
    	
    	sei();
    	
    	while (1)
    	{
    		if (daten_gesendet)
    		{
    			// Flag zurücksetzen
    			daten_gesendet = FALSE;
    			
    			// Pointer zeigt auf die Daten im Flashspeicher
    			p_string = daten;
    			
    			/* Interrupt aktivieren, damit wird sofort zur
    			   Interruptroutine gesprungen und das erste Zeichen gesendet. */
    			UCSRB |= (1<<UDRIE);
    		}
    	}
    }
    
    void uart_init(void)
    {
    	// Baudrate einstellen ( Normaler Modus )
    	UBRRH = (unsigned char) (UBRR_BAUD>>8);
    	UBRRL = (unsigned char) (UBRR_BAUD & 0x00FF);
    
    	// Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts
    	UCSRB = (1<<RXEN)|(1<<TXEN);
    	
    	// Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit
    	UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);	
    }
    
    /* Interrupt wird ausgelöst sobald der Sendepuffer leer ist */
    SIGNAL(SIG_UART_DATA)
    {
    	char buffer = pgm_read_byte(p_string++);
    	
    	/* Wenn nicht das Ende der Zeichenkette erreicht wurde, 
    	   dann weiteres Zeichen senden */
    	if ( buffer != '\0' ) {
    		UDR = buffer;
    		
    	} else {
    		// Flag setzen, das der String gesendet wurde
    		daten_gesendet = TRUE;
    		
    		// Interrupt deaktivieren
    		UCSRB &= ~(1<<UDRIE);
    	}
    }
    MfG Kjion

Seite 1 von 4 123 ... LetzteLetzte

Berechtigungen

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

LiFePO4 Speicher Test