Software UART

Gast #4710235
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
}
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
Peter schrieb:
> void suart_empfangen(void)
> {
>   if(srx_done>0)
>   {
>     [...]
>   }
> }

Frage: Wer setzt srx_done auf einen Wert >0 ?
Wenn das sonst nirgendwo passiert, wird der äüßerste if-Block nie als 
TRUE bewertet und auch nie ausgeführt.
Gast
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
}
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)
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
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

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