USART Takt stimmt nicht mit Atmega8

OP Persönliche Seite #2551405
Lesenswert?
• ▲
▼
Hallo,

ich weiß, die USART Takt-Fragen gibt es wie Sand am Meer, aber ich komme 
nicht weiter, obwohl ich eigentlich weiß wie man UBRR berechnet.

Folgendes Problem: Ich habe funktionierenden Code für den Atmega168. Ich 
habe diesen nun einfach nur für einen Atmega8 angepasst, da dort die 
Register etwas anders heißen. Sonst ändert sich nix.
Laut Datenblatt sollte an der Taktberechung ja nix anders sein, oder 
habe ich da was verpasst?

Randbedingungen: 8MHz Takt, Baudrate soll 9600 sein -> also ein UBRR von 
51.

Code:
/* UART Configuration */
#define BAUD 9600UL
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)

#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
#endif

/* Initialize UART */
void InitUART()
{
    /* Set DDR TX to output */
    DDRD |= _BV( PD1 );
    /* Set DDR RX to input */
    DDRD &= ~_BV( PD0 );

#ifdef _AVR_ATmega8_
    //UBRRH = ( unsigned char )( UBRR_VAL >> 8 );
    //UBRRL = ( unsigned char )UBRR_VAL;
    UBRRH = 0;
    UBRRL = 51; // diesmal aus Datenblatt vorsichtshalber
    UCSRA &= ~(1<<U2X); /* disable double speed, nur ein test */
    /* Enable UART receiver and transmitter */
    UCSRB = _BV( RXEN ) | _BV( TXEN );
    /* Frame Format: synchronous 8N1 */
    UCSRC = /*_BV( UMSEL ) |*/ _BV( UCSZ1 ) | _BV( UCSZ0 );
    /* enable RX interrupt */
    UCSRB |= _BV( RXCIE );
#else /* jetzt funktionierender Code für Atmega48/168/328 */
    UBRR0H = ( unsigned char )( UBRR_VAL >> 8 );
    UBRR0L = ( unsigned char )UBRR_VAL;
    /* Enable UART receiver and transmitter */
    UCSR0B = _BV( RXEN0 ) | _BV( TXEN0 );
    /* Frame Format: synchronous 8N1 */
    UCSR0C = /*_BV( UMSEL00 ) |*/ _BV( UCSZ01 ) | _BV( UCSZ00 );
    /* enable RX interrupt */
    UCSR0B |= _BV( RXCIE0 );
#endif
}

Die Fuse-Bits habe ich auf 8MHz externen Quarz gestellt. Der Quarz 
schwingt und der Takt stimmt, kann im Sekunden-Takt mittels 
__delay_ms(1000) eine LED blinken lassen.
Habs auch schon mit internem 8MHz RC Osz. versucht, selbes Ergebnis.

Mit dem Oszi sehe ich, dass der UART für 8 Bit (Testzeichen 0x55 'U') 
25ms braucht -> 320 Baud. Sollte aber 0.833ms sein für 9600 Baud.
Das ist zeimlich genau ein Faktor 30 daneben, was ich mir nicht erklären 
kann.

Gibt's da noch irgendeinen Teiler von dem ich nix weiß?
Ich hoffe jemand kann mir da weiterhelfen.
#2551412
Lesenswert?
• ▲
▼
1
    UCSRC = /*_BV( UMSEL ) |*/ _BV( UCSZ1 ) | _BV( UCSZ0 );
Du schreibst also 6 nach UBRRH. Kein Wunder, dass
> Mit dem Oszi sehe ich, dass der UART für 8 Bit (Testzeichen 0x55 'U')
> 25ms braucht -> 320 Baud.

Sheldon Cooper schrieb:
> Folgendes Problem: Ich habe funktionierenden Code für den Atmega168. Ich
> habe diesen nun einfach nur für einen Atmega8 angepasst, da dort die
> Register etwas anders heißen. Sonst ändert sich nix.

Tja, so einfach ist es halt doch nicht.

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.