Software UART

Gast #4710235
Lesenswert?
• ▲
▼
Hallo Leute,

hab eine quick and dirty version von Software UART programmiert. Die 
senden Routine funktioniert Einwand frei. Aber die Empfangsroutine 
nicht. Ich empfange immer nur eine 0x00. Mit dem Oszi sehe ich das der 
Pegel stimmt. Auch wenn ich den Ein auf einen Ausgang einfach weitergebe 
stimmt dieser Pegel. Im AVR-Studio funktioniert es auch so wie 
gewünscht. Wenn der Pin auf Low gezogen wird, wird 1.5 Bits gewartet und 
ab dann Per Interrupt die Routine aufgerufen.
Jemand eine Idee wo der Fehler ist. Wald vor lauter Bäumen?!

1
    SRXPORT  |= (1<<SRX);  // Pullup Aktiv gesetzt
2

3
void suart_empfangen(void)
4
{
5
  if(srx_done>0)
6
  {
7
    if(srx_done<9)
8
    {
9
      if ( SRXPIN & (1<<SRX) )
10
      {
11
        srx_tmp |=( 1<< (srx_done-1) );
12
      }
13
    }
14
    srx_done++;
15
    if(srx_done>=10)
16
    {
17
      srx_data[srx_count]=srx_tmp;
18
      srx_count++;
19
      srx_tmp=0;
20
      srx_done=0;
21
    }
22
  }
23
}
#4710248
Lesenswert?
• ▲
▼
Narbend,

Da fehlt doch die Hälfe des Quellcodes. So ist alles nur Rätselraten.
Wo ist "srx_tmp" deklariert, wo wird "srx_tmp" initialisiert?
Was ist der Startwert von "srx_done"? Wenn er denn 0 ist, wie zumindest 
der untere Teil vermuten lässt, dann ist in deinem Schnipsel keine 
Stelle zu sehen, an der "srx_done" mal auf einen Wert > 0 gesetzt wird.
Gast #4710263
Lesenswert?
• ▲
▼
Das läuft in meiner main. Die 1 ist im Pinzip mein Startbit und 
gleichzeitig die die Freigabe zur Abarbeitung meiner Empfangsroutine. 
Wollte mir zeit im Interrupt sparen.
1
void suart_getchar(void)
2
{
3
  if ( ( ( SRXPIN & (1<<SRX) ) ==0)& srx_done==0)
4
  {  
5
    TCNT0=SBAUD_TCNT_INIT;
6
    srx_done=1;
7
  }
8
}
#4710317
Lesenswert?
• ▲
▼
Mmn erfolgt bei dir das Abtasten der Bits nicht in der Bitmitte, sondern 
genau zum Bitwechsel, weil du den Timer mit der fallenden Flanke des 
Startbits mit einer Bitzeit +2(?) startest und nicht zunächst mal mit 
1,5 Bitzeiten, um genau zur Bitmitte abzutasten.
Weiterhin setzt du srx_tmp nie zurück. Da du nur die 1en reinschreibst, 
musst du srx_tmp mit jedem neuen Empfang auf 0 setzen, sonst stehen 
irgendwann nur noch 1en drin.

Beides erklärt aber nicht, warum du konstant 0x00 empfängst.

Ich würde folgendes tun: Wenn es dir darum geht, eine Soft-Uart 
produktiv zu nutzen, dann würde ich eine fertige, getestete 
Implementierung nehmen und deine in die Tonne kloppen.

Wenn es dir darum geht, eine Soft-Uart zu Lernzwecken selbst zu bauen, 
dann würde ich den Hardware-Uart und z.B. die Fleury-Lib nehmen, darin 
ausreichend grossen Tx-Ringbuffer konfigurieren und den Hardware-Uart 
dann für Debug-Ausgaben nutzen, um z.B. erstmal "srx_tmp" mit jedem 
empfangenen Bit anzugucken.
(Firma: matzetronics) #4710418
Lesenswert?
• ▲
▼
Ich teile einen Soft UART Receiver in zwei Teile auf. Das eine ist ein 
Pinchange Interrupt auf fallende Flanke, der den Bitzähler und den Timer 
auf 1,5 fache Bitlänge mit ISR initialisiert, den Status des Receivers 
auf busy setzt und dann sich selber sperrt.
Die Timer ISR setzt den Timer auf 1 Bitdauer, liest den Pin, schiebt das 
Ergebnis von links in den RX-Buffer und erhöht den Bitzähler. Wenn 
Bitzähler > 8, sperrt sich die Timer ISR, setzt den Status auf 
nicht-busy (also ready) und gibt den o.a. Pinchange Interrupt wieder 
frei.
Gast #4710583
Lesenswert?
• ▲
▼
Matthias S. schrieb:
> Ich teile einen Soft UART Receiver in zwei Teile auf. Das eine ist ein
> Pinchange Interrupt
...

Man kann es sich auch einfacher machen, indem man die übliche Hardware 
softwaremässig nachbaut: man nimmt einen durchlaufenden Time-Interrupt 
von 8 oder 16 mal der Baudrate und programmiert den Empfänger als State 
machine, die beim erstenmal Lo loszählt, beim Zählerstand 8 das Startbit 
verifiziert, bei 24 das erste Bit usw.

Kommt natürlich auf die Baudrate an, aber heutige Prozessoren sollten 
damit kein Problem haben, und das Senden wird im gleichen Time Interrupt 
miterledigt.

Georg

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