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
CTC Mode empfohlen, sonst kumuliert der durch verzögerte Abarbeitung des Interrupts entstehende Fehler.
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); }
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...
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.
noch was zur hardware : rx-pin ist bei mir auf int0 tx-pin auf int1. int0 brauche ich wie gesagt nur zur flankenerkennung
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.
oh ... copy&paste fehler. habs behoben. jetzt empfängt er richtig. allerdings besteht das problem das "hängenbleibens" immer noch :-(
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
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 ?
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
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 ?
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.
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
@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
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
man merkt das es heute früh spät geworden ist .... hier die fehlenden dateien :-((
hat denn niemand zeit mal eben drüber zu schauen und nen hinweis was es sein könnte ?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.