PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : alle 250 ms Interrupt mit Timer2 auslösen - geht das?



malthy
18.04.2007, 16:25
Hallo,

ich möchte alle 250 ms ein Unterprogramm ausführen. Dabei ist weniger entscheidend, dass es exakt alle 250 ms aufgerufen wird, wohl aber, dass die Intervalle zwischen den Aufrufen gleich groß sind.
Leider steht mir - und da lässt sich nichts ändern - nur noch der Timer2 zur Verfügung. Da es sich um einen 8bit Timer handelt, dachte ich zunächst, ein so großes zeitl. Intervall lässt sich nicht erzielen (mein M32 läuft mit 16MHz). Jetzt habe ich aber gelesen, dass Bascom für seine Softclock auch über Timer2 (beim M32) alle Sekunde einen Interrupt auslöst. Geht es also doch irgendwie so große Intervalle hinzubekommen? So wie ich jetzt gerechnet habe, komme ich mit prescale=1024 bei 16MHz auf einen max. Abstand von ca. 16.4 ms.
In der Interrupt-Routine zu zählen und nur z.b. jeden 15ten Aufruf auch wirklich was zu tun, geht übrigens nicht, weil das, was ich in der Routine machen will, länger dauern würde, als der Abstand zwischen zwei Interrupts.
Danke für alle Tipps!

Malthy

papa_of_t
18.04.2007, 16:32
nimmst Du halt einen EingangsPin mit Interrupt-Fähigkeit und baust Dir aus nem ATTiny oder analog einen externen "250ms Timer"?

Ich nehme an, die Programmteile in der ISR sind zeitkritisch..

malthy
18.04.2007, 16:35
Hallo,

das ist aber sehr unelegant... Wie macht das denn die Softclock von Bascom, oder habe ich da einfach nur etwas falsch verstanden?

Viele Grüße,
Malthy

papa_of_t
18.04.2007, 16:57
Lies mal die BasCom - Hilfe zu CONFIG CLOCK - entweder wird ein externer (i2C)-baustein benutzt oder die "Softclock" braucht genauso einen timer, der Interrupt-Routinen feuern wird - nix für zeitkritische Sachen wie Rs232 oder so..

so wahnsinnig ist ja der externe Aufwand nicht, ein NE555 + 2 Bauteile oder eben ein ATTiny, oder was Dir noch einfällt..

malthy
18.04.2007, 18:45
Hallo papa_of_t!

Ich weiss nicht genau, ob ich dich richtig verstanden habe, aber mir ist schon klar, dass die "softclock" einen Timer braucht - beim M32 meines Wissens eben Timer2. Mich wundert nur, dass die Softclock es mit diesem 8bit-Timer(!) schafft, nur alle 1000 ms einen Interrupt auszulösen (nämlich alle Sekunde das Unterprogramm "sectic" anspringt). Wenn das irgendwie softwaretechnisch möglich ist, möchte ich natürlich auf zusätzliche Hardware verzichten (zumal tatsächlich alle Ports meines AvRs belegt sind).

Gruß,
malthy

malthy
18.04.2007, 20:10
Okay, ich glaube ich habe da etwas überlesen. Sehe ich es richtig, dass die Softclock einen zusätzlichen externen 32768 Hz Quarz benötigt? Das würde meine Frage beantworten ;)

malthy

jar
18.04.2007, 21:45
Okay, ich glaube ich habe da etwas überlesen. Sehe ich es richtig, dass die Softclock einen zusätzlichen externen 32768 Hz Quarz benötigt? Das würde meine Frage beantworten ;)
malthy

denke ich auch, ich grübel gerade am selben Problem

32.768 256 128,0000
32.768 1024 32,0000

entweder Vorteiler auf 256 oder 1024 dann würde das compare register mit 8-bit passend bei 128 oder 32 geladen werden....

alle sec ein IRQ

Vitis
19.04.2007, 17:33
man kanns auch umständlich machen.
Geh doch einfach hin und zähle mit der ISR von Timer2 ne
Bytevariable hoch und wenn eben der x-te Durchlauf vollzogen
ist, dann führe deine Funktion aus.
Du brauchst keine zusätzliche Hardware (NE555 etc.) und von der
Präzision her kommste auch noch gut hin.

Die Softclock läuft im Übrigen tatsächlich mit 32768KHz Quarz.

malthy
22.04.2007, 15:24
Hallo Vitis,

das geht leider nicht, weil das, was ich ausführen will, länger dauert, als der maximal möglicher Abstand zwischen zwei 8bit-Timer-Interrupts. Das hatte ich oben schon versucht zu sagen, war wohl etwas verschwommen ;). Habe mich mittlerweile damit abgefunden, dass es nicht geht, versuche das Problem anders zu lösen - aber auch ohne zusätzliche Hardware.

Gruß,
malthy

Vitis
22.04.2007, 17:46
Also die Hauptanwendung ist länger als die Interruptroutine
oder die Interruptroutine ist länger als der Überlauf von nem 8-Bit-Timer
mit Prescaler? ... Wenn letzteres der Fall ist würd ich von nem
Programmierfehler ausgehen.
Das macht man nämlich nicht, den Controller in nem Interrupt
gefangen halten. Schau mal State machine

HansHans
22.04.2007, 18:28
Hallo,
mach es so wie Vitis
es schreibt :
Zähle in der ISR nur die bytevariable hoch und prüfe ob sie
Größer als (250ms / 16,4ms = ca.) 15 ist, wenn das so ist setzt du die
Variable zurück und setzt ein Bit .

Im Hautprogramm fragst du genau dieses Bit ab ob es gesetzt, ist wenn ja
machst du dein „Ersatz ISR Unterprogramm“ und am Ende Resetest du das Bit wieder
somit hast du für deine Ersatz ISR wieder fast 250 ms zur Verfügung .


Natürlich dürfen dann im Hautprogramm nicht Sachen wie
Wait 2 (oder so) stehen, aber das ist ja sicher auch nicht der Fall .

Gruß
HansHans

malthy
24.04.2007, 14:05
Hallo,

diese Variante funktioniert - wie gesagt - deshalb nicht, weil das Unterprogramm, das alle 250ms ausgeführt werden soll, länger als der max. Abstand zwischen zwei Interrupts ist. Deshalb kann die Sache mit dem Zähler nicht funktionieren - wie ich ja schon in meinem allerersten Posting schrieb.

Das Unterprogramm dauert nicht wegen eines Programmierfehlers so lange, sondern weil ich einige (leider zeitraubende) Grafik-LCD Befehle ausführe. Das würde ich gerne lassen, muss es aber im Interrupt tun, weil die Grafikausgabe ansonsten durch den Interrupt gestört würde. Wenn also während des Schreibens aufs LCD ein Interrupt ausgelöst wird, stellt das LCD nur noch Müll dar. Ich muss also dafür sorgen, dass die Darstellung immer komplett abgeschlossen ist, bevor ein Interrupt ausgelöst wird. Interrupts während der Grafikausgabe zu verbieten stellt natürlich auch keine Lösung dar, denn dann stimmt das Timing wieder nicht mehr genau. Ich sah also als einzige Variante das Überhnehmen der LCD-Ausgabe in die Interrupt-Routine. Die Routine würde übrigens knapp 20 ms dauern - also auch nicht so viel länger als der mögl. Interruptabstand...
Ich machs jetzt ingesamt anders: ich tune nach dem alles fertig ist den Schleifendurchlauf auf exakt 250ms mit waitms und waitus.

Gruß,
malthy

HansHans
24.04.2007, 17:12
Also ich verstehe zwar nicht warum man das LCD im Interrupt
beschreiben muss, ich mach das immer im Hauptprogramm
wenn ich gerade mal zeit dazu habe. Durch eine
Interrupt Unterbrechung der LCD Routine sollte sich das LCD nicht
stören lassen. Das sind ja nur ein paar Takte
Aber wenn es jetzt so geht ...

malthy
24.04.2007, 20:01
Hallo HansHans!

ich hätte auch nicht gedacht, dass der Interrupt das LCD stört - ist aber definitiv so. Und das ist der alleinige Grund, warum ich das LCD in der Interrupt-Routine beschreiben wollte...

Gruß,
malthy

Vitis
24.04.2007, 22:18
naja, so kann mans auch machen, aber ne andere Variante ists
die Interrupts während der Ausgabe zu disablen, also
einfach zu Beginn des refresh disabel interrupts, danach
wieder enable interrupts ... nicht schön, aber sollte gehen.
Warum das Display aber durch die Int gestört werden kann
hängt mir aber dennoch zu hoch.
Was ists denn für ein Display und wie ists angeschlossen?

HansHans
24.04.2007, 22:36
Mir geht das mit deinem Display nicht aus dem Kopf .....
ist das ein Display ohne Controller wo du selbst das
Timing und den refresh machen musst ?
(Ich meine jetzt den refresh obwohl sich der Bild Inhalt
gar nicht verändert hat )

malthy
25.04.2007, 09:43
Hallo,

naja, wie gesagt, Interrupts während der Grafikausgabe verbieten macht auch nicht so viel Sinn, weil dann das Timing wieder ungenau wird...
Es wäre natürlich super, wenn mir noch jemand die Sache mit dem LCD erklären könnte - ich verstehe es nämlich auch nicht so recht. Ich verwende ein 240*128 Grafik-LCD mit einem T6963C als Controller, es ist entsprechend BASCOM-Hilfe an meinen M32 angeschlossen (Controll- und Dataport) Zur Ansteuerung verwende ich ausschließlich die BASCOM-Befehle, vor allem Showpic. Ohne Interrupts funktioniert alles super, mit Interrupts zeigt das Display nur noch Müll...

Gruß,
malthy

Vitis
25.04.2007, 20:49
hmmm, dem Datenblatt nach dürfte es eigentlich keine
Probleme mit den Interrupts geben, der Controller ist nicht
zeitkritisch. Möglich, das es mit den Einstellungen
für Stack und Frame zutun hat, das sich dann eben was überschneidet.

Um genauere Analyse vorzunehmen müsste man den Code sehen.

malthy
26.04.2007, 09:40
Hallo,

ich werde mal versuchen, ein möglichst reduzierten und dadurch durchsichitgen Code zu erzeugen, bei dem das Problem auftritt. Das könnte einen Tag dauern, habe gerade andere Dinge an den Hacken. Was ich vielleicht noch nachtragen könnte: Die Showpic Aufrufe finden in einer Do-Loop-Schleife sehr schnell hintereinander statt, was letztlich programmiertechnische Gründe hat. Im Endeffekt wird also kontinuierlich aufs LCD geschrieben.