Forum: Mikrocontroller und Digitale Elektronik USART überträgt falsche Zeichen


von TM F. (p_richner)


Angehängte Dateien:

Lesenswert?

Hallo Zusammen

Ich versuche die Kommunikation zwischen uC Atmega 1284p mit 16MHz und PC 
über USART. Dabei benutze ich folgendes Programm, wobei dies 
grösstenteils dem Beispiel aus dem Datenblatt entspricht.
Das Problem liegt darin, dass komplett falsche Zeichen ausgegeben 
werden. Ich sehe jedoch nicht weiter, wo das Problem liegen könnte.

Im Anhang ist die Ausgabe vom Putty Terminal. Dieses habe ich auf eine 
Baudrate von 9600 eingestellt, Parity: none, Flow Control: XON/XOFF, 8 
Datenbit, 1 Stopbit
1
void USART_init( void )
2
{
3
  // Initialize the whole USART
4
  // Set the baud rate value
5
  uint16_t baud = 9600;
6
  // Set baud rate 
7
  UBRR0H = (unsigned char)(baud>>8);
8
  UBRR0L = (unsigned char)baud;
9
  // Set the XCK0 pin to output
10
  DDRB   = 0x01;
11
  // Enable receiver and transmitter 
12
  UCSR0B |= (1<<RXEN0)|(1<<TXEN0);
13
  // Set frame format: 8data, 1stop bit and synchronous mode 
14
  UCSR0C |= (1<<UCSZ01) | (1<<UCSZ00) | (1<<UMSEL00);
15
}
16
17
void USART_transmit( unsigned char data )
18
{
19
  // Send the data to the PC
20
  // Wait for empty transmit buffer  
21
  while ( !( UCSR0A & (1<<UDRE0)) )
22
  ;
23
  // Put data into buffer, sends the data  
24
  UDR0 = data;
25
}
26
27
int main(void)
28
{
29
  USART_init();
30
    while (1) 
31
    {  
32
    if(TASTER_EINGANG)
33
      USART_transmit('A');
34
35
    }
36
}

: Bearbeitet durch User
von Peter II (Gast)


Lesenswert?

welche Taktquelle hast du am Atmega?

von Cyblord -. (cyblord)


Lesenswert?

Baudrate wird völlig falsch gesetzt. Schaue bitte ins Datenblatt was in 
UBRR rein muss und wie das aus der Baudrate berechnet wird.

von Peter II (Gast)


Lesenswert?

TM F. schrieb:
> uint16_t baud = 9600;
>   // Set baud rate
>   UBRR0H = (unsigned char)(baud>>8);
>   UBRR0L = (unsigned char)baud;

das kann doch nicht funktionieren, ließ mal das Datenblatt was in UBRR0 
für ein Wert rein muss.

von TM F. (p_richner)


Angehängte Dateien:

Lesenswert?

Peter II schrieb:
> das kann doch nicht funktionieren, ließ mal das Datenblatt was in UBRR0
> für ein Wert rein muss.

Ok danke.

Ich habe mal 103 in dieses Register geschrieben und den Modus in den 
asynchronen gewechselt und jetzt funktioniert es:)

Habe den Baud-wert in der Initialisierung falsch interpretiert.

Danke für die schnelle Hilfe

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

TM F. schrieb:
> Ich habe mal 103 in dieses Register geschrieben

Das geht auch noch etwas portabler:
1
#define UART_BAUD_RATE 9600
2
...
3
   uint16_t baud = F_CPU / (UART_BAUD_RATE * 16L) -1;
4
5
   UBRRH = (uint8_t) (baud >> 8);
6
   UBRRL = (uint8_t) baud;

Da kommt dann für baud ebenso die 103 raus.

Vorteil: Solltest Du mal Deine UART-Routinen für einen AVR mit anderer 
Taktrate verwenden wollen, brauchst Du am Code nichts zu ändern. 
Dasselbe gilt für UART_BAUD_RATE. Bei einer Änderung auf 19200 ist 
lediglich das #define dafür zu ändern.

Es gibt noch weitere Optimierungsmöglichkeiten, wie zum Beispiel die 
Berücksichtigunge des U2X-Flags - falls der verwendete AVR dies hat.

von TM F. (p_richner)


Lesenswert?

Frank M. schrieb:
> Da kommt dann für baud ebenso die 103 raus.

Ok danke, dann mache ichs universell.

Frank M. schrieb:
> falls der verwendete AVR dies hat.

Ja das hat er.

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.