Forum: Mikrocontroller und Digitale Elektronik stm32 - USART Rx über DMA


von peter m. (bastler788)


Lesenswert?

Hallo,

ich benutze USART3 eines stm32f100rb zur Kommunikation mit einem PC. 
Interruptgesteuert funktioniert alles soweit, aber nun möchte ich den 
Empfang über DMA machen, aber leider weis ich nicht so recht wie.
Initialisiert hab ich die DMA wie folgt:

DMA_InitTypeDef  DMA_InitStructure;

   /* USARTy RX DMA1 Channel (triggered by USARTy Rx event) Config */
   DMA_DeInit(USART3_Rx_DMA_Channel);
   DMA_InitStructure.DMA_PeripheralBaseAddr = USART3_DR_Base;
   DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RxBuffer1;
   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
   DMA_InitStructure.DMA_BufferSize = 7;
   DMA_Init(USART3_Rx_DMA_Channel, &DMA_InitStructure);

   /* DMA clock enable */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

   /* Enable USART3 DMA Rx and TX request */
   USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);

   /* Enable USARTy RX DMA1 Channel */
   DMA_Cmd(USART3_Rx_DMA_Channel, ENABLE);

  /* Enable the USARTy */
  USART_Cmd(USART3, ENABLE);

  /* Wait until USARTy RX DMA1 Channel Transfer Complete */
   while (DMA_GetFlagStatus(USART3_Rx_DMA_FLAG) == RESET)
   {
   }



Die Konfiguration des UARTS müsste stimmen da es ja über Interrupt 
funktioniert. den Interrupt hab ich aber auskommentiert da es über DMA 
funktionieren soll. verwende übrigens Keil uVision 4

von erst lesen, dann posten! (Gast)


Lesenswert?

In der ST-Stm32 StdPeripLib 
in.../Project/STM32F10x_StdPeriph_Examples/USART/ gibt es einige 
Beispiele zu dem was Du vorhast.

Schon reingeschaut?

>  /* Wait until USARTy RX DMA1 Channel Transfer Complete */
>   while (DMA_GetFlagStatus(USART3_Rx_DMA_FLAG) == RESET)
>   {
>   }

Wenn das nicht nur zum Ausprobieren ist, ist es ziemlicher Unsinn.

Während DMA läuft, hat die CPU besseres zu tun als Zyklen zu verbrennen.

>den Interrupt hab ich aber auskommentiert da es über DMA
>funktionieren soll

Den USART Interrupt schon, aber nicht den der DMA. Den brauchst Du,
wenn Du nicht die DMA pollen willst....

von peter m. (bastler788)


Lesenswert?

erst lesen, dann posten! schrieb:

> Den USART Interrupt schon, aber nicht den der DMA. Den brauchst Du,
> wenn Du nicht die DMA pollen willst....

doch den möchte ich pollen. die Empfangenen Zeichen müssten doch in dem 
RxBuffer1 stehen oder?

von erst lesen, dann posten! (Gast)


Lesenswert?

peter müller schrieb:
> erst lesen, dann posten! schrieb:
>
>> Den USART Interrupt schon, aber nicht den der DMA. Den brauchst Du,
>> wenn Du nicht die DMA pollen willst....
>
> doch den möchte ich pollen. die Empfangenen Zeichen müssten doch in dem
> RxBuffer1 stehen oder?

Wenn Du alles richtig gemacht hast. Schau halt die Beispiele an
und probier' die aus.

Wie gesagt: DMA und Pollen ist unsinnig, es sei denn zum Ausprobieren.

von peter m. (bastler788)


Lesenswert?

aber der Interrupt vom DMA löst doch erst aus wenn die eingestellte 
Zeichenzahl in dem DMA drin steht.

das Problem ist dann das sich die anzahl an zeichen variieren kann, also 
die empfangene Telegramme können unterschiedlich lang sein.

von erst lesen, dann posten! (Gast)


Lesenswert?

>das Problem ist dann das sich die anzahl an zeichen variieren kann, also
>die empfangene Telegramme können unterschiedlich lang sein.

Du solltest Dich mit dem Sinn von DMA beschäftigen, bevor Du 
programmierst.
Wenn es keine Mindestblocklänge oder vorher bekannte Blocklänge gibt, 
bringt DMA nix! DMA operiert auf Blockebene, nicht auf Zeichenebene!
Warum eine DMA beschäftigen, wenn trotzden jedes Zeichen angeschaut 
werden
muss.

Evtl. haben Deine Blöcke ja einen Header, der die Länge angibt.
Dann:
-- Header empfangen -- mit oder ohne DMA
-- Blocklänge bestimmen
-- DMA programmieren, um Rest des Blocks empfangen,
   CPU schläft derweil oder tut was anderes, jedoch nicht
   Warteschleifen drehen
-- Wenn DMA fertig, Interrupt, CPU behandelt den ampfangenen Block.

oder so ähnlich.

von Bastler (Gast)


Lesenswert?

>das Problem ist dann das sich die anzahl an zeichen variieren kann, also
>die empfangene Telegramme können unterschiedlich lang sein.

Für so etwas würde ich einen UART-Interrupt verwenden mit State-Machine.
DMA ist nicht immer sinnvoll...

von public (Gast)


Lesenswert?

Hallo Peter,

du hast viele Fragen ans Forum. Schau doch bitte mal hier vorbei:
http://diller-technologies.de/stm32.html#dma

Ich hoffe dort werden dir alle deine Fragen beantwortet.

Besten Gruß

von erst lesen, dann posten! (Gast)


Lesenswert?

Noch was zu:

>doch den möchte ich pollen. die Empfangenen Zeichen müssten doch in dem
>RxBuffer1 stehen oder?

Das ist u.U erst nach dem Ende des DMA Transfers garantiert.
Viele DMA Controller haben interne FIFOs mit 4K oder grösser.

Da kannst Du mglw. pollen bis Du schwarz wirst ;-)

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.