mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Software UART


Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?!


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

void suart_empfangen(void)
{
  if(srx_done>0)
  {
    if(srx_done<9)
    {
      if ( SRXPIN & (1<<SRX) )
      {
        srx_tmp |=( 1<< (srx_done-1) );
      }
    }
    srx_done++;
    if(srx_done>=10)
    {
      srx_data[srx_count]=srx_tmp;
      srx_count++;
      srx_tmp=0;
      srx_done=0;
    }
  }
}

Autor: Rainer B. (katastrophenheinz)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: bastler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: nochmal bastler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter schrieb:
> (srx_done-1)

Warum benutzt du keinen 0-bezogenen Index für die Bits?

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
void suart_getchar(void)
{
  if ( ( ( SRXPIN & (1<<SRX) ) ==0)& srx_done==0)
  {  
    TCNT0=SBAUD_TCNT_INIT;
    srx_done=1;
  }
}

Autor: Rainer B. (katastrophenheinz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Poste bitte den kompletten Quellcode!

Autor: Peter (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier der Quelltext

Autor: Rainer B. (katastrophenheinz)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Matthias S. (Firma: matzetronics) (mschoeldgen)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Georg (Gast)
Datum:

Bewertung
1 lesenswert
nicht 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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Matthias S. schrieb:
> 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.

Und wo ist der Code?
In Deinem Code ist nur ein Overflow-Interrupt.

Autor: Matthias S. (Firma: matzetronics) (mschoeldgen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter D. schrieb:
> Und wo ist der Code?
> In Deinem Code ist nur ein Overflow-Interrupt.

Ich habe dazu keinen Code hier veröffentlicht.
Man kann sich das in meinem V-USB Projekt 'Tektronix Tablet 4957 auf 
USB' auf
http://www.schoeldgen.de/avr/ anschauen.

: Bearbeitet durch User

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.