Forum: Mikrocontroller und Digitale Elektronik UART Problem mit ATTiny2313


von Jan G. (jan80)


Lesenswert?

Ich habe ein kleines Problem mit dem UART (USI) beim Attiny2313. 
Grundsätzlich funktioniert die Datenübertragung absolut einwandfrei. Ich 
werde die serielle Schnittstelle, um Daten an einen Raspberry Pi (3,3V 
Logik, kein Pegelwandler oÄ erforderlich) zu übertragen. Auf dem Pi 
läuft die Automatisierungssoftware openHAB, die die Daten dann 
auswertet. Dabei kommt es leider häufig vor, dass die Verzögerung 
zwischen dem 8. und 9. Byte der Übertragung größer ist als zwischen den 
übrigen Bytes. openHab interpretiert dies als neue Übertragung. Der 
betreffende Code sieht so aus:

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

Initialisierung
1
UCSRB |= (1<<RXEN);
2
UCSRB |= (1<<TXEN);
3
UBRRH = UBRR_VAL >> 8;
4
UBRRL = UBRR_VAL;


Funktion
1
static uint8_t uart_putc(unsigned char c)
2
{
3
  while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
4
  {
5
  }
6
  
7
  UDR = c;                      /* sende Zeichen */
8
  return 0;
9
}

Übertragung
1
cli();
2
for (int x = 0; x < buffersize; x++) {
3
  uart_putc(buffer[x]);
4
  buffer[x] = 0;
5
  }
6
sei();

Hat jemand eine Idee, wordurch diese unterschiedlichen Latenzen zustande 
kommen???

von g457 (Gast)


Lesenswert?

> Verzögerung zwischen dem 8. und 9. Byte der Übertragung

Um wieviel größer? Ich tippse auf RX-FIFO im Pi oder anderweitig 
fehlerbehaftete Zeitverstempelung.

von Jan G. (jan80)


Lesenswert?

Um wie viel kann ich nicht sagen. Ich sehe halt nur, dass für openHAB 
die Übertragung abgeschlossen ist. Und das entspricht dem Verhalten, 
dass ich sehe, wenn ich händisch eine Verzögerung einbaue. Eine 
Microsekunde reicht da schon. Wenn es der FIRO im Pi ist, kann ich 
wahrscheinlich nicht viel machen, oder?

von Uwe (de0508)


Lesenswert?

Hallo ja,

der Attiny2313 hat kein (USI) !

von g457 (Gast)


Lesenswert?

> Ich sehe halt nur, dass für openHAB die Übertragung abgeschlossen ist.
> [..] Eine Microsekunde reicht da schon.

Klingt wie ein krankes Protokoll. Steig um auf was vernünftiges [0], das 
Timing als Paketmarker ist komplett fehlangebracht [1].

HTH

[0] z.B. was mit Start-Ende-Kennungen
[1] vergleiche die Übertragungszeit für ein einzelnes Zeichen, die ist 
hier etwa 1ms - das ist Eintausendmal länger!

von Spess53 (Gast)


Lesenswert?

Hi

>der Attiny2313 hat kein (USI) !

Dann lügt mein Datenblatt.

MfG Spess

von Jan G. (jan80)


Lesenswert?

@g457: Ich habe Quatsch geschrieben, gemeint war natürlich eine 
Milisekunde, nicht Mikro. Dürfte mit UART sonst auch nicht abbildbar 
sein.
Das Protokoll kann ich mir ja nicht wirklich aussuchen, dann müsste ich 
die ganze Lösung wechseln.

von Florian T. (florian_t)


Lesenswert?

Ich tippe mal auf das clevere runden. Ab dem 08. Byte ist der 
Rundungsfehler dann so groß, dass eine zu große Lücke entsteht. Hast Du 
mal versucht F_CPU anzupassen? Nimmst du einen normalen Quartz, oder 
einen Oszillator?

von Jan G. (jan80)


Lesenswert?

Ich nehme einen normalen Quarz. F_CPU habe ich gerade mal in kleineren 
Schritten sowohl nach oben als auch nach unten so lange angepasst, bis 
die Datenübertragung fehlschlägt. Das Problem bestand immer unverändert. 
Wenn ich das richtig verstanden habe, ist der Quarz, den ich verwende, 
doch ein Baudratenquarz und es müsste gar nicht groß gerundet werden, 
oder liege ich da falsch?

von Thomas E. (thomase)


Lesenswert?

Florian Trück schrieb:
> Ich tippe mal auf das clevere runden.
Quatsch.
11059200Hz ist ein Baudratenquarz. Da wird gar nichts gerundet.

mfg.

von g457 (Gast)


Lesenswert?

> Das Protokoll kann ich mir ja nicht wirklich aussuchen, dann müsste ich
> die ganze Lösung wechseln.

Afaik unterstützt openHAB so ziemlich alles an Protokollen und ist sogar 
problemlos um eigene erweiterbar. Kannst ja was ganz primitives machen, 
sowas wie 'Klartext mit \n als Ende-Marker'. Oder das vorhandene 
Protokoll um eine High-Level-Paketerkennung erweitern, die sich nicht an 
den Grenzen der einzelnen 'Status Updates' aufhängt.

von Jan G. (jan80)


Lesenswert?

Daran habe ich auch schon gedacht. Leider sind ist es um meine 
Java-Kenntnisse nicht gut bestellt. Ich habe das Problem gestern in der 
openHAB Newsgroup gepostet. Einer der Programmierer wollte sich das 
ansehen und eventuell den Code so umbauen, dass nach dem letzten Zeichen 
noch ein paar ms auf weitere gewartet wird. Der entsprechende Code sieht 
zZ so aus

while (dataavailable){
do stuff
}

Und anscheinend gibt es irgendwo den Punkt, an dem aus Sicht von openHAB 
keine weiteren Daten mehr verfügbar sind...

von Jan G. (jan80)


Lesenswert?

Ich habe die Berechung von UBRR mal angepasst
1
//UART
2
#define BAUD 9600UL          // Baudrate
3
4
5
// Berechnungen
6
#define UBRR_VAL ((F_CPU/(16*BAUD))-1)  // runden nicht nötig, wegen Baudratenquarz
7
//#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
8
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
9
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
10
11
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
12
#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
13
#endif

Die eingestellte Baudrate sollte jetzt genau 9600 sein. Leider hat das 
das Problem auch nicht gelöst, aber vielleicht ist die Info ja für 
jemand anderes von Nutzen. Das UARt Tutorial fand ich sehr hilfreich.

http://www.mikrocontroller.net/articles/AVR-Tutorial:_UART

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.