Forum: Mikrocontroller und Digitale Elektronik STM32: ADC während PWM High lesen.


von Jana (Gast)


Lesenswert?

Hallo zusammen!
Ich haben einen Timer, der einen Pin mittels PWM-Signal ansteuert. Nun 
möchte ich während pwmHIGH eine Spannung mittels ADC messen. Am liebsten 
noch mit etwas Verzögerung. Nur wie bekomme ich das hin (Mein PWM-Timer 
hat leider nur einen Kanal)?

ideal:
1
           __________            __________
2
          |          |          |          |
3
          |          |          |          |
4
__________|          |__________|          |_________
5
                 ^                      ^            ADC Wert lesen
6
7
Meine Überlegung wäre die:
8
a) HAL_TIM_PeriodElapsedCallback startet den ADC. Dieser wird dann paar Takte später in HAL_ADC_ConvCpltCallback gelesen. Problem hierbei ist, dass ich nicht weiß, ob das Signal schon rechtzeitig am ADC anliegt (aa es erst während PWMhigh durchgeschaltet wird (ein OPV Propagation Delay), der ADC aber direkt mit pwmHigh startet))
9
[code]
10
           __________            __________
11
          |          |          |          |
12
          |          |          |          |
13
__________|          |__________|          |_________
14
          ^                     ^                    ADC start
15
            ^                     ^                  ADC in IT lesen


b) Mittels DMA permanent Werte in eine Schattenvariable schaufeln und 
dann in HAL_TIM_PeriodElapsedCallback den Wert in die Operationsvariable 
kopieren. Kann man das so machen?
1
           __________            __________
2
          |          |          |          |
3
          |          |          |          |
4
__________|          |__________|          |_________
5
^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ADC via DMA lesen
6
                    ^                     ^          Wert in Variable kopieren

Danke und gute Nacht :)

von Guido K. (Firma: Code Mercenaries GmbH) (thebug)


Lesenswert?

So was Ähliches habe ich kürzlich gemacht, allerdings benutze ich die 
HAL nicht, die verbraucht irre viel Speicher, macht komische Dinge und 
bei solchen Anwendungen muss man dann erst lernen, was die Timer können 
und dann wie die HAL das verwurstelt.

Wenn Du die Callback-Funktionen benutzt, ist nicht sicher, wie viel Zeit 
seit der Flanke vergangen ist, da ja erst mal der Interrupt aufgerufen 
werden muss, etc.

Sinnvoller ist es zwei Timer zu nehmen und den PWM Timer als Trigger für 
den Delay-Timer zu verwenden, der dann den ADC anstößt. So passiert das 
Sampling komplett in Hardware und die Software muss nur noch den 
gemessenen Wert abholen.

Dazu im Datenblatt rückwärts suchen, welche Timer den ADC triggern 
können und von welchen anderen Timer die wiederum getriggert werden 
können.

von Kevin M. (arduinolover)


Lesenswert?

Hilfreich wäre es zu wissen welchen Timer du benutzt. Normalerweise 
nutzt man dafür einen zweiten Channel oder bei Center Aligned PWM den 
Trigger wenn er überläuft. Möglichkeiten gibt es viele kommt eben ganz 
auf die Anwendung an.

von Jana (Gast)


Lesenswert?

Guido K. schrieb:
> Sinnvoller ist es zwei Timer zu nehmen und den PWM Timer als Trigger für
> den Delay-Timer zu verwenden, der dann den ADC anstößt. So passiert das
> Sampling komplett in Hardware und die Software muss nur noch den
> gemessenen Wert abholen.
>
> Dazu im Datenblatt rückwärts suchen, welche Timer den ADC triggern
> können und von welchen anderen Timer die wiederum getriggert werden
> können.

Danke, das klingt super und ist sicher eine sehr professionelle Lösung. 
Aber ich weiß ehrlich gesagt nicht, ob ich das in Registerprogrammierung 
hinbekomme. Ist denke ich nicht einfach, wenn man noch nicht so viel 
Erfahrung hat. Leider ist die Hardware auch schon fertig.

von Bauform B. (bauformb)


Lesenswert?

Manche Timer können einen zweiten Timer triggern.

Mit einer relativ großen sample time und dem passenden ADC-Takt geht es 
im Prinzip auch, nur die zeitliche Auflösung für die Verzögerung ist 
nicht so fein. Dabei wird der ADC mit der positiven PWM-Flanke gestartet 
und auch das Signal sofort durchgeschaltet. Die eigentliche Wandlung 
passiert aber erst, wenn das Signal stabil ist, ein paar Hundert 
ADC-Takte später.

Ob man das Ergebnis dann per DMA oder ADC-Interrupt oder erst beim 
nächsten Timer-Interrupt abholt, ist Geschmackssache.

von Jana (Gast)


Lesenswert?

Kevin M. schrieb:
> Hilfreich wäre es zu wissen welchen Timer du benutzt. Normalerweise
> nutzt man dafür einen zweiten Channel oder bei Center Aligned PWM den
> Trigger wenn er überläuft. Möglichkeiten gibt es viele kommt eben ganz
> auf die Anwendung an.

Ja, würde am liebsten auch 2 Channel benutzen wollen, jedoch hat mein 
Timer nur einen Channel (TIM16). Und der benutzte Pin kann leider nur 
auf TIM16 gemapped werden.

von Maxe (Gast)


Lesenswert?

Du kannst ja einen zweiten Timer parallel zum PWM-Timer laufen lassen. 
Dann bist du vom PWM-Ausgang unabhaengig. Allerdings meine ich war es 
beim F103 so, dass das Triggersignal auf einen Pin gefuehrt werden muss, 
um den ADC ausloesen zu koennen. Muesste also ein freier (offener) Pin 
sein.

von Kevin M. (arduinolover)


Lesenswert?

Der genaue Controller wäre auch hilfreich, allerdings ist Timer 16 
denkbar schlecht gewählt. Wenn ich mich richtig erinnere kann der den 
ADC onehin nicht Triggern. Mag aber sein das das auf manchen möglich 
ist. In dem Fall bleibt dir nur das Triggern über einen anderen Timer, 
die wirst du allerdings nicht synchron starten können.

von Jana (Gast)


Lesenswert?

Maxe schrieb:
> Du kannst ja einen zweiten Timer parallel zum PWM-Timer laufen lassen.
> Dann bist du vom PWM-Ausgang unabhaengig. Allerdings meine ich war es
> beim F103 so, dass das Triggersignal auf einen Pin gefuehrt werden muss,
> um den ADC ausloesen zu koennen. Muesste also ein freier (offener) Pin
> sein.

Das habe ich nicht ganz verstanden, aber gerade im Ref-Manual geschaut 
und leider kann TIM16 weder einen anderen Timer triggern, als von einem 
Timer getriggert werden.

Kevin M. schrieb:
> Der genaue Controller wäre auch hilfreich, allerdings ist Timer 16
> denkbar schlecht gewählt. Wenn ich mich richtig erinnere kann der den
> ADC onehin nicht Triggern. Mag aber sein das das auf manchen möglich
> ist. In dem Fall bleibt dir nur das Triggern über einen anderen Timer,
> die wirst du allerdings nicht synchron starten können.

Ich bin mir zwar nicht ganz sicher, aber ich glaube TIM16 ist wirklich 
der ungeeignetste Timer aller... :/ Es handelt sich um einen STM32G031.

Danke schonmal bis hier hin :)

von Kevin M. (arduinolover)


Lesenswert?

Ich befürchte das es keine wirklich elegante Lösung gibt, wenn du den 
Timer nicht wechseln kannst. Es gibt spezielle Timer wie 1, 8 und 20 die 
extra für Motor Anwendungen gedacht sind, die können auf mehrere Wege 
(update, compare, etc.) den ADC triggern. Manche general purpose Timer 
können das auch aber ggf. nur limitiert, wiederum andere können es 
garnicht. Sowas sollte man sich immer im Vorhinein überlegen. Du 
könntest Timer 1 nutzen, um den ADC zu triggern und ihn direkt nach dem 
PWM Timer starten, wie konsistent das funktioniert sei mal 
dahingestellt.

: Bearbeitet durch User
von Jana (Gast)


Lesenswert?

Also ich werde jetzt wahrscheinlich die Platine umlöten und auf TIM1 mit 
mehreren Channels wechseln. Den zweiten Channel outputless konfiguieren 
und ihm einfach einen Offset spendieren um den ADC zu starten.

von Jana (Gast)


Lesenswert?

Kevin M. schrieb:
> Ich befürchte das es keine wirklich elegante Lösung gibt, wenn du den
> Timer nicht wechseln kannst. Es gibt spezielle Timer wie 1, 8 und 20 die
> extra für Motor Anwendungen gedacht sind, die können auf mehrere Wege
> (update, compare, etc.) den ADC triggern. Manche general purpose Timer
> können das auch aber ggf. nur limitiert, wiederum andere können es
> garnicht. Sowas sollte man sich immer im Vorhinein überlegen. Du
> könntest Timer 1 nutzen, um den ADC zu triggern und ihn direkt nach dem
> PWM Timer starten, wie konsistent das funktioniert sei mal
> dahingestellt.

Du hast völlig recht. Habe ich auch jetzt gesehen. Ich hatte mich im 
Vorfeld leider nicht wirklich mit der Softwareseite auseinander gesetzt, 
bin nur hierüber gestolpert
1
HAL_TIM_PWM_PulseFinishedHalfCpltCallback
 und fand es perfekt geeignet. Hatte dann leider nichts mit meiner 
Vorstellung (dass die Funktion nach halbem Puls aufgerufen wird) zu tun 
(sondern mit DMA). Wie geschrieben werde ich dann mal zwei Pins mit 
Tüdeldraht umlöten und TIM1 nutzen.

von Kevin M. (arduinolover)


Lesenswert?

Um solche Spielereien im Vorfeld einfach zu prüfen bietet sich CubeMX 
ganz gut an (auch wenn hier gleich nochmal Leute auftauchen, die das 
Gegenteil behaupten werden, weil böses Cube). Alternativ findet sich das 
natürlich auch alles im Reference Manual.

von Jana (Gast)


Lesenswert?

Kevin M. schrieb:
> Um solche Spielereien im Vorfeld einfach zu prüfen bietet sich CubeMX
> ganz gut an (auch wenn hier gleich nochmal Leute auftauchen, die das
> Gegenteil behaupten werden, weil böses Cube). Alternativ findet sich das
> natürlich auch alles im Reference Manual.

Hast du absolut Recht. Ich hatte einfach nicht die Zeit dafür und 
dachte, wird schon passen. Während die Platine in Produktion ist (jetzt) 
wollte ich mich mit den Dokumenten beschäftigen. Einem Erfahrenen 
passieren solche Fehler wahrscheinlich nicht.

von Maxe (Gast)


Lesenswert?

Kevin M. schrieb:
> könntest Timer 1 nutzen, um den ADC zu triggern und ihn direkt nach dem
> PWM Timer starten, wie konsistent das funktioniert sei mal
> dahingestellt.
So wuere ich das im beschriebenen Fall (Hardware schon fertig) einfach 
mal probieren. Die Timer sollten dann per direkten Registerzugriff 
gestartet werden, das duerten dann nur ein paar CPU-Takte Differenz 
sein. Konfigurieren kann man die Timer ja trotzdem per HAL.
Bei gleicher Taktquelle und fester Periode koennen die Timer auch nicht 
auseinanderlaufen.
Klar, waere ein Hack, aber Tuedeldraht ist es auch.

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.