Forum: Mikrocontroller und Digitale Elektronik STM32F4 UART2 - Empfangen mit DMA


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von murmel (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,

ich versuche gerade 1 Byte auf dem UART2 des STM32F4-Discovery Board mit 
DMA zu empfangen. Mit Interrupts hat alles relativ problemlos 
funktioniert, hier aber irgendwie nicht. Senden mit DMA tut ohne 
Probleme.

UART Initialisierung
    uart2Handle.Instance = USART2;
    uart2Handle.Init.BaudRate = 2000000;
    uart2Handle.Init.WordLength = UART_WORDLENGTH_8B;
    uart2Handle.Init.StopBits = UART_STOPBITS_1;
    uart2Handle.Init.Parity = UART_PARITY_NONE;
    uart2Handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    uart2Handle.Init.Mode = UART_MODE_TX_RX;
    uart2Handle.Init.OverSampling = UART_OVERSAMPLING_16;

    /* NVIC for USART2 */
    HAL_NVIC_SetPriority(USART2_IRQn, 15, 0);
    HAL_NVIC_EnableIRQ(USART2_IRQn);

DMA Initialisierung

     /* DMA'ize TX path */
     hdma_tx.Instance                 = DMA1_Stream6;
     hdma_tx.Init.Channel             = DMA_CHANNEL_4;
     hdma_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
     hdma_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
     hdma_tx.Init.MemInc              = DMA_MINC_ENABLE;
     hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
     hdma_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
     hdma_tx.Init.Mode                = DMA_NORMAL;
     hdma_tx.Init.Priority            = DMA_PRIORITY_LOW;
     hdma_tx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
     hdma_tx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
     hdma_tx.Init.MemBurst            = DMA_MBURST_INC4;
     hdma_tx.Init.PeriphBurst         = DMA_PBURST_INC4;

     HAL_DMA_Init(&hdma_tx);

     /* Link UART TX path to DMA */
     __HAL_LINKDMA(&uart2Handle, hdmatx, hdma_tx);

     /* DMA'ize RX path */
     hdma_rx.Instance                   = DMA1_Stream5;
     hdma_rx.Init.Channel               = DMA_CHANNEL_4;
     hdma_rx.Init.Direction             = DMA_PERIPH_TO_MEMORY;
     hdma_rx.Init.PeriphInc             = DMA_PINC_DISABLE;
     hdma_rx.Init.MemInc                = DMA_MINC_DISABLE;
     hdma_rx.Init.PeriphDataAlignment   = DMA_PDATAALIGN_BYTE;
     hdma_rx.Init.MemDataAlignment      = DMA_MDATAALIGN_BYTE;
     hdma_rx.Init.Mode                  = DMA_NORMAL;
     hdma_rx.Init.Priority              = DMA_PRIORITY_LOW;
     hdma_rx.Init.FIFOMode              = DMA_FIFOMODE_DISABLE;
     hdma_rx.Init.FIFOThreshold           = DMA_FIFO_THRESHOLD_HALFFULL;
     hdma_rx.Init.MemBurst = DMA_MBURST_SINGLE;
     hdma_rx.Init.PeriphBurst = DMA_PBURST_SINGLE;

     HAL_DMA_Init(&hdma_rx);

     /* Link UART RX path to DMA */
     __HAL_LINKDMA(&uart2Handle, hdmarx, hdma_rx);


     /* Set priorities */
     HAL_NVIC_SetPriority(DMA1_Stream6_IRQn, 14, 0);
     HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn);

      HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 14, 0);
     HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);

Last but not least die Interrupt Routinen

/* UART DMA RX Handle */
void DMA1_Stream5_IRQHandler(void)
{
  HAL_DMA_IRQHandler(uart2Handle.hdmarx);
}

/* UART DMA TX Handle */

void DMA1_Stream6_IRQHandler(void)
{
  HAL_DMA_IRQHandler(uart2Handle.hdmatx);
}


/* USART2 interrupt */
void USART2_IRQHandler(void) {
    HAL_UART_IRQHandler(&uart2Handle);
}


Hat jemand Vorschläge? Ich hab auch schon endlose Bytes auf die 
UART-Gebombt, in der Hoffnung das ich nur einen Buffer falsch definiert 
hätte. Aber da kommt nix.

von murmel (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Ach du heiliges Frickeltier, man muss einmalig auslesen um den RX-Modus 
scharf zu schalten:
   if (HAL_UART_Receive_DMA(&uart2Handle, &int_rx_char, sizeof(uint8_t)) != HAL_OK)
    {
        error_function();
    }


Schönes Wochenende allerseits.

von Marcel M. (goenndir)


Bewertung
0 lesenswert
nicht lesenswert
murmel schrieb:
> Ach du heiliges Frickeltier, man muss einmalig auslesen um den RX-Modus
> scharf zu schalten:
>    if (HAL_UART_Receive_DMA(&uart2Handle, &int_rx_char, sizeof(uint8_t))
> != HAL_OK)
>     {
>         error_function();
>     }
>
> Schönes Wochenende allerseits.

Ich hänge momentan auch an dem selben Problem Daten via UART im DMA zu 
empfangen. Nun ist mir aufgefallen, dass ich einmalig die Funktion 
HAL_UART_Receive_DMA() mit den entsprechenden Übergabeparameter in der 
main aufrufen muss, damit ich was empfange. Aber warum ist das so? Kann 
mir das jemand erklären?

Vielen Dank :)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.