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


von murmel (Gast)


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
1
    uart2Handle.Instance = USART2;
2
    uart2Handle.Init.BaudRate = 2000000;
3
    uart2Handle.Init.WordLength = UART_WORDLENGTH_8B;
4
    uart2Handle.Init.StopBits = UART_STOPBITS_1;
5
    uart2Handle.Init.Parity = UART_PARITY_NONE;
6
    uart2Handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
7
    uart2Handle.Init.Mode = UART_MODE_TX_RX;
8
    uart2Handle.Init.OverSampling = UART_OVERSAMPLING_16;
9
10
    /* NVIC for USART2 */
11
    HAL_NVIC_SetPriority(USART2_IRQn, 15, 0);
12
    HAL_NVIC_EnableIRQ(USART2_IRQn);

DMA Initialisierung
1
     /* DMA'ize TX path */
2
     hdma_tx.Instance                 = DMA1_Stream6;
3
     hdma_tx.Init.Channel             = DMA_CHANNEL_4;
4
     hdma_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
5
     hdma_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
6
     hdma_tx.Init.MemInc              = DMA_MINC_ENABLE;
7
     hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
8
     hdma_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
9
     hdma_tx.Init.Mode                = DMA_NORMAL;
10
     hdma_tx.Init.Priority            = DMA_PRIORITY_LOW;
11
     hdma_tx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
12
     hdma_tx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
13
     hdma_tx.Init.MemBurst            = DMA_MBURST_INC4;
14
     hdma_tx.Init.PeriphBurst         = DMA_PBURST_INC4;
15
16
     HAL_DMA_Init(&hdma_tx);
17
18
     /* Link UART TX path to DMA */
19
     __HAL_LINKDMA(&uart2Handle, hdmatx, hdma_tx);
20
21
     /* DMA'ize RX path */
22
     hdma_rx.Instance                   = DMA1_Stream5;
23
     hdma_rx.Init.Channel               = DMA_CHANNEL_4;
24
     hdma_rx.Init.Direction             = DMA_PERIPH_TO_MEMORY;
25
     hdma_rx.Init.PeriphInc             = DMA_PINC_DISABLE;
26
     hdma_rx.Init.MemInc                = DMA_MINC_DISABLE;
27
     hdma_rx.Init.PeriphDataAlignment   = DMA_PDATAALIGN_BYTE;
28
     hdma_rx.Init.MemDataAlignment      = DMA_MDATAALIGN_BYTE;
29
     hdma_rx.Init.Mode                  = DMA_NORMAL;
30
     hdma_rx.Init.Priority              = DMA_PRIORITY_LOW;
31
     hdma_rx.Init.FIFOMode              = DMA_FIFOMODE_DISABLE;
32
     hdma_rx.Init.FIFOThreshold           = DMA_FIFO_THRESHOLD_HALFFULL;
33
     hdma_rx.Init.MemBurst = DMA_MBURST_SINGLE;
34
     hdma_rx.Init.PeriphBurst = DMA_PBURST_SINGLE;
35
36
     HAL_DMA_Init(&hdma_rx);
37
38
     /* Link UART RX path to DMA */
39
     __HAL_LINKDMA(&uart2Handle, hdmarx, hdma_rx);
40
41
42
     /* Set priorities */
43
     HAL_NVIC_SetPriority(DMA1_Stream6_IRQn, 14, 0);
44
     HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn);
45
46
      HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 14, 0);
47
     HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);

Last but not least die Interrupt Routinen
1
/* UART DMA RX Handle */
2
void DMA1_Stream5_IRQHandler(void)
3
{
4
  HAL_DMA_IRQHandler(uart2Handle.hdmarx);
5
}
6
7
/* UART DMA TX Handle */
8
9
void DMA1_Stream6_IRQHandler(void)
10
{
11
  HAL_DMA_IRQHandler(uart2Handle.hdmatx);
12
}
13
14
15
/* USART2 interrupt */
16
void USART2_IRQHandler(void) {
17
    HAL_UART_IRQHandler(&uart2Handle);
18
}

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)


Lesenswert?

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

Schönes Wochenende allerseits.

von Marcel M. (goenndir)


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 :)

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.