ATmega8 USART

Gast #2038168
Lesenswert?

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
}
Gast #2048896
Lesenswert?

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 #2069666
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren