Forum: Mikrocontroller und Digitale Elektronik USART anpassen Atmega8 -> Atmega168


von Thomas G. (Gast)


Lesenswert?

Hallo,

möchte mein Programm vom Atmega8 auf den Atmega168 zum laufen bringen. 
Ich lese Daten von einem GPS-Empfänger mit der USART Schnittstelle aus. 
Auf dem Atmega168 sind die empfangenen Daten jetzt jedoch teilweise 
falsch (teilweise stimmts).

Hier mein Code vom Atmega8:
1
//---------------------
2
//  USART.h
3
//---------------------
4
#ifndef _USART_H_
5
#define _USART_H_
6
7
#define F_CPU 3686400
8
#define USART_BAUD_TEILER(baudRate,cpuClk) ((cpuClk)/((baudRate)*16l)-1)
9
10
#include <avr/io.h>
11
#include <avr/interrupt.h>
12
13
void usart_init(unsigned int baudrate);
14
char usart_get_char(void);
15
16
#endif
1
//---------------------
2
// USART.c
3
//---------------------
4
#include "usart.h"
5
6
void usart_init(unsigned int baudrate)
7
{
8
  UBRRH = (unsigned char)(baudrate>>8);
9
    UBRRL = (unsigned char) baudrate;
10
11
    // Enable USART: Empfänger
12
    UCSRB = (1<<RXEN); //UCSRB = (1<<RXCIE)|(1<<RXEN); 
13
    
14
    //Frame Format: asynchron, 8bit, no parity, 1stop bit
15
    UCSRC = (1<<URSEL)|(3<<UCSZ0);
16
}
17
18
19
char usart_get_char(void)
20
{    
21
  char zeichen;
22
23
  while(!(0x80 & UCSRA))
24
  {}
25
  
26
  zeichen = UDR;
27
  return zeichen;
28
}

USART.c habe ich für den Atmega168 folgendermaßen angepasst:
1
//---------------------
2
// USART.c
3
//---------------------
4
5
#include "usart.h"
6
7
void usart_init(unsigned int baudrate)
8
{
9
  UBRR0H = (unsigned char)(baudrate>>8);  
10
    UBRR0L = (unsigned char) baudrate;    
11
12
    // Enable USART: Empfänger
13
    UCSR0B = (1<<RXEN0);
14
    
15
    //Frame Format: asynchron, 8bit, no parity, 1stop bit
16
  UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
17
}
18
19
char usart_get_char(void)
20
{    
21
  char zeichen;
22
23
  while(!(0x80 & UCSR0A))
24
  {}
25
  
26
  zeichen = UDR0;
27
  return zeichen;
28
}

Die init-Funktion rufe ich dann so auf:
1
   usart_init(USART_BAUD_TEILER(4800,F_CPU));

Bin schon seit ewig am Fehlersuchen... wäre super wenn mal jemand drauf 
schauen könnte... oder hat jemand eine Idee, was ich beim Anpassen noch 
beachten muss?

Gruß Thomas

von ... (Gast)


Lesenswert?

die Fuse /8 gesetzt?

von ... (Gast)


Lesenswert?

was ist 0x80 in
while(!(0x80 & UCSR0A)) ?

sollte das nicht so aussehen:

/* Wait for data to be received */
while ( !(UCSR0A & (1<<RXC0)) )

von Thomas G. (Gast)


Lesenswert?

Vielen Dank, das war ein guter Hinweis! Mit "while (!(UCSR0A & 
(1<<RXC0)))" funktioniert es :-) super!

von Stefan E. (sternst)


Lesenswert?

Thomas G. schrieb:
> Vielen Dank, das war ein guter Hinweis! Mit "while (!(UCSR0A &
> (1<<RXC0)))" funktioniert es :-) super!

Sorry, aber das ist Unsinn. Das ist bloß eine andere Schreibweise deiner 
Variante (allerdings die bessere). Wenn diese Zeile in deinem Code 
falsch gewesen wäre, dann hätte es gar nicht funktioniert, aber nicht:
> teilweise falsch (teilweise stimmts).

Lass mich raten, du verwendest beim Mega168 den internen RC-Oszillator, 
oder? Der ist zu ungenau und dann kann genau so was passieren:
> teilweise falsch (teilweise stimmts).
Dass es jetzt geht liegt dann eher daran, dass er heute Abend etwas 
weniger daneben liegt, als heute Mittag (z.B. wegen einer anderen 
Temperatur).

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.