PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ADC und interrupts



Powell
03.10.2010, 20:15
Hallo Leute,

folgende (eigentlich simple) Aufgabe:

Über meinen ADC1 Kanal bekomme ich ein Signal rein. Über die Software wird ein Schwellwert in einer Variablen gespeichert. Bei erreichen des Schwellwerts soll das Programm sofort (wie bei einem Interrupt) in eine Subroutine springen.

Wie implementiere ich sowas am elegantesten?

Meines wissens nach ist der Interrupt Befehl "On ADC" ja dafür vorgesehen in die Routine zu springen sobald der ADC "fertig" ist, also ein I O Wert.

Ich möchte aber sowas wie "wenn ADC1 > 765 dann springe sofort in ISR X"

Danke für eure Tips

Jaecko
03.10.2010, 20:25
Bei einem bestimmten Wert erst springen, geht leider nicht.
Was aber geht: Immer reinspringen und gleich wieder raus, wenn der Wert nicht dem gesuchten entspricht; also sowas wie "If ADC1 <= 765 Then return". Ob Bascom damit klar kommt wüsst ich jetzt nicht genau.

for_ro
03.10.2010, 20:52
Hallo Powell,
wenn du den Analog Comparator nutzen kannst, dann geht das schon.
Du müsstest dann die Eingänge AIN0 und AIN1 verwenden und auf einen die Spannung legen, die dem Wert 765 entspricht.

Powell
03.10.2010, 21:16
Hi zusammen,

ich geb mal ein paar mehr infos, dann könnt ihr das auch besser einschätzen:

Meine Software springt bis zu 400 mal / sek in einen ICP interrupt um ein externes signal auszuwerten (pulsabstand wird gemessen). Diese Routinte ist das Kernstück der Software und hat höchste priorität, sie darf nicht verspätet kommen oder ausfallen.

Hierüber kriege ich einen Digitalen Wert rein.

Mit einem Poti generiere ich einen Soll-wert (über adc also auch ein digitaler wert)

Diese beiden werte sollen nun verglichen werden.

Wenn eine gewisse vergleichswertbedingung erfüllt ist (z.B. ADC > 765) dann soll das Programm springen, auch wenn das Hauptprogramm gerade etwas anderes macht.

Ich denke hieraus geht dann hervor dass deine Idee @jaecko vermutlich meine Haupt-Interruptroutine behindern könnte, und deine @for_ro mangels eines anderen Analogsignals nicht gehen wird (plus hardware einschränkung, AINs sind belegt)

kann ich die priorität des ADC Interrupts vielleicht runtersetzen? Dann könnte ich es doch über den ON ADC machen, welcher aber unterbrochen wird wenn eine ISR mit höherer Priorität kommt.

Besserwessi
03.10.2010, 21:45
Die Interrupt-Prioritäten sind fest vergeben, da kann man nichts ändern.
Das würde auch nicht helfem, denn auch so könnte das Externe signal genau dann kommen,wenn gerade die ADC-ISR läuft. Die AVRs haben nur Prioritäten für die Auswahl bei mehreen Anstehen Interrupts, nicht für die Unterbrechung eines anderen.

Wenn der Sollwert für den Vergleich über einen Poti, also als analoges Signal gegriert wird, wäre der Analoge Komperator eigentlich die richtige Wahl. Den eine Eingang des Analogen Komperators kann man auch auf einen anderen AD Eingang verlegen.

Wenn man sich bei der Programmierung anstrengt (z.B. mit inline ASM) kann man die ISR für den Interrupt aber sehr schnell machen, und ggf. auch gleich Interupts wieder zulassen. Dann sollten sich die Verzögerungen in Grenzen halten.

Bei nur 400 Interrupts je Sekunde sollte man bei der ICP funktion noch keine Problem mit verzögerungen bekommen. Die ICP Hardware ist ja gerade dafür da die Zeitmessung unabhängig von verzögerungen zu machen.

Vitis
03.10.2010, 22:14
man kann interrupts in der ISR enablen, ist aber ne bedenkliche Sache, weil da schnell mal der Stack überläuft, sprich nach irgendeiner Zeit kommen irgendwelche wirren Sachen raus.
Was DU machen kannst ist in der ADC ISR den vergleich machen (400Hz sollten spielend machbar sein) und in der ISR die Subroutine aufrufen. Dann bleibt die Unterbrechung des Hauptprogrammes stehen bis diese Sub bearbeitet ist und die ISR verlassen ist.
Genaueres kann man aber nur mit Durchsicht des Codes sagen. Stell den mal rein, evtl fällt einem ja was gescheites zur Beschleunigung ein.