Forum: Mikrocontroller und Digitale Elektronik PiC 18F4580 ADC


von Daniel78 (Gast)


Lesenswert?

Hallo zusammen,
ich hab da mal ne Frage.
Ich benutze mehrere ADC in meiner Hauptroutine und zweimal in einer 
interrupt Routine. Ist das so möglich oder gibt es da Probleme, wenn er 
gerade in der Hauptroutine bei irgend einer Wandlung drin ist und 
plötzlich in die Interrupt Routine springen muss und diese abarbeiten 
muss?

Ich messe Temperatur mit dem ADC und manchmal kommt es vor dass die 
Temperatur Werte eingefroren sind und sich nicht verändern, das kann 
aber auch noch andere Ursachen haben aber ich wollte gern hier erst mal 
anfangen.

Danke, code könnte ich bei bedarf nachliefern.

von Erhard S. (Gast)


Lesenswert?

Die Wandlung geschieht ja in der Hardware, sollte somit kein Problem 
darstellen.
Du kannst ja probehalber mal bei einer Wandlung in der Hauptroutine die 
Interrupts abschalten bis der ADC fertig ist.
Danach Interrupts wieder freigeben.

von Noch einer (Gast)


Lesenswert?

Augenblick mal...

Der hat doch nur einen ADC. Alle analogen Eingänge gehen auf denselben 
ADC.

Wenn deine Hauptroutine den ADC startet und danach deine 
Interruptroutine den ADC mit einem anderen Eingang noch mal startet, 
kommt nur Chaos bei raus.

von Dieter W. (dds5)


Lesenswert?

Den AD Wandler sowohl im (Haupt-)Programm als auch in Interrupts 
benutzen zu wollen ist keine gute Idee.
Welcher (vermeintliche) Grund zwingt denn zu dieser Vorgehensweise?

Immerhin dauert es eine Weile - Kanalwahl, Einschwingzeit, Wandelzeit - 
bis das Ergebnis vorliegt und dann kann der Wandler ja auch selbst einen 
Int auslösen.

: Bearbeitet durch User
von Daniel78 (Gast)


Lesenswert?

Hallo und danke,

Zwei Temperaturwerte welche ich Abfrage in meiner Solarsteuerung sind 
pepulste 1 mA Signale zum PT1000. Jedes Signal ist 100 ms lang und damit 
sind 10 Signale möglich. Wenn das Signal kommt gibt es für jedes Signal 
einen Interrupt, wo ich dann die Wandlung vornehme. Mein Main Programm 
ist sehr langsam, weil ich ein 4x40 Display mitcallerhand werten 
beschreibe. Und dort passt die Wandlung daher schlecht hin.

Das Programm läuft eigentlich mehrere Stunden 4-10 ohne Probleme. Wenn 
es Probleme gäbe, dann würde das doch nicht so lange dauern oder?

In der low ISRoutine sind nur 2x die Wandlung drin, welche bei 20 MHz 
recht flott gehen sollte.

High ISR hab ich für RTC.

von Daniel78 (Gast)


Lesenswert?

Sollte er sich das nicht sichern? Und dann dort weiter machen?

von Noch einer (Gast)


Lesenswert?

> Wenn das Signal kommt gibt es für jedes Signal einen Interrupt, wo ich dann die 
Wandlung vornehme.

Kann das Signal auch kommen, während der ADC noch mit der vorherigen 
Messung beschäftigt ist?

>Mein Main Programm ist sehr langsam
>Und dort passt die Wandlung daher schlecht hin.

Sieht so aus, als müsstest du dich erst mal in die Strategien 
einarbeiten, wie man Hauptschleife und unkoordinierte Interrupts 
wasserdicht anlegt.

Hat du ein Pickit3? Bei eingefrorenen Werten mit dem Debugger 
nachschauen, ob die Interrupts aufgerufen, werden vereinfacht die Sache 
unglaublich. China-Clones gibt es für 20€.

von Daniel78 (Gast)


Lesenswert?

Kann das Signal auch kommen, während der ADC noch mit der vorherigen 
Messung beschäftigt ist?

Ja, das kann es!

Ja, Ich hab ein Pic Kit 3 rumliegen, aber der Zeit wegen noch nicht mich 
damit beschäftigt ?. Die Interrupts kann ich auch mit einer LED checken. 
Nach meinem Wissen gibt es das Problem mit der Temperatur bei der 
Messung in der Hauptroutine und nicht in der ISR Routine.

Ich werde mal schauen, was ich am Programm bearbeiten könnte.

von Noch einer (Gast)


Lesenswert?

> Ja, das kann es!

Da solltest du sauber mit 3 Sätzen an Flags arbeiten. Umbauen geht 
schneller als seltene Fehler suchen.

Zunächst ein Flag, ob der ADC arbeitet.

Die Interruptroutine "Signal liegt an" setzt ein Flag "Temperatur1 
messen". Falls der ADC nicht beschäftigt ist, startet sie den ADC und 
setzt das Flag "ADC arbeitet".

Der ADC benutzt den "ADC Fertig" Interrupt. als "Schleife". Wenn die 
Wandlung fertig ist, schreibt die Interruptroutine den Messwert in eine 
globale Variable "Temperatur1" und setzt ein Flag "Temperatur1 gelesen". 
Dann schaut die Interruptroutine, ob noch weitere Messungen gemacht 
werden müssen.

Die Hauptschleife kümmert sich nur um das Display. Die setzt auch nur 
ein Flag "Temperatur1 messen". Während die Hauptschleife die 
"ADC-Schleife" startet, musst du Interrupts abschalten.

Mit dem Pickit kannst du dann nachschauen, ob alle Flags sinnvolle Werte 
haben.

von Daniel78 (Gast)


Lesenswert?

Danke! Wie siehts aus, wenn ich alle ADC in die Low ISR rein pack und 
der Kontrolller nur noch von der high ISR aus der Low ISR herausgerissen 
wird und dann nach Abarbeitung der High isr zur Low ISR zurückkehrt ?

von Hurra (Gast)


Lesenswert?

Daniel78 schrieb:
> Danke! Wie siehts aus, wenn ich alle ADC in die Low ISR rein pack und
> der Kontrolller nur noch von der high ISR aus der Low ISR herausgerissen
> wird und dann nach Abarbeitung der High isr zur Low ISR zurückkehrt ?

Niemals in ISR warten. Das müsstest du bei einem ADC aber tun!

Wenn du in einer ISR auf das Ablaufen der Samplezeit wartest, blockierst 
du alle anderen niederprioren Interrupts. Oder schlimmer - du wirst 
dabei unterbrochen.

Gemessen werden sollte zum Beipiel im Main Loop oder einer eigenen 
Funktion.

Miss doch alle ADC Werte einfach zyklisch (z.B. alle 10ms). Oder benutze 
das Job-Flag-Konzept, welches von "Noch einer (Gast)" beschrieben wurde.

Ich an deiner Stelle würde einfach zyklisch messen, und die Werte im 
Speicher halten. Für eine Temperatur nur 1x pro Sekunde, oder alle 
100ms. Die ändert sich einfach nicht schnell genug, dass eine häufigere 
Messung Sinn ergibt.
Das eine Byte muss man halt übrig haben...

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
Noch kein Account? Hier anmelden.