Har gjort en massa ändringar i ett program. Bytt kristall från 19.66080 MHz till 3.6864 MHz samt ändrat och joxat o det mesta. En skillnad var även att jag valde att skala ner frekvensen för CPU till 1/4 av oscillatorfrekvensen för att spara ström. Så CPU kör på 0.9216 MHz (med hjälp av CLKPR).
Då börjar UART att köra på fel frekvens... den var inställd på 38.400 baud men kör i verkligheten på 19.200.
Det började med att jag upptäckte att F_CPU och F_OSC inte var samma sak. Enligt databladet till ATMega644 är F_OSC själva oscillatorfrekvensen medans F_CPU är den nerskalade CPU-frekvensen.
Eftersom jag hade använt F_CPU för att beräkna baudrate så blev ju det fel. Så jag skapade en ny symbol F_OSC som jag satte till oscillatorfrekvensen.
Så här ser initiering av UART ut:
Kod: Markera allt
#define F_OSC = 3686400UL
#define BAUDRATE = 38400UL
void uart0_init(void) { // ----- initiera UART0 -----
#define BAUD_PRESCALE (F_OSC/(16*BAUDRATE)-1)
UBRR0L = BAUD_PRESCALE & 0xff;
UBRR0H = (BAUD_PRESCALE >> 8);
UCSR0C = (1 << UCSZ00) | (1 << UCSZ01); // Use 8-bit character sizes
UCSR0B = (1<<TXEN0)|(1<<RXEN0)|(1<<RXCIE0); // starta usart+recieve interrupt
sei(); // aktivera global interruptflagga
}
(U2X0 är en flagga i UCSR0A som dubblar UART-hastigheten om den är ettställd. UCSR0A rörs ej, så flaggan behåller sitt initieringsvärde som är 0).
Så nu undrar jag vad jag har glömt eller missat.... för den ska köra med 38400 baud med dessa settings! Och jag vill inte lösa problemet genom att skriva in fel klockfrekvens eller ändra i formlen.
Jag kollade för säkerhets skull på kristallen. Jodå, det står 3.6864.
Kan tillägga att jag använt exakt samma kod för UART i alla mina projekt i ett par år nu, och det har aldrig blivit fel förut.
EDIT: sjutton också! flyttade runt lite kommentarer i koden och kompilerade om. Nu kör den på 9600 baud... helt otroligt. Vad håller den på med?

Nu börjar jag undra alltså... delas UART-frekvensen också till 1/4 när man sätter CLKPR så att F_CPU blir F_OSC/4.... ser ju ut så just nu, men det är väl en slump...
