Hi, ich nutze hier diese Methode zur Berechnung: #define BAUD 9600l #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // das geht auch bei: #define F_CPU 800000 wunderbar. Doch bei 1Mhz ist das wohl nicht funktional. Ich nutze den Atmega168 bzw 48. Wenn jemand ein funktionierendes Beispiel hätte wäre das sehr hilfreich! Übrigens, was treibt der fleury hier: /*********************************************************************** ** Function: uart_init() Purpose: initialize UART and set baudrate Input: baudrate using macro UART_BAUD_SELECT() Returns: none ************************************************************************ **/ void uart_init(unsigned int baudrate) { UART_TxHead = 0; UART_TxTail = 0; UART_RxHead = 0; UART_RxTail = 0; #if defined( AT90_UART ) /* set baud rate */ UBRR = (unsigned char)baudrate; /* enable UART receiver and transmmitter and receive complete interrupt */ UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|_BV(TXEN); #elif defined (ATMEGA_USART) /* Set baud rate */ if ( baudrate & 0x8000 ) { UART0_STATUS = (1<<U2X); //Enable 2x speed baudrate &= ~0x8000; } UBRRH = (unsigned char)(baudrate>>8); UBRRL = (unsigned char) baudrate; /* Enable USART receiver and transmitter and receive complete interrupt */ UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN); /* Set frame format: asynchronous, 8data, no parity, 1stop bit */ #ifdef URSEL UCSRC = (1<<URSEL)|(3<<UCSZ0); #else UCSRC = (3<<UCSZ0); #endif #elif defined (ATMEGA_USART0 ) /* Set baud rate */ if ( baudrate & 0x8000 ) { UART0_STATUS = (1<<U2X0); //Enable 2x speed baudrate &= ~0x8000; } UBRR0H = (unsigned char)(baudrate>>8); UBRR0L = (unsigned char) baudrate; /* Enable USART receiver and transmitter and receive complete interrupt */ UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0); /* Set frame format: asynchronous, 8data, no parity, 1stop bit */ #ifdef URSEL0 UCSR0C = (1<<URSEL0)|(3<<UCSZ00); #else UCSR0C = (3<<UCSZ00); #endif #elif defined ( ATMEGA_UART ) /* set baud rate */ if ( baudrate & 0x8000 ) { UART0_STATUS = (1<<U2X); //Enable 2x speed baudrate &= ~0x8000; } UBRRHI = (unsigned char)(baudrate>>8); UBRR = (unsigned char) baudrate; /* Enable UART receiver and transmitter and receive complete interrupt */ UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN); #endif }/* uart_init */ da steige ich nicht durch. Der scheint es ohne F_CPU zu berechnen...? Gruß, Yve
Yvonne J. schrieb: > Hi, > > ich nutze hier diese Methode zur Berechnung: > > #define BAUD 9600l > #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // > > das geht auch bei: > > #define F_CPU 800000 > > wunderbar. Doch bei 1Mhz ist das wohl nicht funktional. Warum sollte das nicht funktional sein? > da steige ich nicht durch. Der scheint es ohne F_CPU zu berechnen...? er berechnet es gar nicht. > Input: baudrate using macro UART_BAUD_SELECT() er erwartet schon den umgerechneten Wert als Argument
> #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) //
Da fehlt die Rundung!
Faktor 2 höher rechnen und vor der Division +1 addieren. Das schaffst Du
schon!
Hallo Karl Heinz, wenn ich F_CPU auf 1Mhz setzte und das div8 Bit setze, dann kommt nur noch Grütze :-) Gruß, Yve
Yvonne J. schrieb: > was treibt der fleury hier > if ( baudrate & 0x8000 ) Na ohne Baudrate geht es bei ihm auch nicht. Aber je nach Chip guckt er nach ob das MSB gesetzt ist und verwendet den 2X-Mode. Rechne doch mal per Hand nach, welche Werte bei Dir rausrommen und welche rauskommen müssten. Läuft Dein Chip auch mit dem richtigen Speed? Sind die Fuses (8x) richtig gesetzt? Rick
Yvonne J. schrieb: > da steige ich nicht durch. Der scheint es ohne F_CPU zu berechnen...? Übergeben wird dieser Funktion nicht die Baudrate selbst, sondern schon der Wert des Baudratenregisters (mit dem Makro UART_BAUD_SELECT() berechnet). Der Aufruf sieht dann also z.B. so aus: uart_init( UART_BAUD_SELECT(19200,F_CPU) ); Also auch wieder mit F_CPU... Der Vorteil dabei ist, dass das Makro schon zur compile-Zeit berechnet wird.
Yvonne J. schrieb: > Hallo Karl Heinz, > > wenn ich F_CPU auf 1Mhz setzte und das div8 Bit setze, dann kommt nur > noch Grütze :-) Allerdings solltest du mal einen Blick ins Datenblatt riskieren. Da gibt es im USAR Kapitel Tabellen, bei denen auch für häufig benutzte Taktfrequenzen und Baudraten die UBRR Werte angegeben sind und auch die Fehler die durch in einer spezifischen Kombination entstehen. Alles über 3% Fehler ist nicht akzeptabel. Deine Kombination: 1Mhz / 9600 Baud hat 7% Fehler wenn U2X auf 0 bleibt Wenn du U2X auf 1 stellst, dann sinkt der Fehler auf nur noch 0.2% Dein Job: Den Code durchgehen und rausfinden, wie du die Lib dazu zwingen kannst U2X zu benutzen. Peter hat da schon was dafür vorgesehen.
Yvonne J. schrieb: > ich nutze hier diese Methode zur Berechnung: > > #define BAUD 9600l > #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // > > das geht auch bei: > > #define F_CPU 800000 > > wunderbar. Doch bei 1Mhz ist das wohl nicht funktional. Die Formel ist prinzipiell schon richtig. Aber bei 1MHz Takt und 9600 Baud ist der Fehler dann 7%, das ist viel zu viel. Du musst U2X aktivieren und die 16 in der Formel durch 8 ersetzen, wenn du diese Takt-/Baudraten-Kombination verwenden willst. Schau dir auch mal <util/setbaud.h> aus der avr-libc an, das nimmt dir die Berechnung ab, du brauchst dann nur noch die Werte in die Register schreiben. Ausserdem sorgt es dafür, dass du eine Compilerwarnung erhältst, wenn der Baudratenfehler zu gross wird. > Ich nutze den Atmega168 bzw 48. Wenn jemand ein funktionierendes > Beispiel hätte wäre das sehr hilfreich! Ein Beispiel steht in der Doku zu <util/setbaud.h> (http://www.nongnu.org/avr-libc/user-manual/group__util__setbaud.html). > Übrigens, was treibt der fleury hier: [...] > da steige ich nicht durch. Der scheint es ohne F_CPU zu berechnen...? Zur Parameterübergabe musst du hier eines der beiden Makros "UART_BAUD_SELECT" oder "UART_BAUD_SELECT_DOUBLE_SPEED" benutzen, darin steckt dann die Berechnung. In deinem Fall müsstest du das erste der beiden bei 8MHz und das zweite bei 1MHz verwenden. Andreas
...ich nutze keinen Quarz... spiele gerad rum: #define BAUD 9600l #define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1) #define UBRR_VAL UART_BAUD_SELECT(BAUD,F_CPU) hmmm
Yvonne J. schrieb: > ...ich nutze keinen Quarz... Das ist schon mal ein Fehler :-) > spiele gerad rum: > > #define BAUD 9600l > #define UART_BAUD_SELECT(baudRate,xtalCpu) > ((xtalCpu)/((baudRate)*16l)-1) > #define UBRR_VAL UART_BAUD_SELECT(BAUD,F_CPU) und weiter? Wie zwingst du die Fleury Lib U2X zu benutzen?
@ Yvonne J. (laserlight) >...ich nutze keinen Quarz... Ob das so ein gute Idee ist? http://www.mikrocontroller.net/articles/AVR_Checkliste#UART.2FUSART
...ich habe gerad versucht das Makro von Fleury für die oben aufgeführte Berechnung zu nutzen, also nicht für die Fleury lib... @ Andreas, das klingt interessant... ich schaue mich um. Gruß, Yve
@Falk, bei 8Mhz und mit der zuerst geposteten Berechnung, läuft es durchgehend 1A, ich habe mein F_CPU Define an eine globale Stelle genommen, und nun habe ich den Porzessor mal auf 1Mhz gestellt, und das Define entsprechend angepasst, es zieht auch alles mit, bis auf den UART. Jetzt suche ich nach einer Möglichkeit diese Sache auch soweit es geht mit zu automatisieren... Yve
@Tropenhitze, so wie ich das bis jetzt verstehe muss ich den 2X mode des Uarts mit ins Spiel holen, anders scheint es nicht zu gehen, wenn doch, bitte verdeutliche mal deinen Vorschlag. Yve
@ Yvonne J. (laserlight) >UART. Jetzt suche ich nach einer Möglichkeit diese Sache auch soweit es >geht mit zu automatisieren... Dann nimm dei Makros aus dem Tutorial und gut ist. Die spucken sogar einen Error, wenn das mit der Baudrate nicht klappt. http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_UART#UART_initialisieren MFG Falk
zu 2X mode .. in der lib ist das :
1 | if ( baudrate & 0x8000 ) |
2 | {
|
3 | UART0_STATUS = (1<<U2X); //Enable 2x speed |
4 | baudrate &= ~0x8000; |
5 | }
|
beachten muss man das die baudrate anders berechnet wird zB
1 | unsigned int ubrr = ( (F_CPU/(8*baud))-1); |
2 | UBRR1H = (unsigned char)(ubrr>>8); |
3 | UBRR1L = (unsigned char) ubrr; |
4 | UCSR1A |= (1<<U2X1); |
ohne u2x
1 | unsigned int ubrr = ( (F_CPU/(16*baud))-1); |
2 | UBRR1H = (unsigned char)(ubrr>>8); |
3 | UBRR1L = (unsigned char) ubrr; |
Es gibt immer wieder Leute, die wollen die Baudrate dem Compiler ueberlassen. Manch ein Programm scheitert so, bevor es begonnen hat. Dabei ist es ja nur eine Konstante, die man einmal vom Datenblatt her rechnen muss. Die meisten Datenblaetter haben sogar Tabellen fuer die Werte...
@ Hey noch Was (Firma: Mumpitz) (hacky) >Es gibt immer wieder Leute, die wollen die Baudrate dem Compiler >ueberlassen. Der Mensch ist von Natur aus faul. > Manch ein Programm scheitert so, bevor es begonnen hat. That's life. >Dabei ist es ja nur eine Konstante, die man einmal vom Datenblatt her >rechnen muss. Dumm nur, dass die Konstante fix mal vaiabel ist, wenn sich die Taktfrequenz ändert. > Die meisten Datenblaetter haben sogar Tabellen fuer die Werte... Mit allen möglichen Taktfrequenzen? Außerdem, der Compiler kann DEUTLICH mehr, als ne popelige Baudrate ausrechnen. MFG Falk
Hallo, Hey noch Was schrieb: > Es gibt immer wieder Leute, die wollen die Baudrate dem Compiler > ueberlassen. Manch ein Programm scheitert so, bevor es begonnen hat. > Dabei ist es ja nur eine Konstante, die man einmal vom Datenblatt her > rechnen muss. Die meisten Datenblaetter haben sogar Tabellen fuer die > Werte... und warum nicht? Dafür hat der GCC doch util/setbaud.h und das klappt auch... Gruß aus Berlin Michael
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.