mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Baudratenumschaltung beim UART des ATMega16


Autor: Georg Speth (gspeth)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ich schreibe grad an meiner Studienarbeit, wo ich auf der Hardwarebasis 
(ATMega16) meines Vorgängers einen LIN Slaveknoten programmieren soll. 
Das Empfangen der Frames klappt einwandfrei.
Mein Problem liegt beim Versenden eines Frames. Laut Spezifikation von 
LIN muss jeder Frame mit einem 13 Bitzeit-langen Syncbreak und 
anschliessend einem Syncfeld (0x55) beginnen. Da der ATMega16 selber 
kein Break-Syncfeld erzeugen kann, hab ich mich beim implementieren an 
einen Tipp aus dem Buch LIN-Bus von Andreas Grzemba gehalten:

"Ein Standard UART kann das Synchronisationsbreak nicht direkt erzeugen. 
Man kann sich aber mit einem Trick behelfen. Will man beispielsweise für 
19,2 KBits/s das Synchronisationsbreak erzeugen, setzt man die Baudrate 
auf ca. 13 KBit/s herab und sendet ein 0x00 Datenbyte. Das Senden der 8 
Bits zuzüglich des Startbits dauert etwas länger als die notwendigen 677 
Mikrosekungen des Synchronisationsbreaks. Anschließend wird die Baudrate 
wieder auf 19,2 KBit/s gesetzt und das Synchronisationsfeld gesendet."

Da die Kommunikation bei mir bei 9600 Bit/s läuft, versuche ich die 
Baudrate auf 6500 Bit/s herunterzusetzen. Allerdings werden die 
verschickten Frames nicht als LIN Frames erkannt und laut Oszi ist auch 
das Synchronisationsbreak zu kurz. Wenn ich zum Testen die Baudrate noch 
weiter herabsetze, verändert sich die Dauer des Synchronisationsbreak 
nicht. Daher nehme ich an, dass die Umschaltung der Baudrate nicht 
funktioniert.

Code zum Initialisieren des UART:
/**
 * Quartfrequenz des Lin - Knoten
 */
#define F_CPU 8000000    // Oszillator-Frequenz in Hz (8MHz)

/**
 * Baudrate für LIN-Kommunikation in bps festlegen
 */
#define UART_BAUD_RATE_NORMAL 9600

/**
 * Baudrate für LIN-Kommunikation in bps festlegen
 * fuer das Sync - Break Feld
 */
#define UART_BAUD_RATE_BREAKSYNC 6500

/**
 * Hilfsmakro zur UBRR-Berechnung fuer den ATMega16
 * ("Formel" laut Datenblatt)
 */
#define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1)


/*
 * setzten der Variablen mit den Werten
 * fuer die Baudrateneinstellung des
 * UARTs des ATMega16
 */
l_UBRRH_Normal = (uint8_t) (UART_UBRR_CALC (UART_BAUD_RATE_NORMAL, 
F_CPU) >> 8);
l_UBRRL_Normal = (uint8_t) UART_UBRR_CALC (UART_BAUD_RATE_NORMAL, 
F_CPU);

l_UBRRH_SyncBreak = (uint8_t) (UART_UBRR_CALC (UART_BAUD_RATE_BREAKSYNC, 
F_CPU) >> 8);
l_UBRRL_SyncBreak = (uint8_t) UART_UBRR_CALC (UART_BAUD_RATE_BREAKSYNC, 
F_CPU);

setBaudNormal ();

/*
 * Frameformat setzen
 */
UCSRB = (1 << TXEN);  // Sender einschalten
UCSRB &= ~(1 << RXCIE);  // Empfaengerinterrupt ausschalten
UCSRB &= ~(1 << RXEN);  // Empfaenger ausschalten


Code der Baudratenumschaltfunktionen:
void setBaudNormal (void)
{
    unsigned char leeren = UDR;

    UCSRC &= ~(1 << URSEL);
    UBRRH = l_UBRRH_Normal; // auf Baudrate fuer Normal stellen
    UBRRL = l_UBRRL_Normal; // auf Baudrate fuer Normal stellen

    UCSRC |= (1 << URSEL) | (3 << UCSZ0); // Asynchron 8 Bit mit 1 
Stoppbit

    leeren = UDR;
}

void setBaudSyncBreak (void)
{
    unsigned char leeren = UDR;

    UCSRC &= ~(1 << URSEL);
    UBRRH = l_UBRRH_SyncBreak;  // auf Baudrate fuer SyncBreak stellen
    UBRRL = l_UBRRL_SyncBreak;  // auf Baudrate fuer SyncBreak stellen

    UCSRC |= (1 << URSEL) | (3 << UCSZ0); // Asynchron 8 Bit mit 1 
Stoppbit

    leeren = UDR;
}

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.