logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[STM32][USART][DMA] - Nadawanie przez USART z wykorzystaniem DMA STM32DISCOVERY

wojlej 15 Lut 2013 23:49 26631 125
Najlepsze odpowiedzi

Jak wysyłać inkrementowaną zmienną przez USART z użyciem DMA na STM32, tak aby terminal dostał poprawne wartości 0–255?

Trzeba najpierw przygotować cały bufor danych, a dopiero potem uruchomić DMA — `TxBuf` powinien być tablicą bajtów, wypełnianą przed startem transmisji, a jako źródło DMA podajesz adres tablicy, nie pojedynczej zmiennej; przy ponownym użyciu trzeba też ustawić od nowa adres źródła i licznik, oraz używać trybu Normal zamiast Circular dla takiego jednorazowego wysyłania [#11941826][#11944311][#11946874] Jeśli plik z konfiguracją jest osobny, bufor trzeba zadeklarować jako `extern` z dokładnie tym samym rozmiarem, bo `char TxBuf` i `char TxBuf[256]` to zupełnie różne rzeczy [#11946907][#11946970] W Twoim przypadku problem wynikał też z tego, że DMA było odpalane w pętli bez czekania na zakończenie transferu, więc adres pamięci „uciekał” poza bufor i pojawiały się losowe dane [#11943636][#11944311] Dla późniejszego ADC lepszy jest układ ping-pong: dwa bufory, ADC wyzwalane timerem, DMA zapisuje do jednego bufora, a po zakończeniu transferu przygotowujesz drugi bufor i wysyłasz pierwszy przez USART [#11949522][#11951730][#11951868] Dodatkowo dla USART pamiętaj, że rejestr danych ma 8 bitów, więc do kanału TX DMA trzeba zaprogramować transfer bajtowy, a nie słowowy [#12023724]
Wygenerowane przez model językowy.
REKLAMA
  • #1 11940670
    wojlej
    Poziom 17  
    Posty: 366
    Ocena: 101
    Witam,

    Jako że jestem początkujący w dziedzinie STM32 napotkałem problem nie do przejścia. Moim zadaniem jest wysyłanie inkrementowanej zmiennej "Dane" która jest wysyłana przez USART i odczytanie jej przez terminal. W konsekwencji wyrysowując otrzymane wartości powinienem uzyskać coś podobnego do piły o amplitudzie od 0 do 255. Bez DMA wszystko pracuje ładnie, ale muszę je wykorzystać dlatego proszę o pomoc.

    Proszę o zerknięcie do kodów i nakierowanie na poprawną drogę myślenia. Wiem prawie na pewno że pętla główna jest zła, ale nie mam pojęcia jak wpisać zmienną Dane do bufora TxBuf.
    Pętla główna:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Funkcja konfiguracyjna Board();

    Kod: text
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #2 11941094
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Ciekawe, że właśnie zacząłem pisać podobny kod... Skończę pewnie wieczorem.

    Zmienną zapewne chcesz zamienić na ciąg cyfr, żeby coś zobaczyć na terminalu - napisz własną funkcję albo użyj sprintf lub itoa. Kiedy już przygotujesz ten ciąg cyfr w buforze - zaprogramuj i włącz DMA.
  • REKLAMA
  • #3 11941224
    wojlej
    Poziom 17  
    Posty: 366
    Ocena: 101
    Nie za bardzo rozumiem. Przecież Dane i TxBuf są jako unsigned int. Wysyłając Taką zmienną bez DMA poprzez USART_Send w terminalu otrzymuje ciąg cyfr. Mógłbyś mi wyjaśnić bardziej łopatologicznie Twoją myśl?

    I byłbym wdzięczny za umieszczenie Twojego kodu :)
  • #4 11941325
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Normalny terminal odbiera, wysyła i wyświetla znaki jako znaki - litery i cyfry. Terminal nie wie, co to jest liczba, ani unsigned int. Jeśli chcesz wyświetlić na terminalu liczbę 123, to wysyłasz kolejno cyfry '1', '2' i '3''. Moduł UART w mikrokontrolerze też przesyła znaki - najczęściej w postaci słów 8-bitowych.

    Kolego, zacznij od podstaw podstaw - co to jest terminal, co to jest UART i RS232. Potem dopiero bierz się za DMA.
  • #5 11941826
    m.ki
    Poziom 15  
    Posty: 117
    Pomógł: 13
    wojlej napisał:
    nie mam pojęcia jak wpisać zmienną Dane do bufora TxBuf.

    Normalnie to się robi tak:

    Jeśli wysyłasz coś z pamięci procesora przez DMA gdziekolwiek (USART, SPI, I2C itd) to musisz wpierw przygotować dane do wysyłki - wszystkie! A dopiero później przygotowaną paczkę wysyłać.

    Czyli Twój TxBuf powinien być tablicą, nie pojedynczą zmienną. Wypełniasz go kolejnymi liczbami, a później odpalasz transfer DMA podając jako źródło adres TxBuf, jako rozmiar danych - rozmiar bufora TxBuf (ile ma elementów) i określasz, że adres źródła ma być inkrementowany.

    Pozdrowienia,
    m.ki
  • #6 11943417
    wojlej
    Poziom 17  
    Posty: 366
    Ocena: 101
    Wreszcie jakaś pomoc konkretna.

    Więc tak, uaktualniłem kod,
    zmienna TxBuf jako tablica o rozmiarze 256:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    W pętli for zapełniam tablicę od 0 do 255 następnie włączam transmisję DMA:
    Kod: text
    Zaloguj się, aby zobaczyć kod

    Zmieniłem jeszcze tryb DMA na Cykliczny:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    I rozmiar bufora na 256:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Uzyskuje tylko coś dziwnego, zamiast wartości od 0 do 255 i dalej od 0 do 255 otrzymuje losowe wartości:

    [STM32][USART][DMA] - Nadawanie przez USART z wykorzystaniem DMA STM32DISCOVERY

    Czy wynika to z faktu, że USART nie zdąży wysłać tablicy a już jest zapełniana ponownie? Jeśli tak to jak temu zaradzić?
  • #7 11943636
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Włączasz transmisję, a za chwilę ją wyłączasz i inicjujesz jeszcze raz, i tak w kółko - inicjujesz transmisję nie czekając na jej zakończenie. Zresztą transmisja nigdy się sama nie zakończy, bo włączyłeś tryb "w kółko". Zastanów się, co chcesz zrobić, a potem dopiero pisz.
  • #8 11943705
    wojlej
    Poziom 17  
    Posty: 366
    Ocena: 101
    Nawet w trybie Normal otrzymuje 256 wartości całkowicie losowych. W takim razie BlueDraco mógłbyś może powiedzieć co poprawić, jak zaczekać aż transmisja się zakończy? Bo na razie tylko dzięki m.ki ruszyłem do przodu. Bardzo się cieszę że jesteś ogarnięty w dziedzinie ARMów, ale forum jest po to żeby rozwiązywać takie problemy i dzielić się wiedzą. Więc bardzo proszę powiedzieć w jaki sposób temu zaradzić.
  • #9 11943714
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    wojlej napisał:
    Więc bardzo proszę powiedzieć w jaki sposób temu zaradzić.

    Przeczytać manuala - przecież to WSZYSTKO jest tam opisane, a nie ukryte i zaszyfrowane... A potem jeszcze przeczytać manuala od tej pseudo-biblioteki.

    4\/3!!
  • #10 11943778
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Jak zaczekać? Zobaczyć w manualu, co robi DMA, kiedy kończy transmisję - jak to sygnalizuje i jak można to sprawdzić, że zakończył.
  • REKLAMA
  • #11 11944311
    m.ki
    Poziom 15  
    Posty: 117
    Pomógł: 13
    wojlej napisał:
    Czy wynika to z faktu, że USART nie zdąży wysłać tablicy a już jest zapełniana ponownie? Jeśli tak to jak temu zaradzić?


    Tak, to jest efekt ponownego zapełniania tablicy. Masz tu kilka błędów. Zauważ, że liczby wysłanie na USART wcale nie są losowe - patrz na grupki po 4 bajty.

    Po primo, zmienne Dane i TxBuf[] są unsigned int, czterobajtowe. A wysyłasz za jednym zamachem 256 bajtów - trochę za mało, no nie?

    Po sekundo, tryb circular oznacza, że DMA będzie działać stale, czyli po wysłaniu 256 słów zaraz zacznie wysyłać kolejne. A program, asynchronicznie do DMA, wypełnia tablicę coraz to większymi liczbami. Czy o to Ci chodzi?
    Jeśli nie o to Ci chodzi, to powinieneś wybrać tryb DMA_Mode_Normal - wtedy po wysłaniu 256 bajtów transfer DMA się zakończy.

    Po minuto, zanim wyślesz coś na DMA, musisz poczekać, aż poprzedni transfer się skończy (oczywiście za pierwszym razem nie musisz czekać, nie ma poprzedniego). Mam dziś dobry dzień - czekanie wygląda (w tej okropnej bibliotece) tak:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Jeśli nie zależy Ci na szybkości, możesz po prostu po zainicjowaniu DMA poczekać, aż się skończy - tak jest prościej. Ale efektywniej jest nie czekać od razu, robić swoje, a czekać gdy DMA będzie znów potrzebne, bo być może wtedy już nie trzeba będzie czekać.

    I jeszcze jedno - przed każdym zainicjowaniem transmisji DMA musisz ustawić na nowo adres źródła danych i licznik!

    Pozdrowienia,
    m.ki
  • REKLAMA
  • #12 11945835
    wojlej
    Poziom 17  
    Posty: 366
    Ocena: 101
    Dzięki Ci za pomoc ale nadal nic.

    Zmieniłem na tryb Normalny. Chcę odebrać w terminalu 256 bajtów od 0 do 255. Zamiast tego otrzymuje 256 bajtów o takich wartościach:
    [STM32][USART][DMA] - Nadawanie przez USART z wykorzystaniem DMA STM32DISCOVERY

    Deklaracje zmiennych TxBuf i Dane zmieniłem na jednobajtowe czyli unsigned char. Nie rozumiem dlaczego tak jest, przecież po wejściu do pętli nieskończonej zapełniam w pętli for indeksy tablicy od 0 do 255 i dopiero potem inicjuje transfer. Tylko raz bo to tryb normalny, więc dlaczego otrzymuje coś takiego?

    Może coś nie tak w konfiguracji DMA?
    Poniżej kod:

    Program główny:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Kod konfiguracyjny:
    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #13 11946006
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Co to jest USART1_DR_BASE? Czy to samo, co &USART1->TDR ?

    DMA przed każdym użyciem wymaga, przynajmniej częściowego, powtórnego zaprogramowania - napewno długość bloku, być może też adresy. Ty tego nie robisz.
  • #14 11946354
    wojlej
    Poziom 17  
    Posty: 366
    Ocena: 101
    Cytat:
    DMA przed każdym użyciem wymaga, przynajmniej częściowego, powtórnego zaprogramowania - napewno długość bloku, być może też adresy. Ty tego nie robisz.


    Rozumiem, że po zakończeniu transmisji DMA należy ją zaprogramować jeszcze raz, ale akurat w tym przykładzie chce dane wysyłać tylko raz, inicjuje ją w Board_Config(); Więc dla pierwszego razu jest zaprogramowana czy tak?

    Cytat:
    Co to jest USART1_DR_BASE? Czy to samo, co &USART1->TDR ?


    DR to Data register w którym są przechowywane dane, według manuala składa się z TDR i RDR.

    Manual:
    Cytat:
    Bits 8:0 DR[8:0]: Data value
    Contains the Received or Transmitted data character, depending on whether it is read from
    or written to.
    The Data register performs a double function (read and write) since it is composed of two
    registers, one for transmission (TDR) and one for reception (RDR)
    The TDR register provides the parallel interface between the internal bus and the output
    shift register
  • #15 11946807
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Dla pierwszego razu jest zaprogramowana, dla następnych już nie, a Ty próbujesz to DMA uruchamiać w pętli, co uda się tylko jeden raz.
    Przepraszam, cały czas nie mogę przestawić myślenia na STM32F1xx, z którym nie mam (na szczęście) do czynienia. Strasznie dziwne to układy i niepodobne nawet do nowszych serii STM32.

    Tyle dywagacji, teraz pora na pokazanie błędu, którego przyczyną jest, uwaga: niepotrzebna i błędna deklaracja zmiennej TxBuf w procedurze inicjowania DMA, która zakrywa deklarację prawdziwego bufora- wywal ją i wszystko będzie ok. A na przyszłość czytaj ostrzeżenie kompilatora, bo pewnie strasznie się o to awanturuje.
  • #16 11946833
    wojlej
    Poziom 17  
    Posty: 366
    Ocena: 101
    Cytat:
    Dla pierwszego razu jest zaprogramowana, dla następnych już nie, a Ty próbujesz to DMA uruchamiać w pętli, co uda się tylko jeden raz.


    Tak wiem, W tej chwili tylko o to mi chodzi, kiedy uda mi się tak zrobię to w trybie circular.

    Usuwam:
    Kod: text
    Zaloguj się, aby zobaczyć kod

    w Board.c

    i kompilator wywala błąd:
    Board.c(135): error:  #20: identifier "TxBuf" is undefined


    dodałem tą deklaracje tylko dlatego że pojawiał się ten błąd. Board_Config mam w pliku Board.c a program główny w main. Dlatego kompilator nie wie kompilując gdzie jest TxBuf. Jak to rozwiązać?
  • #17 11946874
    m.ki
    Poziom 15  
    Posty: 117
    Pomógł: 13
    wojlej napisał:
    Rozumiem, że po zakończeniu transmisji DMA należy ją zaprogramować jeszcze raz, ale akurat w tym przykładzie chce dane wysyłać tylko raz, inicjuje ją w Board_Config();

    Ale przecież wołasz ten transfer w pętli głównej, czyli go w nieskończoność powtarzasz! Na dodatek nie ustawiasz na nowo licznika i adresu źródła, więc adres jest nonstop inkrementowany i wyłazi poza obszar Twoich zmiennych - pewnie włazi na stos i stąd takie śmieszne wartości.

    Wyciągnij zapełnianie TxBuf i operacje na DMA przed pętlę while (1) {}, jak coś chcesz zrobić raz, to ta pętla ma być pusta i na końcu main().

    Mam też wątpliwości co do adresów w incjowaniu DMA.
    Elementy DMA_PeripheralBaseAddr i DMA_MemoryBaseAddr są typu uint32_t, a nie wskaźnikowego (a TxBuf, jako nazwa tablicy, jest przecież wskaźnikiem). Nie masz ostrzeżeń przy kompilacji tego?
    Najlepiej zrobić jawny cast (uint32_t)TxBuf. Nie wiem, jak z USART1_DR_Base, ale skoro w ogóle cokolwiek idzie na USART, to ten adres raczej jest dobry.

    Pozdrowienia,
    m.ki

    Dodano po 2 [minuty]:

    BlueDraco napisał:
    Tyle dywagacji, teraz pora na pokazanie błędu, którego przyczyną jest, uwaga: niepotrzebna i błędna deklaracja zmiennej TxBuf w procedurze inicjowania DMA, która zakrywa deklarację prawdziwego bufora- wywal ją i wszystko będzie ok.

    Toć tam jest extern...

    Pozdrowienia,
    m.ki
  • #18 11946907
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Jeśli to jest w jednym pliku, zadbaj o kolejność deklaracji. Jeśli w dwóch (średni pomysł w tym przypadku, bo nie jest to logiczna dekompozycja), to w tym, w którym odwołujesz się do danej z innego modułu na poziomie zewnętrznym umieść deklarację skopiowaną z z definicji, z dodanym z przodu słowem kluczowym extern.

    char TxBuf to coś zupełnie innego niż char TxBuf[256] !!!

    Myślę, że w Twoim zastosowaniu nie chcesz mieć trybu "w kółko", bo nie ma on tutaj sensu. To ma zastosowanie przy odczycie wielu kanałów ADC i chyba tylko w takim przypadku. Danych przez UART nie transmituje się bez przerwy, bo np. odbiornik nie będzie w stanie dobrze zsynchronizować transmisji, pomijając już sens pchania na okrągło tego samego bufora milion razy do odbiorcy (bo przecież modyfikacja podczas transmisji skutkowałaby błędami w danych).
  • #19 11946937
    m.ki
    Poziom 15  
    Posty: 117
    Pomógł: 13
    wojlej napisał:
    kiedy uda mi się tak zrobię to w trybie circular.


    Czy jesteś pewien, że o to Ci chodzi? DMA działa asynchronicznie do programu i w trybie cicrular nonstop wypycha w UART zawartość tablicy TxBuf. Program zapełnia tę tablicę w swoim rytmie, a DMA zupełnie niezależnie wysyła jej zawartość. W znakomitej większości wypadków wysłane będzie część nowej zawartości TxBuf i część starej.
    Oczywiście są zastosowania, w których to się sprawdza, ale to raczej rzadkie przypadki.

    Pozdrowienia,
    m.ki

    Dodano po 2 [minuty]:

    m.ki napisał:
    BlueDraco napisał:
    Tyle dywagacji, teraz pora na pokazanie błędu, którego przyczyną jest, uwaga: niepotrzebna i błędna deklaracja zmiennej TxBuf w procedurze inicjowania DMA, która zakrywa deklarację prawdziwego bufora- wywal ją i wszystko będzie ok.

    Toć tam jest extern...

    No faktycznie, nie zauważyłem braku nawiasów...
    Powinno być:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Pozdrowienia,
    m.ki
  • Pomocny post
    #20 11946970
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Na wypadek, gdybyś nie zauważył: przy takich deklaracjach i treści procedury konfiguracji DMA, jakie masz obecnie, do rejestru adresu pamięci DMA wpisujesz wartość bajtową odczytaną z pamięci ze zmiennej TxBuf, rozszerzoną zerami do 32 bitów, czyli wysyłasz przez UART zawartość tablicy wektorów wyjątków.
  • #21 11946997
    wojlej
    Poziom 17  
    Posty: 366
    Ocena: 101
    A więc działa.

    Pomogło dopisanie do deklaracji zewnętrznej zmiennej [256]. Teraz otrzymuje 256 bajtów o wartościach od 0 do 255. Umieszczenie pętli for i włączenia DMA przed while nie zmieniło nic, ale faktycznie, funkcja była wywoływana non stop więc umieściłem to zgodnie z radami m.ki.

    Dzięki.

    Na razie sprawdzałem tylko DMA.

    Docelowo chcę zrobić co innego:

    Muszę próbkować 4 kanały ADC1 w przemiataniu i wysyłać wartości po USART do komputera. Tylko, że kanał 4 DMA zajmuje się USART1 TX a kanał 1 ADC więc jeszcze nie mam pomysłu jak to połączyć.

    Niżej umieszczam screen z terminala:
    [STM32][USART][DMA] - Nadawanie przez USART z wykorzystaniem DMA STM32DISCOVERY

    I kod dla potomnych:
    Program główny:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Funkcja Board:
    Kod: text
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    #22 11947096
    m.ki
    Poziom 15  
    Posty: 117
    Pomógł: 13
    wojlej napisał:
    A więc działa.

    Gratulacje :)

    wojlej napisał:

    Docelowo chcę zrobić co innego:
    Muszę próbkować 4 kanały ADC1 w przemiataniu i wysyłać wartości po USART do komputera. Tylko, że kanał 4 DMA zajmuje się USART1 TX a kanał 1 ADC więc jeszcze nie mam pomysłu jak to połączyć.

    Kolizja DMA nie występuje, bo są różne kanały. Po prostu jeden poczeka na drugi.
    Jak najbardziej sensowne jest odczytywanie ADC w trybie circular, natomiast nie ma sensu nonstop pchać danych z czujników przez USART. Po co? Są tak szybkozmienne? Ustaw sobie przerwanie w timerze i odpalaj transfer USART przez DMA co jakiś czas - sam oceń jak często, co 10ms, częściej, rzadziej...

    Warto też pamiętać, że USART jest średnio odporny na zakłócenia, możesz po drodze zgubić jeden bajt i się dane rozsynchronizują - powinieneś opracować jakieś ramki danych, żeby w razie utraty jednego czy kilku bajtów komputer mógł się z powrotem zsynchronizować. Najprościej - jeśli dane nie przekraczają wartości 127, wysyłaj jeden początkowy bajt z ustawionym najstarszym bitem.

    Pozdrowienia,
    m.ki
  • #23 11947156
    wojlej
    Poziom 17  
    Posty: 366
    Ocena: 101
    Przetworniki w STM są 12-bitowe, więc maksymalnie zmienna będzie przyjmować wartość 4095, jako, że przez USART jednorazowo nie prześle tego to rozdzielę to na dwa bajty jeden maksymalnie 40, drugi maksymalnie 95, w programie na PC sobie już to jakoś połączę. Tylko, że muszę powysyłać dane z 4 kanałów więc muszę to jakoś ładnie uporządkować.

    Więc dobrym rozwiązaniem będzie przesyłanie próbek z ADC w trybie Circular do jakiejś tablicy a następnie w przerwaniu od timera do USART?

    Pozostaje rozwiązanie jeszcze tablicy, np tablica mająca 4 kolumny, każda kolumna to jeden kanał i nieparzysty wiersz to pierwszy bajt a parzysty drugi? itd?
  • #24 11947197
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Coś się tak uparł na pomiar w kółko? Jak często chcesz transmitować wartości próbek do PC? Najpierw to określ, a potem zaprojektuj strukturę oprogramowania. Nie ma sensu mierzyć 10000 razy na sekundę i transmitować potem wyniki co setnego pomiaru.

    Mam wrażenie, że podchodzisz do tego projektu "od tyłu". Zamiast zacząć od funkcjonalności, zaczynasz od tego, jakie dziwne i ciekawe możliwości mają peryferiale mikrokontrolera i próbujesz je wykorzystać nie patrząc na cel tej zabawy.
  • #25 11947243
    wojlej
    Poziom 17  
    Posty: 366
    Ocena: 101
    Maksymalna składowa harmoniczna tego sygnału to około 2 kHz, Minimalnie muszę próbkować każdy kanał z częstotliwością 4 kHz ale chciałbym uzyskać koło 10 kHz. 4 kanały to 40 kHz. W takim razie czas pomiędzy próbkami to 25 µs. Czyli dość szybko, dlatego wydaje mi się, że tak jak mówi m.ki próbkować ADC w trybie Circular, zbierać dane do tablicy i wysyłać po USART. Kolejna sprawa to czy przepustowość USART wystarczy.
  • #26 11947258
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    80 KB/s ... trochę dużo na UART. Może USB?

    ADC wyzwalaj timerem, zrób dwa bufory na odczyty i pakuj do niech dane naprzemiennie, odpuść tryb circular.
  • #27 11947352
    wojlej
    Poziom 17  
    Posty: 366
    Ocena: 101
    Korzystam z przejściówki USART ->USB na FT232, podobno do 3MB/s. Docelowo chcę to zrobić na STM32F103, najwyżej zjadę z częstotliwości próbkowania do 4 kHz . Jak nie da rady to spróbuje wykorzystać interfejs USB w STMie, chociaż jeszcze tego nie robiłem.

    Zrobiłem teraz to samo co poprzednio ale tak aby transmisja się powtarzała, ustawiam zgodnie z waszymi radami parametry transmisji po poprzedniej i wszystko działa

    Funkcja główna:
    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #29 11948249
    m.ki
    Poziom 15  
    Posty: 117
    Pomógł: 13
    BlueDraco napisał:
    ADC wyzwalaj timerem, zrób dwa bufory na odczyty i pakuj do niech dane naprzemiennie, odpuść tryb circular.

    Otóż to, cicrular ma sens na przykład dla sygnałów wolnozmiennych, gdy jest obojętne, kiedy zmierzysz. Wtedy po prostu na początku programu odpalasz DMA z ADC i nie musisz się niczym przejmować, zawsze w pamięci będzie aktualny pomiar.
    Ale jeśli potrzebujesz synchronizować pomiary, to tylko tak, jak BlueDraco pisze.

    Pozdrowienia,
    m.ki
  • #30 11948263
    wojlej
    Poziom 17  
    Posty: 366
    Ocena: 101
    No tak, trochę zamieszałem.

    4095 zapisze się na 12-bitach, więc mogę podzielić na 2 po 6 bitów czyli 63(dec). Zostaną mi dwa bity i mogę wykorzystać je do oznaczenia numeru kanału lub kodowania.

    a Ty Freddie Chopin jakie byś wybrał rozwiązanie, żeby było optymalnie? Odczytywałbyś ADC w trybie circular czy wyzwalał Timerem?

Podsumowanie tematu

✨ W dyskusji poruszono problem wysyłania inkrementowanej zmiennej przez USART z wykorzystaniem DMA na mikrokontrolerach STM32. Użytkownik napotkał trudności w konfiguracji DMA oraz w poprawnym przesyłaniu danych do terminala. Wskazówki obejmowały konieczność konwersji danych do formatu ASCII przed wysłaniem, poprawne ustawienie buforów oraz synchronizację transferów. Użytkownicy podkreślili znaczenie odpowiedniej konfiguracji rejestrów ADC i DMA, a także wyzwalania pomiarów przez timer. Wskazano na różnice między trybami SCAN i DISCONTINUOUS w ADC oraz na konieczność obsługi przerwań. Ostatecznie, po wprowadzeniu poprawek, użytkownik uzyskał poprawne wyniki pomiarów.
Wygenerowane przez model językowy.
REKLAMA