Hallo, bei mir verhält sich der DMA in Verbindung mit dem ADC1 etwas
zickig.
Der ADC soll 4 Kanäle durchlaufen, also das SCAN Bit ist gesetzt und das
soll er endlos tun -> CONT Bit ist auch gesetzt.
Wenn ich jetzt den IRQ auf den ADC draufloslasse, so bekomme ich auch
jeden Wert zurück und kann den in ein Array einsortieren.
Jetzt soll aber der DMA das abholen, da der ADC doch recht schnell ist
und die ganzen IRQs den CPU Kern zu sehr belasten.
Daher ist das DMA Bit gesetzt im ADC.
Der DMA selber ist auf den Circle Modus gestellt.
Beim ersten SCAN Durchlauf landen die Werte auch schön per DMA im Array,
aber danach ist funkstille auf dem DMA Stream.
Ich weis nicht ob der ADC keinen DMA request mehr raushaut oder der DMA
doch irgendwie meint, dass jetzt Schluss ist?
Als Code nutz ich nicht den Gencode vom STMCUBE, ich wollt da was selber
häkeln ;)
Hier mal die wichtigen Codeschnipsel:
adc.c:
Du musst continuous requests für DMA aktivieren, damit das mit dem
continuous conversion Modus funktioniert.
Ich weiß nicht, ob das im Datenblatt auch so heißt, aber so heißt es in
CubeMX.
Das wäre das DDS bit.
Wie man sieht, hab ich das inzwischen wieder auskommentiert.
Wenns aktiviert ist dann landet der DMA nämlich andauernd (=
Dauerschleife) im "DMA hat fertig" IRQ.
Mw E. schrieb:> Wenns aktiviert ist dann landet der DMA nämlich andauernd (=> Dauerschleife) im "DMA hat fertig" IRQ
Ich hab es mir jetzt nicht den ganzen Sourcecode zugeführt, aber du
musst das Interrupt-Flag vom DMA manuell wieder löschen. Siehe
Datenblatt.
@Simon,
Der Versuch zählt!
@Nils N.
Exakt und vor jedem INit eines DMA.
Den IRQ Handler hab ich ganz verpennt reinzuposten, ups!
Der macht nämlich genau das (Mitm Vorschlghammer alle Bits auf 0
Klopfen):
dma.c:
Ich finde es immer wieder klasse, wenn man erkennt, dass man HAL nicht
braucht und Register viel praktischer sind. Lesbarer, kürzer und man
lernt den Prozessor kennen und hat alles selber in der Hand.
Aber bitte, bitte benutze Registermasken.
Das
Am besten packst du diese Zeile in ein Makro, dann wird es kurz und
super lesbar! Und das Makro kommt natürlich in eine eigene Headerdatei
und wird überall eingefügt, wo dus brauchst! Ist so natürlich noch nicht
fertig das Makro, aber als Idee..
Die 4 und die 6 könnt man noch ersetzen durch defines.
"STREAM_PER_REG"
"BITS_PER_STREAM"
Ich wollt eben NICHT alle Bitnamen ins enum werfen wo sich nur ne Zahl
ändert
.. mea culpa
Aber ich bin kuurz vorm umkippen meiner Meinung, gibts nochn starkes
Argument ;)?
Der HAL für die STM32 ist mir zu viel Tipparbeit mit den ausschweifenden
Elementnamen im struct und die passenden Values dazu.
Zudem versteht man dann auch nicht was es tut, genau richtig erkannt ;)
STMCube schießt dann noch den Vogel ab, dass es einen absoluten Pfas zum
GCC will und der muss innerhalb des Projekts liegen.
(Ich kann den Pfad unter "Toolchain Folder Location" nur verlängern aber
nicht kürzen)
Jetz funktioniert was nicht, da muss man sich mehr durch die Register
wühlen.
Wenn mit dem HAL was nicht geht, dann muss man im HAL UND in den
Registern nach dem Fehler wühlen.
Nun, ich programmiere den STM32 auch nur über Register. Zum Clock
einstellen brauche ich z.B. 11 Zeilen Code, alles nur einzelne
OR-Anweisungen etc. PLL aktivieren. HSE ektiviert, PLL aktivieren und
einstellen, HSI deaktivieren usw...
Um einen Timer einzustellen sind es meist ~5 Zeilen.
Die Peripherie der STM32 bietet oft sehr viele Zusatzfunktionen. Wenn
man diese aber einfach ignoriert und aus lässt - und das kann man in der
Regel - ist die Peripherie mit Registern nicht schwerer zu
parametrieren, als auf einem XMEGA oder gar einem Atmega (z.B. SPI).
LÄUFT!
Was wars?
Ersteinmal das fehlende DDS Bit beim SCAN+CONT Mode.
Dann liefs auch eigentlich schon, das "unendliche Aufrufen" des Transfer
End IRQs scheint wohl auch richtig zu sein obwohl der DMA eigentlich nie
zuende geht wenn er auf Zirkulär geschalten ist.
-> Trotzdem wird der IRQ ausgelöst.
-> Schalten wir den im SCAN+CONT Mode eben ab und lauschen nurnoch auf
die Fehler IRQ des ADC und des DMA.
Dadurch hat meine kleine Debugausgabe im IRQ den UART so vollgespammt,
ass die Arrayausgabe nicht mehr stattfand.
Manchmal sieht sone Tischkante echt lecker aus :/