Hallo,
ich versuche gerade, einen ATmega88 gegen einen ATmega168 zu tauschen.
Dabei gibt's Probleme mit dem UART. Der folgende Code funktioniert beim
Atmega88 wunderbar, beim ATmega168 aber nicht:
1 | #include <stdlib.h>
|
2 | #include <avr/io.h>
|
3 | #include <avr/interrupt.h>
|
4 | #include <inttypes.h>
|
5 |
|
6 | #define F_CPU 18432000
|
7 | #define __OPTIMIZE__
|
8 |
|
9 | // Baudrate
|
10 | #define BAUD 115200
|
11 |
|
12 | // Berechnungen zur Baudrate:
|
13 | #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden
|
14 | #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
|
15 | #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
|
16 |
|
17 | #if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
|
18 | #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
|
19 | #endif
|
20 |
|
21 | //Forwarddeklarationen
|
22 | void USART_Init( unsigned int ubrr);
|
23 | void USART_Transmit( unsigned char data);
|
24 | unsigned char USART_Receive( void );
|
25 |
|
26 | char text1[4];
|
27 |
|
28 | int main()
|
29 | {
|
30 | //USART initialisieren
|
31 | USART_Init(UBRR_VAL);
|
32 | uint8_t i=0;
|
33 |
|
34 | while(1)
|
35 | {
|
36 | i++;
|
37 | itoa(i, text1, 16);
|
38 | USART_Transmit(text1[0]);
|
39 | USART_Transmit(text1[1]);
|
40 | USART_Transmit(0x0A); //LF
|
41 | USART_Transmit(0x0D); //CR
|
42 | }
|
43 | return 0;
|
44 | }
|
45 |
|
46 | void USART_Init( unsigned int ubrr)
|
47 | {
|
48 | //Set baud rate
|
49 | UBRR0H = (unsigned char)(ubrr>>8);
|
50 | UBRR0L = (unsigned char)ubrr;
|
51 | //Enable receiver and transmitter
|
52 | UCSR0B = (1<<RXEN0)|(1<<TXEN0);
|
53 | // Set frame format: 8data, 2stop bit
|
54 | UCSR0C = (1<<USBS0)|(3<<UCSZ00);
|
55 | }
|
56 |
|
57 | void USART_Transmit( unsigned char data )
|
58 | {
|
59 | //Wait for empty transmit buffer
|
60 | while ( !( UCSR0A & (1<<UDRE0)) );
|
61 | //Put data into buffer, sends the data
|
62 | UDR0 = data;
|
63 | }
|
64 |
|
65 | unsigned char USART_Receive( void )
|
66 | {
|
67 | // Wait for data to be received
|
68 | while ( !(UCSR0A & (1<<RXC0)) );
|
69 | // Get and return received data from buffer
|
70 | return UDR0;
|
71 | }
|
die Routinen USART_Init, USART_Transmit und USART_Receive habe ich aus
dem Datenblatt zum ATmega 48/88/168 entnommen, die Application Note
"AVR095 - Migrating between ATmega48, 88 and 168" ist mir bekannt - sie
enthält leider nichts, was auf einen Unterschied am UART zwischen den 3
Prozessoren hinweisen würde. Andere Baudraten oder
Stopbitkonfigurationen funktionieren mit dem ATmega88 auch, nicht aber
mit dem 168. Ich benutze AVR Studio und achte darauf, mein device
richtig einzustellen, wenn ich den Prozessor wechsle, auch am Programmer
(usbprog am ISP) stelle ich immer zwischen dem 88 und dem 168 um.
... Weiss jemand, was ich noch ändern könnte ? - Oder, was ich übersehen
habe?