Elektroda.pl
Elektroda.pl
X

Wyszukiwarki naszych partnerów

Kategoria: Kamery IP / Alarmy / Automatyka Bram
Montersi
Kategoria: Akumulatorki / Baterie / Ładowarki

STM32 F4 (Nucleo F446RE) DMA UART RX - konfiguracja

KFplay4free 04 Lut 2017 14:25
  • #1 04 Lut 2017 14:25
    KFplay4free
    Poziom 3  

    Cześć, skonfigurowałem DMA i 2 UARTY (właściwie jeden USART, jeden UART), tak żeby odbierać dane z GPSa na UART4 i poprzez DMA przesyłać dane na stringa, a następnie wysyłać do putty`ego przez USART2. Na pewno dobrze skonfigurowałem UARTy, dane odbieram, natomiast DMA nie działa. Pewnie popełniłem błąd gdzieś w konfiguracji, ale porównywałem ją z różnymi przykładami w sieci i nic. Czy zapomniałe o jakiejś linijce? Z góry wielkie dzięki ;)
    PS. UART_init() to konfiguracja dla UARTa dla putty`ego, uart4_init() - do DMA

    Kod: c
    Zaloguj się, aby zobaczyć kod

  • #2 04 Lut 2017 14:48
    BlueDraco
    Specjalista - Mikrokontrolery

    A skąd wziąłeś krasnoludka, który pilnuje, żeby GPS rozpoczął transmisję wiersza po zaprogramowaniu DMA i drugiego, który pilnuje, żeby wszystkie wiersze miały po 99 znaków? Ja też chcę takie dwa krasnoludki!

    Pardon, zapomniałem o trzecim krasnoludku - tym od zerowana bufora danych przed transmisją.

  • #3 04 Lut 2017 18:24
    KFplay4free
    Poziom 3  

    Zaraz, zaraz. Trzeci krasnoludek to tablica globalna. Pierwszy - GPS nadaje ciągle w f = 1Hz, chyba, że masz na myśli coś innego. A drugi - z tego co zrozumiałem o DMA, to linia DMA_InitStructure.DMA_BufferSize = (uint16_t)sizeof(buf) - 1; powinna załatwić sprawę, tzn. po wysłaniu 99 znaków DMA skończy pracę. Ale nie wiem czy dobrze zrozumiałem DMA, stąd ten temat :)
    Pozdrawiam i dziękuję za odpowiedź.

  • #4 04 Lut 2017 18:26
    BlueDraco
    Specjalista - Mikrokontrolery

    Racja, tablica przed pierwszą transmisją zawiera zera. DMA zakończy po 99 znakach, pytanie, który to znak będzie ten 99-ty? GPS wysyła dane cyklicznie, a rekordy mają różne długości.

  • #5 04 Lut 2017 19:35
    Piotrus_999
    Poziom 38  

    zamiast tak dywagować (podejrzewam że masz nucleo) zamiast sprawdzać czy znak bedzie równy zero sprawdzaj flagę czy transmisja się już zakończyła. Zresztą najpierw bym proponował sprawdzić czy cokolwiek się transmituje z tego układu to lepiej zrobić to nie DMA, a dopiero później DMA. Bo tak masz 3 potencjalne problemy:
    1. Źle skonfigurowany UART
    2. Źle skonfigurowany GPS
    3. Żle skonfigurowane DMA

    Najpierw ustal czy p 1 i2 jest ok a dopiero po tym p. 3.

    Zresztą w tym kodzie nie masz żadnego ustawiania GPS-a a większość układów wymaga najpierw skonfigurowania, a dopiero później używania.

  • #6 05 Lut 2017 19:24
    KFplay4free
    Poziom 3  

    KFplay4free napisał:
    Na pewno dobrze skonfigurowałem UARTy, dane odbieram

    Tak więc jest to kwestia DMA. Piotrus_999 czy masz na myśli flagę przerwania w DMA?

  • #7 05 Lut 2017 19:34
    Piotrus_999
    Poziom 38  

    Nie wiem - nie używam usartów z dma w HAL - dużo prościej i logiczniej (dla mnie przynajmniej) jest napisać to na rejestrach.

  • #8 12 Lut 2017 17:10
    KFplay4free
    Poziom 3  

    Napisałem na rejestrach, ale bez oczekiwanego skutku...
    Załączam maina

    Kod: c
    Zaloguj się, aby zobaczyć kod

  • Pomocny post
    #9 12 Lut 2017 17:26
    Piotrus_999
    Poziom 38  

    KFplay4free napisał:
    (1 << 27)
    Tego nie będę rozszyfrowywał.

    I przy okazji nie mieszaj kodu HAL-a z rejestrami - w tch samych funkcjach - no chyba że dokładnie wiesz co te halowe robią na poziomie rejestrów (ja np poza kilkoma nie wiem i nie chce mi się grzebać)

    Procedurę masz opisaną w RM
    Cytat:
    Reception using DMA
    DMA mode can be enabled for reception by setting the DMAR bit in USART_CR3 register.
    Data is loaded from the USART_DR register to a SRAM area configured using the DMA
    peripheral (refer to the DMA specification) whenever a data byte is received. To map a DMA
    channel for USART reception, use the following procedure:
    1. Write the USART_DR register address in the DMA control register to configure it as the
    source of the transfer. The data will be moved from this address to the memory after
    each RXNE event.
    2. Write the memory address in the DMA control register to configure it as the destination
    of the transfer. The data will be loaded from USART_DR to this memory area after each
    RXNE event.
    3. Configure the total number of bytes to be transferred in the DMA control register.
    4. Configure the channel priority in the DMA control register
    5. Configure interrupt generation after half/ full transfer as required by the application.
    6. Activate the channel in the DMA control register.
    When the number of data transfers programmed in the DMA Controller is reached, the DMA
    controller generates an interrupt on the DMA channel interrupt vector. The DMAR bit should
    be cleared by software in the USART_CR3 register during the interrupt subroutine.
    Działa bez pudła

  • #10 13 Lut 2017 17:51
    KFplay4free
    Poziom 3  

    Piotrus_999 napisał:
    Tego nie będę rozszyfrowywał.
    KFplay4free napisał:
    DMA1_Stream2 -> CR = (1 << 27) | DMA_SxCR_MINC; // kanał 4, inkrementacja w pamięci

    Dzięki za procedurę z RM
    Pozdrawiam

  • #11 13 Lut 2017 17:54
    Piotrus_999
    Poziom 38  

    KFplay4free napisał:
    Dzięki za procedurę z RM
    Chodziło mi o to aby zrobić dokładnie tak, a nie raz hal, raz rejestry i w sumie nie wiesz tak naprawdę co się dzieje

  • #12 13 Lut 2017 18:03
    KFplay4free
    Poziom 3  

    Tak zrobię, spróbuję na samych rejestrach.

  • #13 16 Lut 2017 15:54
    KFplay4free
    Poziom 3  

    Próbowałem, ale znów bez skutku, skonfigurowałem DMAR na uarcie i przerwanie RXNE, zgodnie z procedurą, wszystkie ustawienia "liczbowe" opisałem w komentarzach. :/

    Kod: c
    Zaloguj się, aby zobaczyć kod
    PS. DMA_Cmd ustawia tylko bit w rejestrze DMA_CR

  • Pomocny post
    #14 16 Lut 2017 16:48
    Freddie Chopin
    Specjalista - Mikrokontrolery

    KFplay4free napisał:
    while(DMA1 -> LISR && DMA_LISR_TCIF2);

    Przyjrzyj się temu dobrze... Już nawet pomijam to, że jest odwrotnie logicznie.

    KFplay4free napisał:
    UART4 -> CR1 |= (1<<5); // RXNE

    I po co komu to przerwanie?

  • #15 17 Lut 2017 16:14
    KFplay4free
    Poziom 3  

    Dzięki wszystkim, udało się. Tak jak Freddie zauważył: zamiast DMA1 -> LISR && DMA_LISR_TCIF2) napisałem !(DMA -> LISR & DMA_LISR_TCIF2).
    Pozdrawiam serdecznie i jeszcze raz wielkie dzięki :)

  Szukaj w 4mln produktów
Przeglądaj produkty