- LiTime Speicher und Akkus         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 17

Thema: UART sendet keine Strings!?

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    27.08.2004
    Beiträge
    9

    UART sendet keine Strings!?

    Hallo! Bin noch recht neu auf dem Gebiet µC.
    Habe mir zu Weihnachten das RNControl 1.4 gekauft und unter Windows mit Bascom lief auch alles wie geschmiert. Nun bin ich aber auf Linux und AVR-GCC umgestiegen und schon kamen die Probleme.
    Der UART lief erst nicht, was an dem bekannten 16 Mhz Problem lag). Dies habe ich nach langen herumhacken aber endlich hinbekommen und konnte einzelne Zeichen versenden.
    Wenn ich aber einen String versenden möchte kommt entweder überhaupt nichts oder nur "bekloppte" Zeichen.
    Hat jemand Ahnung woran das liegen könnte? Auf dem Board ist ein Mega16 mit 16 Mhz.

    Hier der Quellcode

    Code:
    #include <avr/io.h>
    #include<avr/interrupt.h>
    #include<avr/signal.h>
    
    volatile unsigned int nTicks=0;
    
    void init_uart(void);
    void timer (void);
    void uart_putc(char c);
    void uart_puts (char *s);
    
    void init_uart (void){
      UBRRL = 207;			//set baud rate
    
      UBRRH = 207 >> 8;
    
      UCSRA = _BV(U2X);
      UCSRC = 1<<URSEL^1<<UCSZ1^1<<UCSZ0;	//8 Bit
      UCSRB = 1<<TXEN;		// TX*/
      UBRRH = 0;
      UBRRL = 207;
      UCSRA = 1<<U2X;
    
      UCSRB = (1<<TXEN)|(1<<TXCIE);
    
      UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
    }
    
    void uart_putc(char c) //gibt ein Zeichen aus
    {
      while( (UCSRA & 1<<UDRE) == 0 );
      UDR = c;
    }
    
    void uart_puts (char *s) //soll einen String ausgeben
    {
        while (*s)
        {   /* so lange *s != NULL */
            uart_putc(*s);
            s++;
        }
    }
    
    void timer (void){
       TIMSK = (1 << TOIE0);
       TCNT0 = 0;
       TCCR0 = (1<<CS00)|(1<<CS02);
     }
    
    SIGNAL (SIG_OVERFLOW0)
    {
       nTicks++;
       // 1/ ((16000000 / 1024) / 256) = 16,384ms * 61 = 999,424ms
       if(nTicks == 61) {
           uart_putc('H');
           uart_putc('e');
           uart_putc('l');
           uart_putc('l');
           uart_putc('o');
           uart_putc(' ');
           uart_putc('W');
           uart_putc('o');
           uart_putc('r');
           uart_putc('l');
           uart_putc('d');
           uart_putc('!');
           uart_putc('\n');
       }
       if(nTicks == 122) {
          uart_putc('1');
          uart_putc('\n');
       }
       if(nTicks == 183) {
          uart_putc('2');
          uart_puts("HELLO WORLD");
          uart_putc('\n');
       }
       if(nTicks > 183) {
          nTicks = 0;
       }
    }
    
    int main (void)
    {
       init_uart();
       timer();
       sei();
       for(;;)
       {
    
       }
    }
    Die Ausgabe gibt jede ist:
    Hello World!
    1

    héÊŒU8Á·

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    08.10.2004
    Ort
    ferd. Waldmüllerg. 7/2
    Alter
    39
    Beiträge
    456
    Also, was mir am code aufgefallen ist:

    1) uart_putc(*s);
    s++; <--- hier gehörte mMn eher ein *s++, zumindest ist es im "normalen" C so, weil einige Compilr ansonsten auf die Idee kommen, nicht den Pointer auf den String um eines nach rechts zu verschieben, sondern gleich den Inhalt zu verändern...

    Diese Ausgabe schaut mir sehr danach aus, als ob du den Zeiger irgendwie "zum Teufel" jagen würdest...

    MfG
    Mobius

    P.S.:
    Code:
    void puts(char *source)
    {
    	while (*source != 0) // wait until tx register is empty
    		putc(*source++);
    	putc(0x0d);
    	putc(0x0a);
    }
    So guckt die standard-Routine für den PIC-C-Compiler aus...

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    27.08.2004
    Beiträge
    9
    Danke für die schnelle Antwort Mobius.
    Habe den Code wie du beschrieben hast geändert. Leider hat sich nichts an meinem Problem geändert.
    Mein Code schaut nun so aus:

    Code:
    void uart_putc(char c)
    {
      while( (UCSRA & 1<<UDRE) == 0 );
      UDR = c;
    }
    
    void uart_puts (char *s)
    {
       while (*s != 0) // wait until tx register is empty
          uart_putc(*s++);
    }
    Der String wird immer noch nicht übertragen.
    Kann das an AVR-GCC liegen, das die Strings irgendwie falsch interpretiert werden?
    Habe mal als Versuch aus dem String nur ein Zeichen in eine Char-Variable gespeichert und dann mit der funktionierenden Funktion uart_putc das Zeichen ausgegeben. Resultat war ein falsches Zeichen. Daher nehme ich an das mein µC irgendwie keine Strings mag.

    Hat jemand schon mal so etwas gehabt, oder weis woran das liegt?

    MfG HAL2004

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    31.01.2004
    Ort
    36399
    Alter
    49
    Beiträge
    1.562
    ehrlich sagt verstehe ich das nicht tut bei mir einband frei

    Code:
    typedef unsigned char BYTE;
    
    void SendMCData(BYTE Var,BYTE Value)
    {
    	BYTE Data[4];
    	Data[0] = 'A';
    	Data[1] = Var;
    	Data[2] = Value;
    	Data[3] = 'E';
    	for(int x = 0;x<4;x++)
    	{
    		SETBIT(UCSRB,TXEN);
    		//Warten bis schnittstelle bereit
    		loop_until_bit_is_set(UCSRA,UDRE);
    		// Zeichen ins register schreiben
    		UDR = Data[x];
    		CLEARBIT(UCSRB,TXEN);
    	}
    }
    P: Meine Tochter (06.11.07) und https://www.carnine.de
    M: Träumen hat nix mit Dummheit zu tun es ist die Möglichkeit neues zu erdenken

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    27.08.2004
    Beiträge
    9
    Danke NumberFive.
    Das funktioniert bei mir ja auch...aber du übergibst ja auch nur einzelne Zeichnen und nicht einen String der Funktion. Ich will ja einen String, z.B. "Hello World" direkt über UART ausgeben und sobald ich einen Zeiger auf einen String setze und die Zeichen Schritt für Schritt ausgeben möchte, kommt bei mir nur Müll heraus.

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    31.01.2004
    Ort
    36399
    Alter
    49
    Beiträge
    1.562
    komisch

    im selben programm

    Code:
    SendString("Enf :");
    char buffer[20];
    ltoa(entfernung,buffer,10);
    SendString(buffer);
    SendString("\n\r");
    int SendChar(char Zeichen)
    {
        SETBIT(UCSRB,TXEN);
    	//Warten bis schnittstelle bereit
    	loop_until_bit_is_set(UCSRA,UDRE);
    	
    	// Zeichen ins register schreiben
    	UDR = Zeichen;
    	
    	CLEARBIT(UCSRB,TXEN);
    	return 0;
    }
    
    void SendString(char* string)
    {
    	while(*string)
    	{
    		SendChar(*string++);
    	}
    }
    P: Meine Tochter (06.11.07) und https://www.carnine.de
    M: Träumen hat nix mit Dummheit zu tun es ist die Möglichkeit neues zu erdenken

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    27.08.2004
    Beiträge
    9
    Habe das Problem jetzt auf eine andere Art und Weise gelöst. Schreibe den String direkt in den Flash-Speicher und lese den dann mit pgm_read_byte Zelle für Zelle aus. Scheint das GCC den String irgendwie falsch in den Speicher ablegt oder ihn nicht korrekt wiederfindet. Anders kann ich mir das nicht erklären.
    Danke nochmals für Eure Hilfe!

    MfG HAL2004

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    16.05.2004
    Ort
    Bergstraße
    Beiträge
    245
    Genau kann ich auch nicht sagen wo jetzt im obigen Prgramm das Problem liegt, aber Strings in C sind einfach eine Krankheit.
    Versuch mal eine Stringvariable zu deklarieren, zB:
    char s[20];
    und via
    strcpy(s,"Hallo Welt");
    den String dareinzubekommen. Evtl. bei der Deklaration via 'volatile' Optimierungen verhindern.
    Und dann s and die USART-Routine übergeben.
    Ich hatte vor kurzem auch heftige Probleme, weil ich s = "abc";- Zuweisungen gemacht hatte, ging 4x gut, und dann kam Käse raus ... C und Strings halt
    ciao .. bernd

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    27.08.2004
    Beiträge
    9
    Danke bhm!
    Hast mich indirekt auf die richtige Spur geleitet. Es lag an paar Einstellungen im "Makefile", wo die Optimierung des Codes eingestellt werden (schätze ich mal).
    Habe mir jedenfalls eine neue Makefile erstellt und plötzlich funktioniert alles!
    Es lag also nie am C-Code.

    Thx HAL2004

  10. #10
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    16.05.2004
    Ort
    Bergstraße
    Beiträge
    245
    würde ich vorsichtig weiter testen. Ein falscher Code (insbesondere mit Pointern und Strings) _kann_ funktionieren, muss aber nicht. Eine kleine Änderung am ganz anderen Ende und es geht wieder nicht
    Hört sich etwas pessimistisch an, ist aber meine Erfahrung.
    ciao .. bernd

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

LiFePO4 Speicher Test