Archiv verlassen und diese Seite im Standarddesign anzeigen : Interrupt während Graphlcd- und UART-Ausgabe
Hallo!
Ich plane gerade ein kleines Projekt, bei dem es darum gehen wird, einige Controllerpins im Interrupt abzufragen und abhängig von deren Zuständen einige Ausgaben per Graph.-LCD (Controller: KS108) und RS232 zu machen. Ich werde int0, int1, pcint0 und pcint1 verwenden. Die jeweils aufgerufenen ISRs sind reltiv kurz (< 5 µs @ 16 Mhz), werden aber u. U. relativ oft (worst case: 5000 mal/ sec) aufgerufen. Für die LCD- und UART-Ausgabe reicht mir eine Updaterate von 5 - 10 Hz. Ich habe nun die Befürchtung, dass die Interrupts die Kommunikation mit dem LCD bzw. die UART-Ausgabe stören, weil es ja durchaus möglich ist, dass ein Interrupt während eines LCD-Befehls bzw. UART-Ausgabe ausgelöst wird. Hat da jemand konkrete Erfahrungen? Dass dieses Problem für die LCD-Ausgabe prinzipiell besteht, weiss ich, allerdings frage ich mich, ab welchen Unterbrechungsdauern der LCD-Routinen das ein Problem wird. Ach ja, um das noch zu ergänzen: es ist absolut keine Option, während der LCD- bzw UART-Ausgabe die Interrupts zu deaktivieren weil ich auf keinen Fall etwas an den Pins verpassen darf.
Vielen Dank für alle Infos!
Malte
Ich werde int0, int1, pcint0 und pcint1 verwenden. Die jeweils aufgerufenen ISRs sind reltiv kurz (< 5 µs @ 16 Mhz)
Hallo Malte,
dies wirst du mit den "normalen Interrupt-Routinen (also ohne Nosave) ganz sicher nicht hinbekommen. Eine leere ISR benötigt schon 110 Takte, bei 16MHz also ca. 7µs. Und wenn du dann noch bei den PCINTs selber auswerten musst, welcher es nun war, dauert es noch länger.
Dass dieses Problem für die LCD-Ausgabe prinzipiell besteht, weiss ich, allerdings frage ich mich, ab welchen Unterbrechungsdauern der LCD-Routinen das ein Problem wird.
LCDs sind normalerweise unempfindlich gegen längere Zeiten und empfindlich gegen zu kurze. Wenn du das LCD also zu schnell aktualisierst, bekommt es Schluckauf. Zu langsam oder unterbrochen macht ihm viel weniger aus. Was da an das LCD geschickt wird, ist ja auch gar nicht so komplex. Am aufwändigsten ist es meistens, die einzelnen Zeichen von Textausgabe herzustellen.
Wenn du z.B. eine Single Variable mittels
LCD MySingle oder LCDAT MySingle
ausgeben willst, muss BASCOM dazu zunächst mal die einzelnen Zeichen bestimmen, sprich es konvertiert die Single in einen String, der dann Zeichen für Zeichen ausgegeben werden kann.
Wenn du mehrere Signale hast, die mit Frequenzen von 5KHz reinkommen und du jedes über eine separate ISR laufen lässt, dann wird meiner Meinung nach die Gesamtzeit, die das Programm in den ISRs verbringt, zum eigentlichen Problem für die LCD Ausgabe werden.
Hallo for_ro!
Danke für die Infos! Dass das LCD nicht so empfindlich gegen Timingschwankungen ist, höre ich in diesem Zusammenhang natürlich gerne.
Ich möchte aber nochmal nachfragen, warum Du der Ansicht bist, dass mein Ansatz aufgrund der ISR-Dauer nicht klappen kann. Du sagst, dass eine leere ISR bei 16 MHz ca. 7 µS dauert. Das was ich in der ISR machen will, dauert wie gesagt max. ca. 5 µs, runden wir also ruhig grob auf 15 µs bei 16 MHz auf. Selbst wenn alle vier ISRs 15 µs brauchen würden, käme ich auf max. 60 µs. Angenommen die Interrupts würden mit 5 kHz, also ca. alle 200 µs getriggert, dann würden doch 140 µs für andere Dinge bleiben. Und das ist der wirklich der worst-case. Ist das zu milchmädchenmäßig gerechnet? Wenn ja, warum?
Vielen Dank! Viele Grüße
Malte
Hallo Malte,
ich denke, deine Rechnung mit den 60µs und den verbleibenden 140µs ist schon ok. Heisst aber auch, dass dein Programm unter dieser Annahme schon 30% der Zeit in der ISR ist. Wenn sonst nicht mehr viel zu tun ist, kann das ok sein. Das wirst du ausprobieren müssen. Auf keinen Fall darf eine ISR solange dauern, dass ein anderes Signal zweimal auftritt. Damit würde ich die absolute Obergrenze für eine ISR bei 200µs/4 sehen, also bei 50µs.
Du musst halt auch genau aufpassen, welche Befehle du in den ISRs benutzt. Am besten mal im Simulator durchspielen und dir die benötigten Zeiten bzw. Takte ansehen.
Danke nochmal for_ro!
Also ich denke ich werde einen M644 verwenden, den würde ich bei 20 MHz betreiben können - als erste Maßnahme zur Geschwindigkeitssteigerung. In der ISR für int0 und int1 wird nur ein Integer auf einen definierten Wert gebracht, das sollte in knapp zehn Takten zu machen sein - natürlich plus die gut 100 Takte "overhead" der ISR (was mir ehrlich nicht klar war...). Wie auch immer, ich denke auch dass es knapp wird, es könnte ja aber auch klappen :-). Und was in der restlichen Zeit zu tun ist, ist in der Tat "nur" die LCD- und RS232-Ausgabe. Bei ersterem warst Du ja optimistisch.
By the way, wie sieht es denn mit der UART-Ausgabe aus, macht es da etwas, wenn währenddessen ISRs aufgerufen werden? Oder kümmert sich die AVR-Hardware da selbst um "kreuzungsfreien Verkehr"?
Danke nochmal! Viele Grüße!
Malte
Die AVR Hardware sorgt nur dafür, das ein einzelnes Zeichen in der vorgegebenen Geschwindigkeit rausgeht. Der ganze Rest wird in SW gemacht und ist daher unterbrechbar. Das sollte aber kein Problem sein, solange auf der anderen Seite auf das Eintreffen der zeichen gewartet wird.
Wo du etwas vorsichtig sein musst sind Änderung an Variablen in der ISR und gleichzeitiges Weiterverarbeiten der Variablen in einem anderen Programmteil, etwa Ausgabe aufs LCD. Nur Byte Variablen können in einem Schritt verarbeitet werden, alle anderen Typen brauchen dafür mehrere Teilschritte. Eine Integer Variable wird daher als 2 Byte verarbeitet. Dabei könnte es dir passieren, dass das erste Byte schon vom alten Wert verarbeitet wurde, dann kommt der Interrupt und ändert den Wert. Wenn dann das zweite Byte verarbeitet wird enthält es schon den neuen Wert.
Je öfter die ISR aufgerufen wird, umso größer wird die Chance, dass so etwas passiert.
Hallo,
hm, auch daran habe ich noch nie gedacht... Aber nachdem ich mir das jetzt mal so auf die Schnelle überlegt habe, scheint es mir, als gäbe es da keine echte Lösung, zumindest wenn man high-level in Bascom programmiert. Sehe ich das richtig? Die Variable vor der Weiterverarbeitung nochmal in eine andere Variable zu spiegeln bringt ja wohl auch keine 100%ige Sicherheit, weil immnoch währenddessen die ISR aufgerufen werden könnte. Aber vielleicht minimiert das zumindest die Wahrscheinlichkeit dass dieses Problem auftritt... Ich glaube es lohnt jetzt, das ganze mal praktisch auszuprobieren.
Danke für die Unterstützung!
Malte
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.