UART bei ATmega/88 Atmega168

Gast #1382082
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?
#1382366
Zwar keine Antwort auf Deine Frage, aber eine Anmerkung:
1
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
wird für Baudrates zwischen 4096 und 65535 falsche Werte liefern 
(Integer-Überlauf).  Verwende doch einfach die Makros aus 
<util/setbaud.h>.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.