Forum: Mikrocontroller und Digitale Elektronik STM32F4 DMA-Interrupts und DMA-Resets


von Michaela (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich kämpfe hier recht verzweifelt mit den STM32F4 herum und benötige 
gerade wieder zwei kleine Hilfestellungen.

Zum einen möchte ich bei einem DMA 2 Interrupts aktivieren. Genauer geht 
es um den DMA2 channel6 stream2. Von dem benötige ich den Half-Transmit- 
und Full-Transmit-Interrupt und verzweifle bei der Namensuche.
Häufig finde ich dann Konstrukte wie
1
void DMA1_Channel1_IRQHandler(void)
2
{
3
  //Test on DMA1 Channel1 Transfer Complete interrupt
4
  if(DMA_GetITStatus(DMA1_IT_TC1))
5
  {
6
      status=1;
7
      LEDToggle(LEDG);
8
   //Clear DMA1 Channel1 Half Transfer, Transfer Complete and Global interrupt pending bits
9
    DMA_ClearITPendingBit(DMA1_IT_GL1);
10
  }
11
}
die mich dann vollends verwirren, denn wenn schon ein Interrupt 
ausgelöst wurde, warum dann noch der Check in Software? Das macht für 
mich keinen Sinn!
Und auch wenn ich aus dem Namen des Interrupts auf den gesuchten Namen 
schließen könnte, es muss doch ein Dokument geben, in dem diese 
Bezeichungen niedergeschrieben sind?! Man kann doch nicht jeden 
Interrupt-Namen erraten müssen?


Und zu meinem 2. Problem:
Wenn der DMA alle Daten übertragen hat soll er gestoppt und wieder auf 
null gestellt werden. Das Problem dabei ist, dass der DMA möglicherweise 
auch alle Daten übertragen haben kann wenn er garade bei der Hälfte 
seines Puffers angekommen ist. Zur Verdeutlichung das Bild im Anhang.
Die Daten liegen im Speicher und werden von dort in einem Interrupt 
konvertiert (dabei wird aus einem Byte acht Byte, daher die späte 
Konvertierung) und in den Puffer des DMA geladen (jenachdem welcher 
Interrupt natürlich auch nur die entsprechende Hälfte des Puffers). 
Jetzt kann es aber sein, dass alle Daten übertragen wurden und der DMA 
gerade beim Half-Transmit angekommen ist. wenn ich nun an dieser Stelle 
stoppen würde, dann würde beim nächsten Start wohl erst die 2.Hälfte des 
Puffers übertragen und danach erst die erste Hälfte. Die Daten die vor 
dem Neustart des DMA aber in dessen Puffer laden möchte sind aber so 
formatiert, dass der DMA auch mit der ersten Hälfte beginnen soll. Nun 
frage ich mich, ob der DMA für diesen Neustart wirklich (wie so oft im 
Internet behauptet wird) komplett deinitialisiert und dann neu 
initialisiert werden muss.
Weiß hier jemand Rat?


Vielen Dank
Grüße Michaela

von Uwe B. (derexponent)


Lesenswert?

Hi Michaela,

Michaela schrieb:
> Man kann doch nicht jeden
> Interrupt-Namen erraten müssen?

sieh mal in der "startup_stm32f4xx.c" nach...da wirst du fündig

Michaela schrieb:
> denn wenn schon ein Interrupt
> ausgelöst wurde, warum dann noch der Check in Software? Das macht für
> mich keinen Sinn!

es macht einen Sinn, wenn man weiß das es mehrere Quellen
für einen DMA-Interrupt gibt

ließ mal im Referenz Manual nochmal unter "DMA" nach

"DMA_GetITStatus(DMA1_IT_TC1)" wertet den "Transfer-Complete-Interrupt" 
aus
es gäbe aber z.B. noch "Half-Transfer-Interrupt" der löst die gleiche 
Interrupt-Funktion

Gruss Uwe

von Uwe B. (derexponent)


Lesenswert?

Michaela schrieb:
> Nun
> frage ich mich, ob der DMA für diesen Neustart wirklich (wie so oft im
> Internet behauptet wird) komplett deinitialisiert und dann neu
> initialisiert werden muss.

disabeln musst du ihn auf jeden Fall,
(und warten bis er wirklich steht)
aber neuinitialisieren wohl nicht
es wird reichen den Startpointer wieder auf Anfang zu setzen

Gruss Uwe

von Patrick B. (p51d)


Lesenswert?

Michaela schrieb:
> Das Problem dabei ist, dass der DMA möglicherweise
> auch alle Daten übertragen haben kann wenn er garade bei der Hälfte
> seines Puffers angekommen ist.

Ich sehe dein Problem nicht. Wenn du dem DMA Daten übergibst, dann 
kannst du ja den Counter so setzen, dass er nur die Menge an Daten 
bearbeitet, die du willst. Ebenso musst du auch kein Interrupt machen, 
wenn du dich nach dem Beenden nicht um etwas spezielles kümmern musst. 
Da reicht normales (nicht kontinuierlich) senden.

Falls du aber Daten Empfangen willst, musst du schon irgendwoher wissen 
wieviel da kommt. Entweder hast du ein Header und stelltst den DMA 
dementsprechend ein oder du hast ein Ring-Puffer, in den du deine 
Datenblöcke kopierst. Da brauchst du auch nur eine fixe grösse. Das 
Problem ist dann aber dass du nicht auf echtzeitbasis arbeiten kannst.

DMA eignet sich nur bei BLÖCKEN, deren Grösse bekannt ist. Oder über 
Ring-Puffer aber ohne "Echtzeit".

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.