Forum: Mikrocontroller und Digitale Elektronik ATmega8 USART


von Frank (Gast)


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
}

von Karl H. (kbuchegg)


Lesenswert?

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?

von Frank (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Huch (Gast)


Lesenswert?

Nimm 'nen Quarz.

von Frank (Gast)


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?

von Frank (Gast)


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!

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.