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

[Mega32][C] ADC - Próbkowanie sygnału

simoon87 21 Sty 2012 20:24 2693 10
REKLAMA
  • #1 10429473
    simoon87
    Poziom 10  
    Witam.
    Od razy przejdę do sedna sprawy. Chciałem napisach program próbkujący sygnał z możliwością wyboru trzech częstotliwości próbkowania (250Hz, 500Hz, 1kHz). Zacząłem pisanie od 250Hz, skonfigurowałem Timer 0 w tryb CTC, przetwornik ADC w tryb konwersji na żądanie. W przerwaniu od Timera 0 odczytuje wartość rejestru ADC i startuje kolejną konwersje. Wartości próbek wysyłam do kompa przez UART ale terminal odbiera cały czas literkę "H". Przejrzałem kilka tematów na forum ale nie znalazłem żadnych przydatnych dla mnie wskazówek. Może ktoś coś podobnego robił i podpowie? Nie koniecznie kodem, może po prostu źle to sobie wymyśliłem

    Oto mój kod:

    PLIK: main.c
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    PLIK adc.c
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #2 10429607
    tmf
    VIP Zasłużony dla elektroda
    utoa zwraca wskaźnik, a najwyraźniej twoja funkcja uart_putc oczekuje wartości typu char. W efekcie adres wskaźnika jest konwertowany na char i wyzyłany jako jeden bajt - a że w gotowym progrmaie adres tego wskaźnika jest stały, to otrzymujesz stałą wartość. Musisz zrobić pętlę, która odczyta kolejne znaki z tablicy buf i je wyśle przy pomocy uart_putc.
  • REKLAMA
  • #3 10430568
    simoon87
    Poziom 10  
    No dobra to jedna rzecz już wyjaśniona, napisałem taka funkcje:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    teraz moja pętla główna w pliku main.c wygląda tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Częściowo się poprawiło tzn przy zmianie położenia potencjometru w układzie testowym, wartości się zmieniają ale są jakieś dziwne. Przy 5V na wejściu ADC wartość wyświetlona w terminalu to 393;/ Zauważyłem też ze w terminalu odbierane są wartości typu: "1bc". Co może być przyczyną? Źle napisana wyżej funkcja?
  • REKLAMA
  • Pomocny post
    #4 10430728
    gaskoin
    Poziom 38  
    za duzo kombinujesz :) nie możesz wysłać 'normalnych' liczb na początek tylko od razu skonwertowane na ascii?

    Problemem pewnie jest siedemnastkowy zapis liczb :)

    simoon87 napisał:
    Przy 5V na wejściu ADC wartość wyświetlona w terminalu to 393;


    3 * 17*17 + 9 * 17 + 3 = 1023 - Bardzo ładny wynik jak na 5V, wszystko więc działa poprawnie :)
  • #5 10431096
    sulfur
    Poziom 24  
    Gaskoin nie zgadzam się. Zauważ, że autor tematu wysyła zawsze 3 znaki - wartość ADC - i to najprawdopodobniej górne 8 bitów - czyli tak naprawdę górne użyteczne 2 bity - czyli wartość 3 właśnie. Później wysyła powrót karetki i znak nowej lini - stąd to 9 i 3. Przy zamianie z wartości szestnastkowej na dziesiętną mnoży się razy 16, a nie 17.
    Jeśli funkcja ADC_check ma liczyć średnią to na pewno tego nie robi.
  • Pomocny post
    #6 10431236
    tmf
    VIP Zasłużony dla elektroda
    sulfur napisał:
    Gaskoin nie zgadzam się. Zauważ, że autor tematu wysyła zawsze 3 znaki - wartość ADC - i to najprawdopodobniej górne 8 bitów - czyli tak naprawdę górne użyteczne 2 bity - czyli wartość 3 właśnie. Później wysyła powrót karetki i znak nowej lini - stąd to 9 i 3. Przy zamianie z wartości szestnastkowej na dziesiętną mnoży się razy 16, a nie 17.
    Jeśli funkcja ADC_check ma liczyć średnią to na pewno tego nie robi.


    Kolega gaskoin ma 100% rację, zobacz prototyp rzeczonej funkcji:
    char * utoa (unsigned int __val, char *__s, int __radix)
    Jak widzisz ostatni parametr to radix, czyli podstawa systemu do którego będzie konwersja, w tym przypadku jest to system 17-kowy, dla którego przeliczenie kolegi gaskoina jest prawidłowe.
  • REKLAMA
  • #7 10437283
    simoon87
    Poziom 10  
    Dzięki za pomoc zmieniłem radix i teraz działa nie wiem czemu wstawiłem tam 17 chyba jakieś zaćmienie umysłu;)

    Ale jak to zwykle bywa nie może być za różowo. Zorientowałem się ze wartości ADC przesyłane do komputera są tak jakby "przesunięte w czasie" tzn. jeśli szybko dokonam zmiany potencjometrem i wrócę do pozycji początkowej to dopiero po chwili zobaczę rezultat tych zmian na ekranie komputera. Czym to może być spowodowane? UART nie wyrabia czy założyłem zbyt małą częstotliwość próbkowania?

    PLIK main.c

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #8 10437421
    gaskoin
    Poziom 38  
    napisy nie nadążają z wyrysowaniem się w okienku. Przecież posyłasz 250 000 znaków w ciągu sekundy
  • #9 10437720
    simoon87
    Poziom 10  
    Przecież UART wysyła wartość próbki zmierzonej przez ADC jeden raz po ustawieniu zmiennej send_uart w przerwaniu od Timer'a 0. Czyli jeśli przerwanie występuje co 1ms i za każdym razem wysyłane są 4 znaki (przy napięciu 5V tj. 1,0,2,3) to daje nam 4000 znaków w ciągu sekundy, czy jestem w błędzie?
  • #10 10438762
    gaskoin
    Poziom 38  
    Nie jesteś, wybacz, nie zajrzałem do kodu, ale na wyświetlanie to i tak dużo. Spróbuj próbkować np 5 razy na sekundę i zobaczysz, że jest ok.
  • #11 10463167
    lukashb
    Poziom 39  
    Witam. Poszukaj mojego tematu o próbkowaniu sygnału z ADC. Jakieś półtora miesiąca wstecz. Miałem z początku podobny problem, że UART wysyłał mi złe dane. Problemem było to, że się nie wyrabiało wszystko. Musiałem zastosować tablicę próbek, odczytywać, zapełnić, zatrzymać timer, wystawić flagę, i wtedy wysłać po UARCIE całość, wyzerować flagę, ruszyć timer i od nowa. Pozdrawiam
REKLAMA