ATmega8 USART

Gast #2038168
Hallo, hab da ne Frage zu Atmega8 und USART/RS232:

Ich versuche vom PC mit HTerm mehrere Zeichen an den ATmega zu senden. 
Der soll die Zeichen kurz speichern und wieder zurücksenden. Sende ich 
jedes Zeichen einzeln vom PC aus geht das auch. Gebe ich alle Zeichen 
ein und gehe dann auf senden kommt der Atmega nicht mehr hinterher. Also 
es kommen nicht alle Zeichen so zurück wie ich sie hingesendet hab.

Um die Standard Frage schonmal zu beantworten: Ja, ich benutze einen 
Quarz.

Was mache ich falsch?

Gruß
Frank

Hier noch der Code:
1
#define F_CPU 8000000UL  // Systemtakt in Hz - Definition als unsigned long beachten 
2
#include <stdint.h>
3
#include <util/delay.h>
4
#include <avr/io.h>
5
#include <avr/interrupt.h>
6

7

8
#define BAUD 4800UL      // Baudrate
9
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
10
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
11
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
12
 
13
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
14
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
15
#endif
16

17

18
void uart_init(void)
19
{
20
  UCSRB |= (1<<TXEN)|(1<<RXEN)|(1<<RXCIE);  // UART TX einschalten
21
  UCSRC |= (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)|(1<<UPM1);  // Asynchron 8N1 
22

23
  UBRRH = UBRR_VAL >> 8;
24
  UBRRL = UBRR_VAL & 0xFF;
25
}
26

27
void uart_senden_c(char zeichen)
28
{
29
  while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich                   */
30
    {
31
    }
32
  
33
  UDR = zeichen;
34
  
35
  return;
36
}
37

38

39
char daten[100];
40
uint8_t volatile anz_daten = 0;
41
uint8_t volatile rxFinish = 0;
42

43

44

45
ISR(USART_RXC_vect)
46
{
47
  
48
  daten[anz_daten] = UDR;
49
  if(daten[anz_daten] == 'a')
50
  {
51
    rxFinish = 1;
52

53
  }
54
  else
55
  {
56
    anz_daten++;
57
    daten[anz_daten] = '\0';
58
  }
59
  
60
}
61

62

63
int main()
64
{
65

66
  uint8_t pos = 0;
67
  uart_init();
68
  sei();
69

70

71
  while(1)
72
  {
73
  
74
    if(rxFinish == 1)
75
    {
76
      cli();
77
      uart_senden_c('!');
78
      while(pos <= anz_daten)
79
      {
80
        uart_senden_c(daten[pos]);
81
        pos++;
82
      }
83
      pos = 0;
84
      anz_daten = 0;
85
      rxFinish = 0;
86
      sei();
87
    }
88

89

90
    
91
  }
92

93
  return 0;
94
}
Frank schrieb:

> ein und gehe dann auf senden kommt der Atmega nicht mehr hinterher. Also
> es kommen nicht alle Zeichen so zurück wie ich sie hingesendet hab.

Kannst du das näher präzisieren?
Was bedeutet 'alle'? Ist das erste Zeichen falsch, das letzte? Was 
sendest du hin, was kriegst du zurück?
Gast
Beispiel:

Ich sende blaaa. Wenn ein a gesendet wird sollte er eigentlich alles 
wieder zurücksenden. Ergebnis is auf den Screenshot zu sehen. Das ! 
markiert übrigens den Übertragungsbeginn vom ATmega.
Angehängte Dateien:
Gast
Ich hab jetzt festgestellt, dass es am Stopbit liegt.

Ich will eine Übertragung mit 1 Stopbit machen. Der AVR empfängt die 
Daten aber nur richtig, wenn ich 2 Stopbits sende.

Laut Datenblatt braucht der Atmega8 nur 1 Stopbit. Das kann man auf der 
Empfansseite auch nicht einstellen. Nur in Senderichtung kann man die 
Anzahl der Stopbits festlegen.

Woran könnte das liegen? Wie bekomme ich das hin, dass Daten mit einem 
Stopbit vom AVR richtig empfangen werden?
Gast
Ich hatte in letzter Zeit viel zu tun und bin heute dazu gekommen mir 
den Code noch mal angeguckt. Da ist mir aufgefallen, dass ich ein 
Paritätsbit in der Initialisierung vom USART einstelle. Ich frag mich 
wie ich das übersehen konnte, aber es liegt ja oft an so einfachen 
Fehlern.

Jetzt funktioniert es!

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 15 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.