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


von Andy (Gast)


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

von ich (Gast)


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

von Andy (Gast)


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

von Andy (Gast)


Lesenswert?

Keiner ne idee?

Vielleicht liegts am Quarz?

von Spess53 (Gast)


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

von Andy (Gast)


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

von Detlev T. (detlevt)


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.

von Andy (Gast)


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.

von U.R. Schmitt (Gast)


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.

von U.R. Schmitt (Gast)


Lesenswert?

Mist, zu spät

von U.R. Schmitt (Gast)


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

von Spess53 (Gast)


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

von U.R. Schmitt (Gast)


Lesenswert?

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

von Andy (Gast)


Lesenswert?

Hört sich gut an...
ich versuchs mal...

Danke
Gruß Andy

von H.Joachim S. (crazyhorse)


Lesenswert?

UBRRH=(unsigned char) (baud>>8);
UBRRL=(unsigned char) baud;

von Andy (Gast)


Lesenswert?

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

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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

Lesen:

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_UART#UART_initialisieren

Auszug:
1
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
2
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
3
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
4
 
5
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
6
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
7
#endif

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

von Peter D. (peda)


Lesenswert?

Ts ts ts.

Warum bloß liest niemand die Warnungen nach dem Compilieren:
1
BAUD.C: In function 'main':
2
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:
1
-Werror


Peter

von U.R. Schmitt (Gast)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.