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

STM32F100 Keil - DMA nie zapełnia bufora ADC po pierwszym przerwaniu

wojlej 09 Lip 2014 13:30 2223 9
REKLAMA
  • #1 13780863
    wojlej
    Poziom 17  
    Posty: 366
    Ocena: 101
    Witam,

    Mam problem z którym już chwilę się borykam. Do STMa mam podłączony czujnik BAR180 z którym już się komunikuje po I2C. Dodatkowo skonfigurowałem ADC w trybie pomiaru jednokrotnego wyzwalanego przez Timer1 co 500µs. Dane z ADC chcę przerzucić do bufora przez DMA. Utworzyłem bufor jako tablicę o 256 pozycjach, ponieważ tyle chciałbym pomiarów. Wszystko ładnie tylko przerwanie od zakończenia transmisji DMA występuje tylko raz. Potem już nie. Chciałbym żeby DMA zapełnił mi bufor. Potem chciałbym go obrobić.

    Poniżej listingi:

    funkcja main:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Funkcja przerwania:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    W przerwaniu zeruje flagę i chciałbym żeby po kolejnych 500us w tablicy znalazły się kolejne pomiary.

    Chciałbym na bieżąco analizować dane z bufora, 256 pozycji to może trochę na wyrost. Może wystarczą 64. Chciałbym z nich liczyć wariancję aby wykryć piki sygnału na ADC. I też moje pytanie jak to najlepiej zrobić?

    Proszę o odpowiedź
  • REKLAMA
  • #2 13780978
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Po zakończeniu transmisji DMA musisz programowo wyłączyć kanał DMA i zainicjować powtórnie transmisję, po czym włączyć kanał.
  • #3 13781298
    wojlej
    Poziom 17  
    Posty: 366
    Ocena: 101
    Dzięki za szybką odpowiedź. Pomogło, ale teraz mam kolejny problem, coś mam nie tak chyba z konfiguracją ADC bo niezależnie czy wejście PA5 (Kanał 5 ADC1) podłącze do 3,3V czy do GND dostaje w terminalu dziwne liczby.

    Po uzupełnieniu tablicy wysyłam przez UART pozycję 1, 10 i 30 tablicy. Otrzymuje w terminalu "30 30 30 30" (HEX) dla każdego kanału.

    Konfiguracja ADC:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    I funkcja przerwania:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    CO jest nie tak?

    Dodano po 30 [minuty]:

    OK, problem został rozwiązany, wystarczyło dodać do deklaracji bufora "buforAdc[1]", nie wiem czemu sama zmienna nie wystarczyła. Prosiłbym o ew. wyjaśnienie.

    Teraz ma pytanie dotyczące trochę obróbki tych danych. Moim głównym celem jest wykrycie w sygnale z A/C momentu pojawienia się pewnych nieregularnych impulsów oraz wykrycie momentu kiedy zanikają na tle sygnału. Myślałem o tym żeby zebrać powiedzmy po 64 próbki, liczyć wariancję z tego sygnału i zobaczyć czy była większa niż wariancja z poprzedniej tablicy. Jeśli byłaby większa to znaczy że był tam jakiś impuls o większej amplitudzie niż tło. A jeśli nie to znaczy że nie było. Pytanie do ekspertów, jak to najłatwiej zrobić?
  • REKLAMA
  • #4 13781800
    Konto nie istnieje
    Poziom 1  
  • #5 13782062
    wojlej
    Poziom 17  
    Posty: 366
    Ocena: 101
    Otóż tutaj:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Tak jak mówiłem chcę dane zbierać do dwóch buforów przesuniętych o połowę i liczyć ich wariancję i porównywać ze sobą. Mam coś takiego:

    Przerwanie:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    I pętla main:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Czy kod powyższy jest poprawny? Niestety nie mam możliwości podejrzenia zmiennych arytmetyczna i wariancja w czasie debugowania, nie wiem czemu. Czy obliczając wariancję buforów 64 elementowych które są przesunięte w stosunku do poprzedniego o 32 pozycję będę w stanie wychwycić gwałtowne wzrosty napięcia?
  • #6 13782125
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #7 13782265
    wojlej
    Poziom 17  
    Posty: 366
    Ocena: 101
    To może napiszę do czego mi to bardziej potrzebne. Mam mikrofon umieszczony przy tętnicy. Przebieg tętna wygląda mniej więcej tak:

    STM32F100 Keil - DMA nie zapełnia bufora ADC po pierwszym przerwaniu

    Oczywiście zaszumiony. Sygnał tętna pojawi się w pewnym niewiadomym momencie (piki ciśnienia skurczowego). Musze je wykryć. Dlatego myślałem żeby liczyć wariancję i porównywać z poprzednia tablicą. Tam gdzie piki są wariancja będzie bardzo duża. Tutaj jest najmniejszy problem.
    Natomiast w pewnym momencie tętno zacznie zanikać. (Piki będą miały mniejszą amplitudę). Trzeba znaleźć moment kiedy będą równo z szumem lub bardzo słabe. Te dwa momenty należy wychwycić, i z tym drugim jest większy problem. Tutaj wariancja by się też dobrze sprawdziła bo by się przestała zmieniać w dużym zakresie.

    Jeśli masz jakiś pomysł na to to chętnie wysłucham ;)
  • REKLAMA
  • #8 13782323
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    atom1477 napisał:
    Tylko że ja nigdzie tam nie widzę takiego fragmentu który by wymagał adresu. Może ktoś inny coś wychwyci.

    O tu:

    //Adres poczatkowy bloku do przeslania
    	DMA1_Channel1->CMAR = (uint32_t)buforAdc;


    4\/3!!
  • #9 13786836
    wojlej
    Poziom 17  
    Posty: 366
    Ocena: 101
    Napisałem program liczący wariancję z obu tablic, dodatkowo skonfigurowałem Timer2 do pracy w trubie PWM o częstotliwości 1Hz z wypełnieniem 10%. Podałem ten sygnał na mój przetwornik A/C. Przetwornik próbkuje sygnał i liczy wariancję z obu tablic. Po wykryciu że wariancja jest bardzo duża zmienia stan diody LED PC9. Druga dioda jest połączona do wyjścia Timera2. Diody migają w takt ze sobą, z tego wnioskuje, że wariancja poprawnie wykrywa zbocza sygnału. Prosiłbym was o sprawdzenie kodu, czy nie da się tego lepiej napisać, no i może wychwycicie błędy:

    Przerwanie zakończenia transferu DMA
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Pętla główna:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Konfiguracja Timer2 i 1
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Jak widać w kodzie program określa zbocze tylko za pomocą wariancji1 czyli wariancji z pierwszej tablicy. Jak wysyłałem obie wariancje po UART dostawałem coś takiego

    
    4
    4
    0
    0
    0
    0
    0
    0
    1881144
    985721
    2
    2
    1
    1
    1525577
    1525043
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    1
    1
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    1
    1
    0
    1
    1
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    1
    1
    0
    0
    0
    2
    1
    0
    0
    0
    0
    0
    0
    1165122
    1799081
    1
    1
    0
    2
    476682
    2001954
    0
    0
    0
    1
    1
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    2038625
    125401
    1
    1
    1
    2
    1906485
    889478
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    1
    1
    0
    0
    1705641
    1319712
    1
    2
    1
    1
    1239418
    1747335
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    


    Jak widać obie wariancję są bardzo duże bo zboczę było w takim miejscu że łapało się na obie tablicę. Jak zrobić żeby dioda zmieniała stan podczas gdy jedna lub druga, lub jedna i druga wariancja jest duża?
  • #10 13806093
    wojlej
    Poziom 17  
    Posty: 366
    Ocena: 101
    Witam,

    Mam problem z konfiguracją ADC. Chcę skanować 3 kanały, 5, 8 i 9. W momencie przerwania Timera chciałbym wysłać poprzez DMA wartości 3 kanałów ADC do bufora Adc, jest to tablica 3 elementowa. Coś jest nie tak bo jak wysyłam te wartości do terminala to otrzymuje losowe wartości, podczas gdy kanał 5 jest podłączony do masy, 8 do zasilania a 9 wisi w powietrzu.
    Poniżej konfiguracja:

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


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


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


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


    Proszę o pomoc w znalezieniu błędu

    Dodano po 18 [minuty]:

    Dziwnie się dzieje, jak mam ustawione breakpointa w miejscu gdzie powinienem wysyłać dane uartem to wychodzą dziwne wartości. A jak breakpointa usunę i zbiorę kilkadziesiąt danych to nie ma błędów. Wartości są ok. Może ktoś mi to wytłumaczyć?

Podsumowanie tematu

✨ Użytkownik ma problem z konfiguracją DMA do przesyłania danych z ADC w mikrokontrolerze STM32F100. Po pierwszym przerwaniu DMA nie zapełnia bufora ADC, co skutkuje brakiem dalszych przerwań. Użytkownik skonfigurował ADC do pomiaru jednokrotnego wyzwalanego przez Timer1, a dane mają być przesyłane do bufora o rozmiarze 256 pozycji. Odpowiedzi sugerują, aby po zakończeniu transmisji DMA programowo wyłączyć kanał DMA, zainicjować transmisję ponownie i włączyć kanał. Użytkownik napotkał również problemy z nieprawidłowymi wartościami ADC, co może być związane z konfiguracją kanałów. Dodatkowo, użytkownik planuje obliczać wariancję z dwóch buforów danych, aby wykrywać zmiany w sygnale.
Wygenerowane przez model językowy.
REKLAMA