Hallo, in dem angehängten Code konnte ich den Fehler soweit eingrenzen sodass ich sehen konnte das nicht immer die Variable TelegrammReady gesetzt wird. Zu 80% gehts gut, die Variable wird gesetzt und in der main routine wird dann mit der entsprechenden if-Abfrage (if (TelegrammReady==true)) der Code abgearbeitet. Aber wie gesagt sporadisch. In der main ist TelegrammReady global als extern volatile bool TelegrammReady definiert. Wie kann das sein das er manchmal im Code die Zeile üebrspringt wo TelegrammReady gesetzt wird? Alle anderen Zeilen werden abgearbeitet und ich sehe dann auch das das Startbit erkannt wurde und die genaue Anzahl an Bytes gelesen wurde. Ein atomarer Zugriff wäre nicht möglich da in der ISR per UART Daten gesendet und die UART ist nach Fleury. Könnte ich einen Denkanstoss kriegen? Ich hänge gerade hier fest und weiß nicht woran e liegen könnte.
Hi, in welchem Zeitlichen Abstand kommen die Bits an und wie lang ist worst case die durchlaufzeit der ISR? gibt es neben deiner INT2-Routine noch weitere, zeitfressende ISR-Routinen ( die der Uart-Lib ausgenommen ) ?
Rafi Dafi schrieb: > da in der ISR per UART Daten Das ist ungünstig. die UART-Lib braucht beim Senden zwingend aktive Interrupts (sobald der Buffer voll ist), aber innerhalb der ISR sind diese per Default deaktiviert. bevor du nun mit cli/sei innerhalb deiner ISR hantierst: Versuch mal höhere Baudrate, kürzere Texte oder größeren Buffer für den UART. die "Saubere" Lösung wäre jedoch, alle uart-sachen aus der ISR rauszuhalten.
Die UART bzw. die ISR für die UART ist nicht das Problem. HAbe schon in die ISR(INT2_vect) uint8_t sreg = SREG; cli(); .... SREG = sreg; eingepflegt um den zugriff anderer ISR's zu verhindern, aber kein Erfolg. Ich reiss mir hier noch die HAare raus.
Es ist auch egal in welchem Abstand ich so ein Frame schicke bzw. empfange. Jede sekunde oder jede 100ms. Rainer B. schrieb: > in welchem Zeitlichen Abstand kommen die Bits an und wie lang ist worst > case die durchlaufzeit der ISR? wie kann ich diese Durchlaufzeit berechnen? Müsste ich nicht dazu die Assembler befehle auswerten? Rainer B. schrieb: > Hi, > > in welchem Zeitlichen Abstand kommen die Bits an und wie lang ist worst > case die durchlaufzeit der ISR? > > gibt es neben deiner INT2-Routine noch weitere, zeitfressende > ISR-Routinen ( die der Uart-Lib ausgenommen ) ? Ja noch einen Timer OVF ISR
Rafi Dafi schrieb: > Die UART bzw. die ISR für die UART ist nicht das Problem. Die uart_puts() in der ISR sind sicher ein Problem. Da schreibst Du ganze Strings raus, die einiges an Wartezeit verpulvern, bevor es in der ISR selbst weitergehen kann. So etwas macht man anders: - Datenspeicherung in der ISR - Datenverarbeitung außerhalb der ISR Zur Kommunkikation zwischen Hauptprogramm und ISR dient ein simples Flag, das volatile zu deklarieren ist. > HAbe schon in die ISR(INT2_vect) > uint8_t sreg = SREG; > cli(); > .... > SREG = sreg; > eingepflegt um den zugriff anderer ISR's zu verhindern, aber kein > Erfolg. Witzig. Wusstest Du eigentlich, dass bei Betreten einer ISR() automatisch sämtliche Interrupts deaktiviert und bei Verlassen wieder aktiviert werden? Deine Versuche sind daher unsinnig und gleichen einem Stochern im Nebel. > Ich reiss mir hier noch die HAare raus. Es gibt hier keinen Grund zur Selbstverstümmelung.
ICh glaub ich hab den Wurm. Der Code funktioniert richtig, ich glaub ich hab die falsche Abfrage auf das Ende des frames. Aber danke für die Anstösse, werde berichten wenn ich es raus habe.
Was genau fragst Du damit eigentlich ab? (!(PIND & (1<<PD4))) Das es eine PIN-Abfrage ist weiß ich - welcher Sinn steckt dahinter?
@ Rafi Dafi (alexanderw) >in dem angehängten Code konnte ich den Fehler soweit eingrenzen sodass >ich sehen konnte das nicht immer die Variable TelegrammReady gesetzt >wird. Die Einrückung deines Codes ist schlecht, damit ist er schlecht lesbar. >Zu 80% gehts gut, die Variable wird gesetzt und in der main routine wird das ist für ein digitales System keine gute Quote ;-) >Wie kann das sein das er manchmal im Code die Zeile üebrspringt wo >TelegrammReady gesetzt wird? Macht er nicht. >Ein atomarer Zugriff wäre nicht möglich da in der ISR per UART Daten >gesendet und die UART ist nach Fleury. Welche ISR? Ahh, ich sehe es. Hmm, könnte ein Problem sein, wenn die Pulsbreiten zu schmal werden und damit die ISR zu langsam. Vorteil ist, dass die Funktion uart0_puts() die Daten NICHT direkt sendet sondern in den FIFO vom Peter Fleury reinschreibt. Von dort werden die Daten per ISR gesendet. Aber das heißt im Zweifelsfall auch, dass die Abarbeitung deiner INT2 ISR von der UART ISR verzögert werden kann. Wenn die Pulse zu schmal sind, geht die Dekodierung schief. >Könnte ich einen Denkanstoss kriegen? Ich hänge gerade hier fest und >weiß nicht woran e liegen könnte. Ich vermute mal, dass dein Algorithmus für deine Protokollerkennung sich verschluckt. Entweder, weil es zu fehleranfällig ist, falsch ist oder das Signal nicht sauber ankommt. Wie schnell klommen denn die Bits bei dem Datenstrom? Minimale Pulsbreite?
@ Dieter Frohnapfel (jim_quakenbush) >Was genau fragst Du damit eigentlich ab? >(!(PIND & (1<<PD4))) >Das es eine PIN-Abfrage ist weiß ich - welcher Sinn steckt dahinter? Er will den Datenstrom dekodieren. PD4 ist hier garantiert das INT2 Pin.
if (PIND & (1<<PD4)) Diese Abfrag ist ja mehrfach im Code vorhanden. Also sollte man sie sinnvollerweise nur einmal machen, nämlich am Anfang der Routine. uint8_t data = PIND & (1<<PD4); ... if (data) .... if (!data) ... Das macht den Code nicht nur lesbarer, es verbessert auch das Timing. Denn du willst ja rauskriege
> uint8_t data = PIND & (1<<PD4); > > if (data) .... > if (!data) ... > > Das macht den Code nicht nur lesbarer, es verbessert auch das Timing. > Denn du willst ja rauskriege Nee, genau nicht. Denn PIND liegt im unteren IO-Bereich, dh. direkt mit SBIC, SBIS abzufragen. Geht deutlich schneller als aus temp. Variablen. Einziger Nachteil ist der, dass PIND sich während der Ausführung ändern könnte. Aber damit kommen wir jetzt bereits in den Bereich der Erbsenzählerei.
Rainer B. schrieb: > Nee, genau nicht. Denn PIND liegt im unteren IO-Bereich, dh. direkt mit > SBIC, SBIS abzufragen. Geht deutlich schneller als aus temp. Variablen. > Einziger Nachteil ist der, dass PIND sich während der Ausführung ändern > könnte. Aber damit kommen wir jetzt bereits in den Bereich der > Erbsenzählerei. Das ist aber eine Erbse, an der man sich übel verschlucken kann, wenn man sie nicht rechtzeitig zählt! Wenn ich in der Programmlogik an mehreren Stellen denselben Eingangswert brauche, dann muß ich dafür sorgen, daß ich auch jedesmal denselben Wert verwende. Und das geht mit einer lokalen Variablen. Natürlich ist die Wahrscheinlichkeit gering, daß sich der Eingang zufällig in diesen paar µs ändert, aber das bedeutet nur, daß dem Entwickler der Fehler beim Testen nicht auffällt. In der Praxis synchronisiert sich dann irgendwo etwas, und aus "zufällig" wird auf einmal "regelmäßig", und dann ist der Fehler schwer zu finden, weil man nicht damit rechnet.
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.