stm32 - USART Rx über DMA

OP #3013548
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
Gast #3013564
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....
Gast #3013868
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.
Gast #3014130
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.
Gast #3014132
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...
Gast #3014153
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 ;-)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren