PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : UART Bautraten Register beschreiben?



kautz
28.02.2005, 19:46
Hallo,
ich habe einen ATmega16 und möchte mit dem Uart an mein Computer Daten senden.
Wie schreibe ich die Baudrate in das Register?
Im Datenblatt sehe ich nur das UBRRL und das ist für das LowByte.
Wie teile ich das denn mit dem "outp()" auf?
Vielen dank im vorraus!!

Thorsten
28.02.2005, 19:57
Man kann direkt das UBRR-Register mit 16bit Werten
beschreiben:

UBRR = F_CPU / (BAUD_RATE * 16L) - 1;

Dann brauchst du nur noch F_CPU als deine Quarzfrequenz
und BUAD_RATE als deine Gewünschte baudrate definieren und
der Präprozessor berechnet die Richtigen Einstellungen.

EDIT:
Hier ist es auch noch mal genau beschrieben:
http://www.mikrocontroller.net/wiki/AVR-GCC-Tutorial#Der_UART

EDIT2:
outp sollte man nicht mehr verwenden, ist in der aktuellen Version der avr-libc (1.2) entfernt wurden. Man kann die Register wie Variablen direkt beschreiben.

kautz
28.02.2005, 20:22
jo danke,
also irgendwie gibt es das register UBRR nicht.

#include <avr/io.h>
#include <avr/iom16.h>
#define F_CPU 8000000
#define BAUD_RATE 9600
int main (void)
{
UCSRB=0x04; //outp ((1 << TXEN), UCSRB);
UBRR = F_CPU / (BAUD_RATE * 16L) - 1;
}
Das funzt nicht.
Der Compiler kennt das Register nicht.
Es steht ja auch nicht im Datenblatt. mmmh

kautz
28.02.2005, 20:26
Ups die Antwort steht ja in deinem Link.
Ok danke

Thorsten
28.02.2005, 20:36
Was mir nch aufällt ist, dass du die io16m.h manuell eingebunden hast.
Es reicht aber wenn du die io.h einbindest, die ioXX.h wird automatisch
eingebunden, je nachdem was du im Makefile eingestellt hasst.

kautz
28.02.2005, 20:45
Also ich habe jetzt das hier aus deinem Link geklaut.

#include <avr/io.h>
#define F_CPU 8000000
#define BAUD_RATE 9600
#define F_OSC 3686400 /* Oszillator-Frequenz in Hz */
#define UART_BAUD_RATE 9600
#define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_OSC)/((UART_BAUD_RATE)*16)-1)

int main (void)
{
UCSRB=0x04;
UBRRH=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_OS C)>>8);
UBRRL=(uint8_t)UART_BAUD_CALC(UART_BAUD_RATE,F_OSC );
while (!(UCSRA & (1<<UDRE)));
UDR = 'x';

}
das sind die Fehler:
uart2.c:10: warning: integer overflow in expression
uart2.c:11: warning: integer overflow in expression

Ich habe kein Plan, wieso da stag overflow stattfindet.
UBRRH=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_OS C)>>8);
Ich weiß auch nich so recht was da gemacht wird.

kautz
28.02.2005, 20:52
Ok,
wer lesen kann ist im Vorteil:


#include <avr/io.h>
#define F_CPU 8000000
#define F_OSC 3686400 /* Oszillator-Frequenz in Hz */
#define UART_BAUD_RATE 9600
#define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_OSC)/((UART_BAUD_RATE)*16)-1)
typedef union {
uint16_t i16;
struct {
uint8_t i8l;
uint8_t i8h;
};
} convert16to8;


int main (void)
{
UCSRB=0x04;

convert16to8 baud;
baud.i16 = F_CPU / (UART_BAUD_RATE * 16L) -1;
UBRRH = baud.i8h;
UBRRL = baud.i8l;

//UBRRH=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_OS C)>>8);
//UBRRL=(uint8_t)UART_BAUD_CALC(UART_BAUD_RATE,F_OSC );
while (!(UCSRA & (1<<UDRE)));
UDR = 'x';

}
Sorry, ich war etwas voreilig beim posten.
Danke für alles!!!

Kjion
28.02.2005, 21:55
Hi,

du brauchst es gar nicht so kompiliziert zu machen:


#include <avr/io.h>
#define F_CPU 3686400L /* Oszillator-Frequenz in Hz */
#define BAUD_RATE 9600L
#define UART_BAUD_RATE 9600
#define UART_BAUD ((F_CPU)/((UART_BAUD_RATE)*16L)-1)

int main (void)
{
UCSRB=0x04;
UBRRH=(uint8_t) (UART_BAUD>>8);
UBRRL=(uint8_t) (UART_BAUD & 0x00ff);
while (!(UCSRA & (1<<UDRE)));
UDR = 'x';
}

F_CPU wird übrigens seit dem neusten WinAVR Release im Makefile definiert. Dann braucht man es nicht mehr im Hauptprogramm zu tun...

MfG Kjion

PicNick
01.03.2005, 09:04
Is absolut richtig, ich schreib aber (wenn geht)
registerH = HIGH(Value)
registerL = LOW(Value)
das spart Hirn, find' ich. Ich will das aber keinem einreden