www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik USART von 9600Baud auf 1200Baud


Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Hab ein kleines Problem mit der USART.
Also ich arbeite mit einem ATMega32 und AVRStudio.
externer Quarz: 14,7456M

Jetzt wollt ich meine Baudrate von 9600Baud auf 1200Baud ändern. Mit 
9600Baud funktionierte die Kommunikation zwischen uC und PC einwandfrei.
mit 1200 kommt aber leider nur Quatsch raus.

meine USART initialisierung sieht so aus:

#include "global.h"

#include <avr/io.h>

void initusart(void) 
//USART bzw. UART initialisieren
{
 unsigned char x; 
//Hilfsvariable
 #ifdef UBRRL 
//USART-Schnittstelle
  UBRRL = (TAK / (16ul * BAUD )) - 1; 
//Baudrate mit TAKT und BAUD
  UCSRB = (1 << TXEN ) | (1 << RXEN);
  UCSRC = (1 << URSEL) | (1 << UPM1) | (0 << UPM0) | (1 << USBS) | (1 
<<UCSZ1) | (0 << UMSEL) | (0 << UCSZ0) | (0 << UCSZ2);
                      //ASYNC, 1Startbit,gerade 
Parität,7Datenbits,2Stopbits



 #else 
//UART-Schnittstelle
  UBRR = (TAK / (16ul * BAUD)) -1; 
//Baudrate
  UCR = (1 <<TXEN) | (1 <<RXEN); 
//Sender und Empfänger
 #endif
 x =UDR; 
//Empfänger leeren
}


Die Baudrate hab ich in den globals definiert.

Danke schon mal im Voraus

Autor: ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Die Baudrate hab ich in den globals definiert.

Und da liegt wohl das Problem, wenn es vorher mit 9600 funktioniert hat 
wird der Code ja stimmen, bzw. keine groben Fehler enthalten.
Zeig mal deine globals.h

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include <avr/wdt.h>
#include <util/delay.h>
#include "adc.h"
#include "lcd.h"
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "timer.h"                  // timer functions (timerpause 
etc...)
#include "uart.h"                 // include uart function library
#include "rprintf.h"               // include printf function library

#define TAK 14745600UL               // Takt
#define BAUD 1200UL                   // Baudrate

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Keiner ne idee?

Vielleicht liegts am Quarz?

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Vielleicht liegts am Quarz?

Mit dem Quartz lassen sich die 1200Bd problemlos erzeugen. Hast du auch 
auf dem PC auf 1200Bd umgestellt?

MfG Spess

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jep, hab ich...ist alles auf 1200Baud eingestellt.

Wenn ich ins Datenblatt vom ATMega32 rein schau auf Seite 165 ist mein 
Quarz mit dem Prozenttualen Fehler und zugehöriger Baudrate angegeben.
Hier gehts aber nur ab 2400 los!?

Gruß Andy

Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der UBRR-Wert bei 1200 Baud beträgt 767, das passt nicht mehr in ein 
Byte. Du beschreibst aber nur UBRRL. In UBRRH steht dadurch null statt 
zwei - und das gibt natürlich eine falsche Baudrate.

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ohhh ja,

danke dir...wär ich so schnell nicht drauf gekommen:).

Hast zufällig ne idee wie ich das jetzt am elegantesten löse?

Danke dir.

Autor: U.R. Schmitt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
UBRRL = (TAK / (16ul * BAUD )) - 1;

ergibt bei Dir mit den gewählten Werten 767
Passt das überhaupt in UBRRL rein? Ist das nicht ein 8 Bit Register?

Es hat wahrscheinlich einen Grund, daß in der Beschreibung ab 2400 Baud 
steht.
Entweder kann der Controller mit dem gewählten Quarz nicht auf 1200 
runterteilen, oder man muss einen Vorteiler anders konfigurieren.

Autor: U.R. Schmitt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mist, zu spät

Autor: U.R. Schmitt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andy schrieb:
> Hast zufällig ne idee wie ich das jetzt am elegantesten löse?

Na ja, wenn der Vorteiler auch noch ein paar höherwertige Bits im 
Register darüber umfasst einfach deinen Teilerwert T
T/256 in die Bits des MSB
T%256 (modulo) für das untere Byte LSB

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Hast zufällig ne idee wie ich das jetzt am elegantesten löse?

UBRR = (TAK / (16ul * BAUD )) - 1;

(ohne Gewähr)

MfG Spess

Autor: U.R. Schmitt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal ne blöde Frage, warum bleibst Du nicht bei 9600 oder wenigstens bei 
2400?

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hört sich gut an...
ich versuchs mal...

Danke
Gruß Andy

Autor: H.Joachim Seifert (crazyhorse)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
UBRRH=(unsigned char) (baud>>8);
UBRRL=(unsigned char) baud;

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Brauch ich in der Arbeit...und der Kunde wünscht so ne scheiss 
Baudrate:)

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andy schrieb:
> Hast zufällig ne idee wie ich das jetzt am elegantesten löse?

Lesen:

http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Auszug:
#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 

und:
/* UART-Init Bsp. ATmega16 */
 
void uart_init(void)
{
  UCSRB |= (1<<TXEN);  // UART TX einschalten
  UCSRC |= (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1 
 
  UBRRH = UBRR_VAL >> 8;
  UBRRL = UBRR_VAL & 0xFF;
}

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ts ts ts.

Warum bloß liest niemand die Warnungen nach dem Compilieren:
BAUD.C: In function 'main':
BAUD.C:10: warning: large integer implicitly truncated to unsigned type

Eh ich nicht 0 Warnungen sehe, kommt das Programm garnicht erst in den 
Chip.

Und für die ganz Unbelehrbaren empfehle ich folgenden Schalter:
-Werror


Peter

Autor: U.R. Schmitt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> #if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
>   #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
> #endif

Nett :-))

Peter Dannegger schrieb:
> Eh ich nicht 0 Warnungen sehe, kommt das Programm garnicht erst in den
> Chip.

100% agree

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.