mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem mit SW UART


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

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

habe mir einen SW UART zusammengebastelt. Das Teil funktioniert auch 
(senden gar kein problem), aber beim empfangen habe ich das problem das 
sich nur ein paar zeichen (reicht von 12 bis 60) empfangen kann und 
danach ist schicht (es wird nichts weiter empfangen, aber der uC läuft 
noch weiter, hängt also nicht).
ich habe den rx-pin mit int0 verbunden und warte da auf die fallende 
flanke. danach nutze ich timer 2 zum weiteren abtasten. die baudrate ist 
mit 4800 bd auch nichts besonderes.
es scheint so das entweder der int0 oder aber der timer2-ovf nicht mehr 
durchkommen. wüsste allerdings nicht wieso, alle weiteren int's kommen 
durch.
hat jemand ne idee ?

gruß

rene

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
CTC Mode empfohlen, sonst kumuliert der durch verzögerte Abarbeitung des 
Interrupts entstehende Fehler.

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also im ctc-mode wills auch nicht so richtig klappen.
habe immer noch das problem das mir die routinen hängen. außerdem 
emfpängt er falsch. aber da ist sicherlich noch ein kleiner bug drin.
ist das mit der akkumulation des jitters bei 4800 auch schon so ein 
problem ?! arbeite mit nem cpu takt von 11,0592mhz.

hier mal die geänderten stellen :

void vSWUARTInit (void)
{
  MCUCR |=  (2 << ISC00);
  GICR  |=  (1 << 6);
  PORTD |=  (1 << 2);
  DDRD  &= ~(1 << 2);

  TCCR2  = TIMER2_DIVIDER;

  TCCR2 = TIMER2_DIVIDER | (1<<WGM21) | (0 << WGM20);
  TCNT2 = 0;
  OCR2  = 255;

  TIMSK &= ~(1 << OCIE2);
  ucRxCnt = 0;

  INIT_TX_PIN;
}

void vSetEdgeDetect (void)
{
  TIFR  |=  (1 << OCF2);
  GIFR  |=  (1 << 6);
  TIMSK  &= ~(1 << OCIE2);
  GICR   |=  (1 << 6);
}

ISR (TIMER2_COMP_vect)
{
  OCR2 = RX_TIME_BIT_TIME;
  TIFR |= (1 << OCF2);
  if (ucRxCnt >= 8)
  {
    if (PIN_RX)
    {
      ucSWUARTData = ucInputShiftReg;
      bSWUARTReceived = TRUE;
    }
    ucRxCnt = 0;
    vSetEdgeDetect();
  }
  else
  {
    ucInputShiftReg = ucInputShiftReg >> 1;
    if (PIN_RX) { ucInputShiftReg |= 0x80; }
    ucRxCnt++;
  }
}

ISR (INT0_vect)
{
  TCNT2  =   0;
  OCR2   =   255 - RX_TIME_1ST_BIT;

  GIFR  |=   (1 << 6);
  GICR  &=  ~(1 << 6);
  ucEdgeCnt++;
  ucRxCnt = 0;
  ucInputShiftReg = 0;

  TIFR  |=   (1 << OCF2);
  TIMSK |=   (1 << OCIE2);
}

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bist du sicher, dass deine Bitzeiten so stimmen? Die Variante in 
ISR(INT0_vect) passt nicht ganz zur anderen. Da du die #defines geheim 
gehalten hast...

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

Bewertung
0 lesenswert
nicht lesenswert
hups, ähm ...

hier noch das header file.
die bitzeiten sollten eigentlich stimmen.
1. bit = 1.5x bitzeit ,
2-10. bit = 1.0x bitzeit.
bitzeit ist bei mir 11059200/64/4800 = 36.
das empfangen selbst ist nicht das problem (zumindest bei der lösung 
ganz oben)
ich kapier nicht warum die interruptabfolge abreisst.

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
noch was zur hardware :

rx-pin ist bei mir auf int0
tx-pin auf int1.
int0 brauche ich wie gesagt nur zur flankenerkennung

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, mit dem Headerfile, ist hatte grad nur noch das zweite gesehen. 
Oben stand das was ich suchte.

Jedenfalls ist
  OCR2 = 255 - RX_TIME_1ST_BIT;
sicherlich nicht richtig.

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oh ... copy&paste fehler.
habs behoben. jetzt empfängt er richtig. allerdings besteht das problem 
das "hängenbleibens" immer noch :-(

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
habe mal debugausgaben auf einem lcd display gemacht.
es wird tatsächlich der timer 2 nicht mehr angestossen.
ich zähle die anzahl der timeraufrufe und gebe diese aus.
irgendwann bleibt der zähler einfach stehen. ich vermute es hängt 
irgendwo mit der umschaltung zw. flankenerkennung und timer-int 
anstossen.
hat jemand ne ahnung was das sein kann ?

gruß
rene

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
keiner ne idee ?! :-(

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kann mir denn niemand nen tip geben ?!

liegt es daran das ich den INT0 und nicht (wie bei peter danneggers 
version) den ICP verwende ?
liegts vielleicht daran das noch zuviel anderes zeugs in meinem programm 
läuft (wobei das m.m. nach nicht erklärt warum der interrupt "hängen" 
bleibt), und interrupts "verschluckt" werden können (dann sollte es aber 
höchstens zeichenaussetzer geben und nicht ein komplettes stehenbleiben 
der empfangsroutine) ?
was fehlt denn noch an infos ?

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
TheMason wrote:
> was fehlt denn noch an infos ?


Ein compilierfähiges Programm wäre nicht schlecht (zip, wenns mehrere 
Files sind).

Mit nur Codeschnipselchen ist das für nen anderen sehr schwer.

Und nach Murphys Gesetzt ist ja der Fehler immer grundsätzlich in dem 
Code, den man nicht zeigt.


Peter

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kann gerne mal den ganzen code posten. dürfte aber "schwere" kost sein, 
weil es recht viel ist (habe mit optimierung ca 30kB asm-code) und z.t. 
auch noch im rohbau, bzw ohne funktion.
bereite den code mal etwas auf und poste ihn dann (muß mir erst noch das 
avr-studio installieren, bin gerade nicht an meinem heimischen rechner)

auf was ist denn besonderes augenmark zu legen damit die 
kommunikationsroutinen sauber laufen.
 - der jitter bzw. jitterakkumulation vermeiden ist klar. (obwohl ich 
denke das bei 4800bd das eher weniger eine rolle spielt als bei 
30-50kbd, oder sehe ich das falsch ?)
 - nach möglichkeit alles im interrupt (1 irq für flankenerkennung, 1 
irq für abtastung und 1 irq für übertragung)
 - code möglichst kurz halten

habe ich noch was vergessen ?

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

Bewertung
0 lesenswert
nicht lesenswert
hier mal der gesamte code.
habe ihn kompilierfähig, und die sw-uart routinen wieder einkommentiert 
(hatte diese auskommentiert da ich an anderer stelle weitergemacht habe)

den sw-uart brauche (wenn er denn mal funktioniert) ich zu 
debug-zwecken. der hw-uart wird für die midi-schnittstelle benötigt.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
TheMason wrote:
> kann gerne mal den ganzen code posten.

Nö, mußt Du nicht.

Reduziere mal das Programm nur auf den Test der UART.
Wenn dann der Fehler weg ist, dann liegt der Fehler nicht in der UART.
Wenn der Fehler immer noch da ist, poste ihn, dann wirds ja überschaubar 
sein.

Es ist immer besser die Probleme aufzuteilen, als sich tagelang durch 
einen riesen Wust an Code zu wuseln (Teile und herrsche).


Wenn man denkt, das Programm bleibt irgendwo hängen, dann klemm ein paar 
LEds an und setze sie an den Stellen, wo Du Probleme vermutest.

Und erstmal nichts mit Sleep und Watchdog machen, die können einen super 
das Entwickeln erschweren.
Sowas baut man, wenn überhaupt, erst ganz zum Schluß ein, wenn alle 
Grundfunktionen fertig sind.


Peter

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@peter

erstmal danke für die tips.
- sleep und watchdog verwende ich nicht (nur den sleep ganz am anfang 
einmal)
- debugausgaben und "sichtungen" auf dem scope habe ich schon gemacht 
(daher wende ich mich ja hoffnungsvoll an euch :-))

werde wenn ich wieder an meinem heimischen rechner sitze es nochmal 
austesten (sprich nur den sw uart laufen lassen um zu sehen ob es 
randeffekte mit anderen sw teilen gibt die den uart zum erliegen 
bringen.

gruß
rene

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hab mich mal mit dem problem beschäftigt und das ganze auf ner kleinen 
platine aufgebaut.
also senden ist kein thema soweit (lediglich in der eigentlichen 
anwendung habe ich ein paar falsch gesendete zeichen).
empfangen funktioniert auch prächtig, hat aber auch aussetzer und bleibt 
hängen.
zwar viel seltener als in der eigentlichen anwendung (in der ich den 
source auch getestet habe), bleibt aber trotzdem stehen.
mit stehen meine ich das der empfang "abreisst", der rest des uCs aber 
fröhlich weitermacht.

habe den swuart einmal mit 2 8bit timern (overflow) sowie mit dem 16 bit 
timer (capture) laufen lassen (auf dem test board).
mit dem 16 bit timer habe ich zwar keine aussetzer, aber der verschluckt 
mehrere zeichen. die 8bit timer lösung bleibt irgendwann stehen.

was mich so wurmt ist das es ja prinzipiell funzt, aber das teil eben 
immer irgendwann stehenbleibt ...
aber irgendeine kleinigkeit (hoffe ich zumindest) mache ich anscheinend 
noch falsch, sonst würd ich ja gar nichts empfangen ...

verwende zum erkennen der rx-start-flanke den int0.
gesendet wird als ganz normaler output-portpin auf int1.
frequenz ist 16mhz. baudrate auf 19200. (wäre ja schon froh wenns auf 
4800 funzt :-(( )

hoffe auf hilfe.

gruß
rene

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

Bewertung
0 lesenswert
nicht lesenswert
man merkt das es heute früh spät geworden ist ....
hier die fehlenden dateien :-((

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hat denn niemand zeit mal eben drüber zu schauen und nen hinweis was es 
sein könnte ?

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.