Hallo
ich habe folgendes Problem. Ich benutze einen Atmega644 und will über
die Usart daten schreiben. Leider bekomme ich aber nur nullen zurück
(mittels Free Serial Prot Monitor). Der mC ist mit einem 14.756 Quarz
geregelt und die F_CPU ist auf 14745600 HZ eingestellt.Hier der
Quelltext:
uart.c :
#include "uart.h"
void init_uart(void)
{
int baud = BAUD;
#if F_CPU <= 1000000UL
UBRR0H = (uint8_t) ((F_CPU / (8 * baud)) - 1)>>8;
UBRR0L = (uint8_t) (F_CPU / (8 * baud)) - 1;
#else
UBRR0H=(uint8_t)((F_CPU / (16 * baud)) - 1)>>8;
UBRR0L=(uint8_t)(F_CPU / (16 * baud)) - 1;
#endif
UCSR0C = (1<<UCSZ01) | (1<<UCSZ00); // Asynchron 8N1
UCSR0B = (1<<TXEN0) | (1<<RXEN0); // tx & rx enable
}
void uart_putc(unsigned char c)
{
while (!(UCSR0A & (1<<UDRE0))) /* warten bis Senden moeglich */
{}
UDR0 = c;
}
uart.h :
#ifndef uart_h
#define uart_h
#include<avr/io.h>
#define BAUD 9600UL
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden
void init_uart(void);
int uart_putc(unsigned char c);
void uart_puts (char *s);
#endif
main.c :
#include<stdio.h>
#include<avr/io.h>
#include <util/delay.h>
#include "uart.h"
int main(void)
{
init_uart();
_delay_ms(10);
uart_putc('=');
while(1)
{
uart_putc('=');
}
return 0;
}
Jemand eine Idee ?
Vielen Dank im voraus
Alex
Alex wrote: > #if F_CPU <= 1000000UL > UBRR0H = (uint8_t) ((F_CPU / (8 * baud)) - 1)>>8; > UBRR0L = (uint8_t) (F_CPU / (8 * baud)) - 1; > #else > UBRR0H=(uint8_t)((F_CPU / (16 * baud)) - 1)>>8; > UBRR0L=(uint8_t)(F_CPU / (16 * baud)) - 1; > #endif Hä? Die Baudratenberechnung ist doch völlig unabhängig von der tatsächlichen Taktfrequenz immer gleich, oder ist das bei einem 644 anders? Das einzige was einen Unterschied machen könnte, wäre wenn U2X gesetzt wird. Aber das ist in deinem Code nicht der Fall.
Beim Quarz habe ich den Fuse auf Ext. Crystal Osc. 8.0- MHz; Start-up time: 16K CK + 65 ms stehen. und Karl du hast recht den Teil UBRR0H = (uint8_t) ((F_CPU / (8 * baud)) - 1)>>8; UBRR0L = (uint8_t) (F_CPU / (8 * baud)) - 1; hätte ich auch weglassen können da mein Programm hier nie hinspringen wird. Aber ich verstehe trotzdem nicht wieso ich nur 0 zurückbekommen (egal was ich an die uart_putc() übergebe es kommen nur 0 an.
Kontrolliere, ob dur F_CPU korrekt gesetzt hast. Code anders strukturiert und mit bewährter Berechnung aus AVR-GCC-Tutorial: uart.c
1 | /*** uart.c ***/
|
2 | #include <avr/io.h> |
3 | #include "uart.h" |
4 | |
5 | void init_uart(void) |
6 | {
|
7 | UBRR0H = (unsigned char)(UBRR_VAL>>8); |
8 | UBRR0L = (unsigned char)(UBRR_VAL); |
9 | UCSR0B = (1<<TXEN0) | (1<<RXEN0); // tx & rx enable |
10 | UCSR0C = (1<<UCSZ01) | (1<<UCSZ00); // Asynchron 8N1 |
11 | }
|
12 | |
13 | void uart_putc(unsigned char c) |
14 | {
|
15 | while (!(UCSR0A & (1<<UDRE0))) |
16 | {
|
17 | /* warten bis Senden moeglich */
|
18 | }
|
19 | UDR0 = c; |
20 | }
|
uart.h
1 | /*** uart.h ***/
|
2 | #ifndef uart_h
|
3 | #define uart_h
|
4 | |
5 | #define BAUD 9600UL // Baudrate
|
6 | |
7 | #ifndef F_CPU
|
8 | #warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 14745600UL"
|
9 | #define F_CPU 14745600UL // Systemtakt in Hz
|
10 | // Definition als unsigned long beachten
|
11 | // Ohne UL ergibt Fehler in der Berechnung
|
12 | #endif
|
13 | |
14 | // Berechnungen
|
15 | #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden
|
16 | #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
|
17 | #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)
|
18 | // Fehler in Promille, 1000 = kein Fehler
|
19 | |
20 | #if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
|
21 | #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
|
22 | #endif
|
23 | |
24 | void init_uart(void); |
25 | void uart_putc(unsigned char c); |
26 | #endif /* uart_h */ |
main.c
1 | /*** main.c ***/
|
2 | #include <avr/io.h> |
3 | #include <util/delay.h> |
4 | #include "uart.h" |
5 | |
6 | int main(void) |
7 | {
|
8 | init_uart(); |
9 | _delay_ms(10); |
10 | |
11 | uart_putc('#'); // vor while |
12 | |
13 | while(1) |
14 | {
|
15 | uart_putc('='); // in while |
16 | }
|
17 | |
18 | return 0; |
19 | }
|
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.