www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega8 UART Probleme


Autor: Ruediger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey Leute, ich weiss das es schon genug Beiträge über Probleme mim UART 
gibt,aber ich komm einfach nich weiter. Ich möchte mir ein Programm in 
GCC schreiben, das bestimmte Wörter über die Hardware UART Schnittstelle 
des Atmega8 verschickt, wenn jeweils ein bestimmter eingang low ist. Um 
aber klein anzufangen soll mein uC erstmal nur ein Wort über die UART 
Schnittstelle versenden. Hab mir dafür den Code aus der Tutorial Seite 
zusammenkopiert. Und das ganze sieht bei mir so aus:

#include <avr/io.h>
#ifndef F_CPU
/* In neueren Version der WinAVR/Mfile Makefile-Vorlage kann
   F_CPU im Makefile definiert werden, eine nochmalige Definition
   hier wuerde zu einer Compilerwarnung fuehren. Daher "Schutz" durch
   #ifndef/#endif 
 
   Dieser "Schutz" kann zu Debugsessions führen, wenn AVRStudio 
   verwendet wird und dort eine andere, nicht zur Hardware passende 
   Taktrate eingestellt ist: Dann wird die folgende Definition 
   nicht verwendet, sondern stattdessen der Defaultwert (8 MHz?) 
   von AVRStudio - daher Ausgabe einer Warnung falls F_CPU
   noch nicht definiert: */
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
#define F_CPU 8000000UL  // Systemtakt in Hz - Definition als unsigned long beachten 
                         // Ohne ergeben sich unten Fehler in der Berechnung
#endif
 
#define BAUD 9600UL      // Baudrate
 
// Berechnungen
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
 
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
#endif


int main(void)
{
    UCSRB |= (1<<TXEN);                // UART TX einschalten
    UCSRC |= (1<<URSEL)|(3<<UCSZ0);    // Asynchron 8N1 
 
    UBRRH = UBRR_VAL >> 8;
    UBRRL = UBRR_VAL & 0xFF;
  
  uart_puts('TEST');    //Test Senden
  
}


// bei neueren AVRs andere Bezeichnung fuer die Statusregister, hier ATmega8:
int uart_putc(unsigned char c)
{
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
    {
    }                             
 
    UDR = c;                      /* sende Zeichen */
    return 0;
}
 
 
/* puts ist unabhaengig vom Controllertyp */
void uart_puts (char *s)
{
    while (*s)
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
        uart_putc(*s);
        s++;
    }
}
das sollte doch soweit in Ordnung sein,oder? Zumindest sendet mein uC so 
irgendwas. Nur leider sieht das nach Kauderwelsch aus. Dachte also 
zuerst an ein Timing Problem. Ist aber in den Fuses alles richtig 
eingestellt. Wenn ich den Code so abänder das ich nicht mehr uart_puts 
aufrufe sondern mit UDR = 'X' ein einzelnes zeichen verschicke, klappt 
auch alles perfekt. Hier der Code mit dem einzelnen Zeichen:

#include <avr/io.h>
#ifndef F_CPU
/* In neueren Version der WinAVR/Mfile Makefile-Vorlage kann
   F_CPU im Makefile definiert werden, eine nochmalige Definition
   hier wuerde zu einer Compilerwarnung fuehren. Daher "Schutz" durch
   #ifndef/#endif 
 
   Dieser "Schutz" kann zu Debugsessions führen, wenn AVRStudio 
   verwendet wird und dort eine andere, nicht zur Hardware passende 
   Taktrate eingestellt ist: Dann wird die folgende Definition 
   nicht verwendet, sondern stattdessen der Defaultwert (8 MHz?) 
   von AVRStudio - daher Ausgabe einer Warnung falls F_CPU
   noch nicht definiert: */
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
#define F_CPU 8000000UL  // Systemtakt in Hz - Definition als unsigned long beachten 
                         // Ohne ergeben sich unten Fehler in der Berechnung
#endif
 
#define BAUD 9600UL      // Baudrate
 
// Berechnungen
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
 
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
#endif


int main(void)
{
    UCSRB |= (1<<TXEN);                // UART TX einschalten
    UCSRC |= (1<<URSEL)|(3<<UCSZ0);    // Asynchron 8N1 
 
    UBRRH = UBRR_VAL >> 8;
    UBRRL = UBRR_VAL & 0xFF;
  
  UDR = 'X';    // X Senden
  
}


// bei neueren AVRs andere Bezeichnung fuer die Statusregister, hier ATmega8:
int uart_putc(unsigned char c)
{
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
    {
    }                             
 
    UDR = c;                      /* sende Zeichen */
    return 0;
}
 
 
/* puts ist unabhaengig vom Controllertyp */
void uart_puts (char *s)
{
    while (*s)
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
        uart_putc(*s);
        s++;
    }
}


wie gesagt ich hab da nur eine Zeile geändert,aber dann komm auch X an 
und kein kauderwelsch. Naja, hoffe ihr habt mein Problem verstanden und 
könnt mir vielleicht helfen. Vielen Dank schonmal, Ruediger

Autor: Jochen R. (josch90)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist der Controller neu? Möglicherweise läuft er noch auf seinem internen 
Takt. Also sicherstellen dass der 8Mhz Quarz dran is un auch in den 
Fuses aktiviert ist.


Gruß

Autor: Sebastian M. (noobuntu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mit uart_puts versendest du ja eine Zeichenkette. Weis nicht ob es 
Probleme gibt wenn du nur 1 Zeichen damit verschickst. Was passiert den 
wenn du
usart_putc('X');
 benutzt ?
Oder probiert mal
usart_puts("Test");

Sonst solltest du mal deine Fuses überprüfen.

Autor: Ruediger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey, das einzelne Zeichen hab ich ja auch nicht mit UART_puts versendet 
sondern direkt an UDR übergeben. Das klappt ja dann auch. Nur wenn ich 
mit UART_puts('test');  nen string senden will klappt es nicht....
Die Fuses hab ich aber trotzdem nochmal überprüft und die stehen auf 
Ext. Crystal und an meinem STK500 ist ebenfalls alles auf externen Quarz 
gejumpert. Hoffe ihr habt noch mehr ideen. LG Ruediger

Autor: Mmmh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
uart_puts('TEST');    //Test Senden

soll wohl
uart_puts("TEST");    //Test Senden

heissen.

Ich wundere mich stark das dieser Code überhaupt ohne Fehler compiliert 
wurde.

Autor: Ruediger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh man, das wars!!!!
Vielen Vielen Dank! Hatte echt ein Brett vorm Kopf. Mit "TEST" 
funktioniert es tadelos! Warum der Compiler allerdings keinen Fehler 
gemeldet hat,weiß ich auch nicht. Auf jeden Fall vielen Dank für dein 
wachsames Auge. Mfg Ruediger

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.