Forum: Mikrocontroller und Digitale Elektronik STM32 ADC Aktionen während der ADC Konvertierung


von Marcus (Gast)


Lesenswert?

Hallo,
wenn ich mit dem STM32F10x einen ADC-Wert konvertieren möchte muss ich 
doch warten bis die Konvertierung abgeschlossen ist:

while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);

kann man in dieser Zeit eigentlich andere Aktionen ausführen. Sprich 
entweder garkein While nutzen und nach einer Zeit die einem angemessen 
erscheint einfach mit dem ADC Wert arbeiten oder es in der Form 
schreiben:

while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET)
{
    Aktion A
    Aktion B
    ......
    ......
}

Oder sollte man den Controller während dieser Zeit in "Ruhe" lasssen? 
Ich frage weil mich die Wartezeit von ca. 8 µs stört.

von AVerr (Gast)


Lesenswert?

Lies dich mal im Thema Interrupts ein ...

von Marcus (Gast)


Lesenswert?

Sorry, wieso jetzt interrupts? Ist die ADC Konvertierung als 
Interruptaufruf zu verstehen oder gehst du davon aus dass ich meine 
Konvertierung in der ISR aufrufe? Ich hatte das mehr als eine Polling 
Abfrage verstanden die eine Art Bearbeitungszeit nach der Anfrage 
braucht und genauso hatte ich das auch aufgebaut. Ich weiß halt nicht ob 
die Konvertierung Parallel zum Programm verläuft oder ob der normale 
Ablauf unterbrochen werden muss. Ich würde sagen man muss nichts 
unterbrechen, sonst wäre die extra While Abfrage wohl nicht nötig. Bin 
mir aber nicht sicher.

[c]

ADC_SoftwareStartConvCmd(ADC1, ENABLE); //Start ADC Konvertierung
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
//Warte bis Konvertierung abgeschlossen

[c/]

Oder möchtest du mir damit jetzt sagen dass es im RM0008 im Kapitel 
Interrupts Hinweise darauf gibt?

von Marcus (Gast)


Lesenswert?

Sorry, wieso jetzt interrupts? Ist die ADC Konvertierung als
Interruptaufruf zu verstehen oder gehst du davon aus dass ich meine
Konvertierung in der ISR aufrufe? Ich hatte das mehr als eine Polling
Abfrage verstanden die eine Art Bearbeitungszeit nach der Anfrage
braucht und genauso hatte ich das auch aufgebaut. Ich weiß halt nicht ob
die Konvertierung Parallel zum Programm verläuft oder ob der normale
Ablauf unterbrochen werden muss. Ich würde sagen man muss nichts
unterbrechen, sonst wäre die extra While Abfrage wohl nicht nötig. Bin
mir aber nicht sicher.
1
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //Start ADC Konvertierung
2
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); //Warte bis Konvertierung abgeschlossen

Oder möchtest du mir damit jetzt sagen dass es im RM0008 im Kapitel
Interrupts Hinweise darauf gibt?

von Helmut L. (helmi1)


Lesenswert?

Wenn du Start und Abfrage vertauschst in der Reihenfolge kannst du auch 
was anderes tun. Du must halt immer nur vorrausschauend den ADC vorher 
starten wenn es geht.

while(1) // Grosse schleife
{
   if (ADC_fertig())
   {
      GetADCValue();
      // tu was damit
      StartADC();   // naechste Wandlung starten
   }

   // ansonsten alles andere tun
}

von SF (Gast)


Lesenswert?

Normalerweise würde man einen ADC so konfigurieren, das er automatisch 
regelmäßig AD-Wandlungen macht und wenn er fertig ist, dann einen 
Interrupt auslöst.

In der Interruptroutine würde man das Ergebnis abholen, eventuell noch 
filtern, Mittelwerte bilden und ein Flag setzen, das dem Hauptprogramm 
mitteilt, das ein neuer ADC-Wert zur Verfügung steht.

Eventuell kann man auch per DMA automatisch die Werte ins RAM kopieren 
lassen und der DMA löst dann den Interrupt aus.

von Marcus (Gast)


Lesenswert?

Super, danke.
Ich habe das so gewählt, weil ich die Messungen zu ganz bestimmten 
Zeitpunkten benötige. Die Genauigkeit ist dabei nicht so wichtig, da ich 
mit dem ADC nur Flankenmessungen kontrolliere und mir dann die Tendenz 
reicht. Mittelwertbildungen könnte ich mir wenn dann wohl nur mit dem 
.... wie hieß das noch gleich..... Oversampling... erreichen, da die 
Messzeit die mir bleibt bei ca. 20 µs liegt.

Mit dem Wissen nebenher noch etwas tun zu können kann ich jetzt aber 
schonmal andere Aktionen dazwischen Quetschen ;-)

von Helmut L. (helmi1)


Lesenswert?

Marcus schrieb:
> Ich habe das so gewählt, weil ich die Messungen zu ganz bestimmten
> Zeitpunkten benötige.

In dem Fall wuerde ich den ADC vom Timer starten lassen und bei 
"Wandlung fertig" einen Interrupt generieren lassen (oder DMA triggern).
Damit hast du den geringsten Overhead in deinem Programm.

von Marcus (Gast)


Lesenswert?

Die Zeitpunkte werden von externen Flanken vorgegeben Es handelt sich 
dabei um Protokolle mit 3 Stufigen Pegeln. Allerdings verwende ich keine 
Interrupts, da der Rest des Programms ohnehin schnell genug sein muss um 
die Pegel sofort auszuwerten und weiter zu verarbeiten. Die Zeitwerte 
werden via DMA aufgenommen. Würde ein Teil des Programms zu langsam 
laufen käme alles in Verzug. Daher verzichte ich auf weitere Interrupts. 
Die Neue Zeitlücke bei der Konvertierung nutze ich nun unter anderem um 
meine DMA Reloads durchzuführen.

von Helmut L. (helmi1)


Lesenswert?

Du kannst den ADC aber auch durch einen Portpin triggern lassen.

von Marcus (Gast)


Lesenswert?

ja, ich möchte aber einen Kleinen Verzug haben um eventuelles Prellen 
oder Fehlimpulse auszuschließen. Obwohl mir fällt gerade ein dass es 
einen Filter für die ADCs gibt der das ganze auch Verzögern sollte. 
Eigentlich eine gute Idee...
Ich glaube das versuche ich nachher auch mal.

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.