STM32 DMA: Kontinuierliche Übertragung von Peripheriegerät zu Speicher (Array).

Ich versuche, einen DMA im Zirkularmodus zu verwenden, um Daten von einem ADC an ein Array zu übertragen, das die Daten enthält. Ich muss gleichzeitig die eingehenden Daten verwenden (in diesem Fall verwende ich AT-Befehle, um die Daten mit dem esp8266-Modul über Wi-Fi zu senden).

Ich frage mich, wie der Softwarefluss aussehen würde.

Hier sind einige Fragen:

  • Woher weiß der DMAC, wann er umbrechen muss, wenn er das Ende des Arrays erreicht? - dh wie kann ich sicherstellen, dass der DMA keine Daten über den letzten Array-Index hinaus überträgt? (Ist diese Größenbeschränkung durch DMA_BufferSize definiert?)

  • Da ich die gesammelten Daten gleichzeitig verwenden möchte, denke ich darüber nach, 3 Arrays zum Speichern der Daten zu verwenden. Ich würde die Daten aus einem Array lesen und löschen, während die anderen vom DMA gefüllt werden, und es würde herumlaufen. Ist es klug und/oder möglich, das DMA-Ziel ständig so zu ändern?

Danke schön.

Antworten (2)

Woher weiß der DMAC, wann er umbrechen muss, wenn er das Ende des Arrays erreicht? - dh wie kann ich sicherstellen, dass der DMA keine Daten über den letzten Array-Index hinaus überträgt? (Ist diese Größenbeschränkung durch DMA_BufferSize definiert?)

Ja, es stoppt entweder an dem von Ihnen festgelegten Limit oder wenn Sie den Zirkularmodus aktivieren , beginnt es von vorne und überschreibt Daten am Anfang des Arrays. Es wird nie über die Grenze gehen.

Ich würde die Daten aus einem Array lesen und löschen, während die anderen vom DMA gefüllt werden, und es würde herumlaufen. Ist es klug und/oder möglich, das DMA-Ziel ständig so zu ändern?

Auf dem STM32 können Sie ein großes Array zuweisen und die beiden Hälften als Doppelpuffer verwenden. Es gibt einen Half-Transfer-Interrupt (wenn aktiviert), der Ihnen mitteilt, dass die erste Hälfte gefüllt und zur Verarbeitung bereit ist und die zweite Hälfte modifiziert wird. Dann erhalten Sie eine Unterbrechung der Übertragung abgeschlossen , wenn die zweite Hälfte fertig ist, und (im kreisförmigen Modus) wird die erste Hälfte erneut aktualisiert.

Es besteht also keine Notwendigkeit, das DMA-Ziel zu ändern (das geht sowieso nicht, während DMA läuft), aber Sie können immer feststellen, welche Hälfte bereit ist, indem Sie die DMA-Statusbits untersuchen.

Auf High-End-Controllern (STM32F4, STM32F7) gibt es tatsächlich zwei Speicheradressen für jeden DMA-Kanal, die Pufferhälften müssen nicht zusammenhängend sein, und Sie können sogar die Adresse des inaktiven Puffers im laufenden Betrieb ändern.

Ich verstehe, das macht sehr viel Sinn – ich war mir dieser Funktion nicht bewusst. Danke!
Nicht alle STM32 - oder besser gesagt ihre DMA-Kanäle - unterstützen den Half-Transfer-Interrupt.

Es scheint, dass der STM32-DMA den Double-Buffering-Betrieb unterstützt (ich bin kein STM32-Profi, daher kann ich Ihnen nicht sagen, was die zugehörigen API-Aufrufe sind). Das ist es, was Sie eigentlich suchen. So handhaben Sie es:

  1. Sie konfigurieren Größe und Speicherort für zwei Puffer. Normalerweise sind diese beiden gleich groß
  2. Sie starten die DMA-Übertragung
  3. Sobald der erste Puffer gefüllt ist, beginnt der DMA-Controller automatisch mit dem Speichern im zweiten Puffer ohne fehlende Daten
  4. Gleichzeitig (wenn der DMA den Puffer umschaltet) erhalten Sie einen Interrupt, der besagt, dass der Puffer voll war. Jetzt ist es an der Zeit, auf die Daten in Puffer 1 einzuwirken, während Puffer 2 gefüllt wird
  5. Sobald Puffer 2 voll ist, beginnt der DMA-Controller mit dem Überschreiben von Daten an der ersten Pufferstelle, ohne dass irgendwelche Daten oder was auch immer gelöscht werden müssen. Auch hier erhalten Sie einen Interrupt und können nun mit den in Buffer 2 gespeicherten Daten arbeiten.
  6. Wiederholen Sie von Anfang an

Grundsätzlich ist die Idee, dass der DMA einen Puffer füllt, während Sie am anderen arbeiten, die Umschaltung zwischen den beiden vom DMA-Controller selbst durchgeführt wird und Sie keine Daten aufgrund der Zeit verlieren, die zum Umschalten zwischen den Puffern erforderlich ist, wenn Sie haben es in der Software gemacht.

Die Daten, die auf einmal übertragen werden, sind - wie Sie sagten - normalerweise in eines der DMA-Register programmiert, BufferSize klingt nach dem richtigen Weg (obwohl ich dies für den STM32 nicht bestätigen kann, da ich diese Plattform nicht so gut kenne). .

Der Doppelpuffer ist eine saubere Lösung. Ich verwende jedoch einen STM32F0, der diese Funktion nicht unterstützt.