Forum: Mikrocontroller und Digitale Elektronik UART - Baudrate stimmt nicht überein (ATmega48)


von Johannes L. (johannes_l37)


Angehängte Dateien:

Lesenswert?

Guten Tag, ich versuche zur Zeit mit meinem ATmega48 eine Zeichenkette 
über UART zu senden, das klappt an und für sich ganz gut, allerdings 
stimmt die Baudrate nicht, ich will eine Baudrate von 9600L einstellen, 
allerdings steht sie auf immer auf 1200 (nur wenn ich mit TerraTerm auf 
1200 empfange, bekomme ich die Zeichen wieder rein), ich bin noch ein 
ziemlicher Anfänger, was programmieren angeht :)
Hier der Code:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <string.h>
4
//Fuer Baudrate
5
#define FOSC 8000000UL // Clock Speed
6
#define BAUD 9600L
7
#define UBRR ((FOSC / (BAUD * 16L)) - 1)
8
//Fuer Baudrate - ende
9
10
11
void setup()
12
{
13
  cli(); // Interrupts deaktiviert - sicherheitshalber
14
15
    DDRC &= ~(0x01);
16
    PORTC &= ~(0x01);
17
18
//Baud Raten einstellungen usw.
19
    UBRR0H = (unsigned char)(UBRR>>8);
20
    UBRR0L = (unsigned char)UBRR;
21
    /*aktiviere Sender und empfänger (uART)*/
22
    UCSR0B = (1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0) | (1 << UDRIE0);
23
    // frame format: 8data, 1stop bit
24
    UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
25
26
27
////////////////////////////////////////////
28
29
30
    ADMUX = 0xC0;
31
    ADCSRA = 0x9A;
32
33
    //INT0 + INT1
34
    EICRA = 0x0F;// Worauf reagiert der jeweilige Interrupt?
35
    EIFR = 0x03; //???? pc?
36
    EIMSK = 0x02; // Interrupts aktivieren
37
38
    TCCR1A = 0x00; // Normal Mode
39
    TCCR0B = 0x00; // Prescaller hier Timer/counter gestoppt
40
    //TCCR1B = 0x02; //Damit Prescaller auf 8 und timer Counter wieder aktiv
41
    TCCR1C = 0x00; // nur für non PWM-mode
42
    TCNT1 = 0;    //Zähl register
43
}//ende von Setup (Initalisierung)
44
45
int uart_putc(unsigned char str)
46
{
47
    while (!(UCSR0A & (1<<UDRE0)))  /* warten bis Senden moeglich */
48
    {
49
    }
50
51
    UDR0 = str;                      /* sende Zeichen */
52
    return 0;
53
}
54
55
/* puts ist unabhaengig vom Controllertyp */
56
void uart_puts (char *s)
57
{
58
    while (*s)
59
  s= "t" ;
60
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
61
        uart_putc(*s);
62
        s++;
63
    }
64
}
65
66
int main(void)
67
{
68
setup() ; // Initialisierung
69
//Beginne zu senden, UART
70
for (uint8_t i=0; i<=3; ++i) {
71
int len;
72
char str[3];
73
74
strcpy(str, "123");
75
len = strlen(str);
76
    uart_putc ( str[i] );
77
   // verkuerzt: uart_putc( i + '0' );
78
}
79
//Ende von senden Uart.
80
while (1) {
81
   //Unendlichkeitsschleife ... (warten auf Interrupts? Andere Befehle?)
82
}
83
84
return 0; // never reached
85
86
}//ende von Main
87
88
//Ende vom Code.
PS: Ich arbeite mit Eclipse und AVR Studio 4. (alt aber bevorzugt)

von Coder (Gast)


Lesenswert?

Ich vermute mal, dass die CLKDIV8 Fuse gesetzt, wenn du beim TeraTerm 
beim 1/8 der geünschten Baudrate vernüftigt Zeichen empfangen kannst.

von Johannes L. (johannes_l98)


Lesenswert?

An den Fuses habe ich an und für sich nichts geändert, ich danke dir 
ersteinmal für deine schnelle Antwort und werde die Fuses Montag mal 
überprüfen. (Würde ich gerne jetz machen, habe den ATmega aber woanders 
liegen gelassen.) Bis dahin, frohes Wochenende

von Johannes L. (johannes_l37)


Lesenswert?

Vielen dank, jetz funktioniert das ganze auch mit der richtigen Baud 
Rate :)
Von den Fuses hab ich (noch) keine Ahnung.

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.