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?
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.
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.
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.
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.
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.
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.
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.
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 :)
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.
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.
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.
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.
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.
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.