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

[ATMEGA8A][C][Atmel Studio] - Odczyt z ADC i komunikacja po USART

_Antos_ 16 Lip 2014 21:01 1863 10
  • #1 13802223
    _Antos_
    Poziom 10  
    Witam

    Mój problem polega na tym, że muszę odczytywać z ADC, a następnie wysyłać dość duże paczki danych.
    Wymyśliłem tak jak poniżej (wiem, że nie najlepiej), że wezmę puszczę przetwornik w FRM, tak żeby generował przerwanie po każdym pomiarze i w tym przerwaniu wysyłam to prosto po USART.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Problem polega na tum, że po włączeniu układu dostaję na konsoli jakieś 1000 wyników zamiast zakładanych 3000 (pomiar jest co drugi takt).
    Chciałbym prosić o podpowiedzenie jak to lepiej rozwiązać.
    Do tej pory próbowałem też przepisywać wyniki do tablicy, a wysyłać je po zakończeniu pomiarów, ale tutaj jest problem z pamięcią - jest jej zbyt mało żeby zmieścić aż tyle wyników.
  • #2 13802294
    el2010tmp
    Poziom 25  
    Albo Free run albo ręczne uruchamianie w pętli lub przerwaniu.
  • #3 13802329
    _Antos_
    Poziom 10  
    Dzięki za odpowiedź. Mógłbyś rozwinąć myśl? Free run używam obecnie i się nie sprawdza, a z pojedynczym pomiarem szczerze powiedziawszy nie pomyślałem. Przetestuje. Chodziło Ci o to, żeby uruchomić pomiar, a następnie w przerwaniu po pomiarze odczytać zawartość, wyslać i jeszcze raz uruchomić?
  • Pomocny post
    #4 13802450
    el2010tmp
    Poziom 25  
    To zależy co chcesz mierzyć [z jaką częstotliwością].
    Jeśli są to wolne przebiegi wówczas ustawiasz przerwanie timara a w nim:
    - uruchomienie pomiaru ADC [pojedyńczy pomiar]
    - wysłanie przez USART
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    i tyle.

    Jeśli przebiegi są za szybkie na USART [9600/8=1200 próbek 8bit na sekundę] wówczas trzeba stosować bufor w ram. Lub przyspieszyć USART.

    Free run wystarczy uruchomić tylko raz ponieważ zakończenie konwersji automatycznie uruchamia kolejną.

    Ps.
    Przed wysłaniem danych przez USART wypadało by też sprawdzić czy poprzedni bajt został już wysłany:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    chyba że masz pewność co do tego że USART wyrobi z prędkością.
  • #5 13802951
    _Antos_
    Poziom 10  
    Usart chodzi obecnie z prędkością 19200. To jest najwyższa jaką udało mi się wyciągnąć tak żeby to co dociera do konsoli miało jeszcze sens.
    Zarówno we free run mode jak i w single moge, gdzie uruchamiam ponowny pomiar w przerwaniu dostaję na konsolę jakieś 1000 wyników (chciałbym około 3000), więc wychodzi na to, że coś nie wyrabia.
    Próbkę chciałbym pobierać co 100us, czyli częstotliwość w okolicach 10KHz, ewentualnie jak uda się wyrobić to chciałbym około 20KHz, tylko, że najpierw wolałem spróbować z niższymi prędkościami.
  • #6 13803194
    BlueDraco
    Specjalista - Mikrokontrolery
    Problem leży najpierw w założeniach. Chcesz przesyłać wynik co 100 us, a transmisja jednego bajtu przy 19200 zajmuje ok. 500 us.

    Zacznij od przeliczenia wszystkich parametrów. Potem dobierz częstotliwość taktowania procesora. Zaprogramuj timer na częstotliwość próbkowania. W przerwaniu timera czytaj wynik poprzedniej konwersji,wyzwól kolejną konwersję i przygotuj wynik do wysłania. Wysyłaj bajty w przerwaniu nadajnika UART. Nie używaj trybu free run ADC ani przerwań ADC.
  • #7 13805333
    _Antos_
    Poziom 10  
    Dzięki wielkie. Bardzo pomogłeś. Na takie rozwiązanie bym nie wpadł. Mógłbyś powiedzieć jeszcze jak policzyłeś to, że jeden bajt w przypadku 19200 zajmuje 500us?
    Oto obecny kod programu:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Co prawda trochę zweryfikowałem założenia i uważam, że to co powyżej to max co mogę wycisnąć sprzętowo z niego (chociaż pewnie się mylę). Jakbyś mógł rzucić okiem na powyższe i powiedzieć, dlaczego dostaję na konsolę jakby dwa razy to samo. Powinienem dostać około 1000 wyników, a dostaje ich 2000?
    Procesor jest taktowany kwarcem 16MHz
  • #8 13806078
    BlueDraco
    Specjalista - Mikrokontrolery
    Nie wiem, jaka to magia jest w podzieleniu jednej sekundy przez 1920 (czyli przez 19200 / 10, bo jeden bajt jest transmitowany w 10 "slotach" bitowych).

    Jeśli masz jakiś problem z wielokrotną transmisją, to winna temu jest pętla główna, która powinna być pusta (a dokładnie - powinna usypiać procesor). Wyzwalanie transmisji powinno następować w przerwaniu timera, z tym, że w ogóle dziwnie wygląda sam algorytm. Chcesz zebrać te próbki jeden raz, ciągle, czy po jakimś zdarzeniu? - Obecnie jest to ciut bez sensu. Jeśli zbierasz ciągle - to wysyłaj ciągle, a nie po zebraniu 999 próbek.
  • #9 13806306
    _Antos_
    Poziom 10  
    Dzięki za odpowiedź. Magia żadna, ale po prostu na to nie wpadłem wcześniej. Teraz sobie zapamiętam i już będę wiedział.

    Co do drugiej części to faktycznie masz rację. Po obejrzeniu dziś tego na spokojnie to faktycznie nie ma sensu.
    Wygląda to tak, że steruję linijką CCD. Ma ona ponad 5000 pixeli. Wypluwa je szeregowo na wyjście z częstotliwością jaką taktuje rejestr (10KHz, mogę podnieść częstotliwość lub obniżyć, żaden problem). Nie chcę zbierać wszystkich wyników, bo wiem, że zebranie 5000 przy obecnym procesorze jest niemożliwe. Ideałem byłoby zebranie co drugiego pixela, ale mogę się też zadowolić co 5 pixelem.
    Próbki chce zbierać po wyzwoleniu pomiaru. Wyzwalaczem pomiaru będzie przycisk w programie komputerowym. Aplikacja jeszcze co prawda nie powstała i dlatego trenuje po prostu na konsoli. Jest mi to obojętne czy będę wysyłał wynik po każdym pomiarze, czy najpierw zbiorę je do tablicy i potem wyślę. Zbieranie do tablicy ma ten minus, że nie zmieszczę więcej niż 1000 pomiarów jednocześnie. Wysyłanie po każdym pomiarze ma ten minus, że skoro chciałbym zbierać co 5 próbkę, to przetwornik musiałby dokonywać pomiaru co 500us, a następnie to wysyłać, gdzie samo wysłanie zajmuje 500us, więc mógłbym nie zdążyć wysyłać danego pomiaru.
  • #10 13806910
    BlueDraco
    Specjalista - Mikrokontrolery
    I pomyśleć, że nie miałbyś zadnego z tych problemów, gdybyś użył dowolnej płytki STM32FDISCOVERY za 40 zł,a jeszcze mógłbyś wygodnie debugować program...

    Tak to jest, kiedy projekt rozpoczyna się od mikrokontrolera, a nie od wymagań i założeń, z których jasno wynika, że ATmega do tego zupełnie się nie nadaje.
  • #11 13807745
    _Antos_
    Poziom 10  
    Niestety. Gdybym wtedy wiedział to co wiem teraz to bym tak nie zrobił i faktycznie bym zaczynał od jakiś lepszych płytek i mikrokontrolerów.
    Jednak skoro już zacząłem. Powstała płytka do tego itp, to chciałbym to skończyć na jako-takim poziomie.
    Niestety każdy jakoś zaczynał. Następnym razem będę mądrzejszy i najpierw dokładnie rozeznam co i jak. Wstępnie mi się wydawało, że to wystarczy, no a potem im głębiej w las...
REKLAMA