Skocz do zawartości

ADC - konfiguracja i działanie


marex

Pomocna odpowiedź

z góry zaznaczam, że nie chcę być w żaden sposób niemiły, albo się z kogokolwiek naśmiewać.

pragnę jedynie zaprezentować, że znalezienie takiej informacji nie jest trudne

1. wejdź na stronę www.atmel.com

2. w wyszukiwarce (po lewej pod logiem Atmel) wyszukaj "atmega328p"

3. wejdź w pierwszy wynik wyszukiwania

4. pobierz dokumentację "Complete" (ta cięższa, tutaj 35MB), PPM na ikonie PDF, zapisz jako

5. otwórz dokumentację w Acrobat Reader

6. po lewej są zakładki, rozwiń 24. Analog-to-Digital Converter

7. kliknij w 24.9 Register Description

8. po pobieżnym przejrzeniu opisów rejestrów znajdujesz, że w ADCSRA jest bit ADATE: ADC Auto Trigger Enable, który włącza automatyczne wyzwalanie konwersji. W tym samym opisie jest informacja, że źródło wyzwalania określają bity ADTS w rejestrze ADCSRB.

9. scrollujesz do opisu rejestru ADCSRB, z tabelki odczytujesz, że free running mode to zera na na wszystkich trzech bitach ADTS, które są tam domyślnie

10. Voila! Już wiesz, że żeby włączyć tryb Free Runing wystarczy wstawić 1 na bit ADATE w rejestrze ADCSRA

Bit 5 – ADATE: ADC Auto Trigger Enable

When this bit is written to one, Auto Triggering of the ADC is enabled. The ADC will start a conversion on a positive

edge of the selected trigger signal. The trigger source is selected by setting the ADC Trigger Select bits, ADTS in

ADCSRB.

Pozdrawiam

Link do komentarza
Share on other sites

Może pytanie było zbyt ogólne, ale jak zrobić żeby tylko raz była konwersja (single conversion), nie ciągła jak we free ?

PS Jeszcze nie jestem tak dobry w j.angielskim.

Link do komentarza
Share on other sites

przetwornik działa normalnie w takim trybie,

po wpisaniu ADSC (Start Conversion) w rejestrze ADCSRA, przetwornik dokona konwersji i wynik zapisze w rejestrze ADC. Nic więcej, aby wykonać następny pomiar znów trzeba wpisać ADSC do ADCSRA

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

OK. Czyli ADATE jest podobna do ADFR.

Jak jest z poborem mocy przez ADC jeśli jest ustawiony ADEN ale przetwornik nie przetwarza ?

Jaki może być realny czas przetwarzania ADC ? (Podają, że 25 cykli)

Te 25 cykli to jak rozumiem z tych 50..200kHz ?

Link do komentarza
Share on other sites

tak, w przypadku gdy nie modyfikujesz rejestru ADCSRB, ADATE zachowuje się dokładnie jak ADFR.

tego nie wiem, w nocie takich danych nie ma, chyba że nie ma żadnej różnicy w takim razie na stronie 618 jest wykres poboru prądu przez ADC

przy 250kHz o ile dobrze pamiętam wyciągałem 80us, na atmedze16, ale ADC jest praktycznie to samo we wszystkich atmegach.

tak, 25 cykli odnosi się do cykli ADC, których częstotliwość wynosi 50...200kHz

  • Lubię! 1
Link do komentarza
Share on other sites

przerwania są najwygodniejsze, ale nie są konieczne

~800 cykli będziesz marnował, jeśli zrobisz bierne czekanie na pomiar

while (ADCSRA & (1<<ADSC))

jeśli jednak napiszesz

if ( !(ADCSRA & (1<<ADSC)) )
{
  pomiar = ADC;
  ADCSRA |= (1<<ADSC);
}

to nie zatrzymujesz programu na czas konwersji, a w sprzyjających warunkach ten sposób będzie mniej "cyklochłonny" niż przerwanie

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Wynik ADC odczytuję i uruchamiam w przerwaniu Timera co 10ms.

Więc raczej nie trzeba sprawdzać flagi ADSC 🙂

PS

@D_C obejrzałem filmik i ...

żałuję, że obejrzałem i straciłem czas.

Przecież to jedna wielka reklama bez sensownej informacji o programowaniu ADC.

Link do komentarza
Share on other sites

Jeżeli pomiary ADC nie są "od przypadku do przypadku" tylko okresowe - na co wskazuje użycie Timera - to może warto jednak skorzystać z bitów ADTS? Przecież właśnie do tego ta funkcja została wbudowana. Za ich pomocą ustawiasz ADC tak by jego start był wyzwalany sygnałem z żądanego timera a sam zasadzasz się na przerwanie od zakończenia konwersji ADC. W funkcji obsługi przerwania odczytujesz wynik i tyle. Jeżeli odpowiednio ustawisz timer to prawie wszystko robi się samo 🙂

Link do komentarza
Share on other sites

@marek1707 dobrze prawisz, ale...

Napisałeś, żeby koniec konwersji obsłużyć w przerwaniu ADC_vect. Tylko po co marnować czas obsługą stosu w ISR ?

Jak pisałem Timer ustawiony jest na 10ms, więc ADC dawno już skończy konwersję, a flaga ADSC też będzie nieistotna.

Jeśli chodzi o start ADC od Timera, to jeszcze się zastanawiam czy jednak nie startować go programowo. Samo ADCSRA |= (1<

Link do komentarza
Share on other sites

Jak to "marnować czas"? Przecież system przerwań właśnie po to został wymyślony, by tego czasu procesor nie marnował na bezmyślne odpytywanie czegoś co samo może się zgłosić i zażądać obsługi. Oczywiście idea przerwania wymaga zachowania kontekstu pracy procesora np. na stosie i późniejszego odtworzenia, ale jest to niewielka cena jaką płacimy za pożytki płynące z tego mechanizmu. Jeżeli już teraz szkoda Ci czasu na kilka/kilkanaście instrukcji prologu/epilogu funkcji ISR to znaczy, że Twój system został źle zaprojektowany i procesor po prostu jest za wolny do tego czym go obciążasz.

Dzisiejsze procesory są szybkie a w Twoim przypadku, gdy chcesz robić coś 100 razy/sekundę to nawet jeśli na naddatek związany z tym przerwaniem zmarnujesz w sumie z 100*20=2000 instrukcji to i tak jest to 0.025% mocy obliczeniowej typowego, 8MHz AVRa. Tego Ci szkoda? Ejże. Przecież w opisanej przeze mnie sytuacji sygnał przepełnienia lub komparacji z timera nie zgłasza swojego przerwania tylko sprzętowo wyzwala ADC a dopiero ten obsługujesz swoją funkcją ISR więc zamieniasz jedno przerwanie - w którym musisz odczytać wynik i wystartować timer, na inne - w którym tylko czytasz wynik. Co więcej, programowe startowanie ADC (nawet wykonywane w przerwaniu od timera) ma tę wadę, że wprowadza do systemu jitter czyli rozmycie fazy, bo opóźnienie od momentu zgłoszenia sygnału przez timer do chwili wykonania instrukcji startu ADC jest niedeterministyczne. W przypadku sprzętowego startu ADC takiego problemu nie ma. Jitter w oczywisty sposób przekłada się na dodatkowy szum nałożony na zbierane wyniki bo przecież reszta programu przetwarzająca liczby z ADC (choćby uśrednianie, filtrowanie lub jakieś inne bardziej wymyślne analizy) zakłada, że zostały zebrane w jednakowych odstępach czasu a tak nie było. Przemyśl to sobie.

Acha, i przy okazji opisz nam proszę jak można zrobić cykliczne wykonywanie pomiarów z wykorzystaniem timera bez przerwań (bo to - jak piszesz - marnowanie czasu) i bez podglądania stanu flag timera w pętli (bo to marnowanie jeszcze większe).

Link do komentarza
Share on other sites

@marek1707 co do Twojego długiego wywodu to zauważ, że nigdzie nie napisałem o krytycznych odstępach czasu dla odczytu ADC. Więc jitter nie ma dla mnie żadnego znaczenia. Jeśli start ADC przesunie się o kilka us to nieistotne.

Bulwersujesz się na "marnować czas" to zauważ, że czas odczytu ADC jest taki sam w przerwaniu ADC_vect jak i moim w Timerze. Ale w przerwaniu ADC_vect na który naciskasz dochodzi jeszcze niepotrzebne wysłanie rejestrów na stos i ich ponowny odczyt, więc występuje "marnowanie czasu".

Jeżeli już teraz szkoda Ci czasu na kilka/kilkanaście instrukcji prologu/epilogu funkcji ISR to znaczy, że Twój system został źle zaprojektowany i procesor po prostu jest za wolny do tego czym go obciążasz.(..)

Proszę, nie wypisuj takich ... To dzięki takiemu myśleniu mamy programy, które zamiast zajmować kilkadziesiąt MB na PC zajmują ponad GB. Podobnie z ciągłą niepotrzebną wymianą sprzętu na "nowszy" bo tak naprawdę programiści nie potrafili przemyśleć kodu.

Przemyśl to sobie.

Acha, i przy okazji opisz nam proszę jak można zrobić cykliczne wykonywanie pomiarów z wykorzystaniem timera bez przerwań (bo to - jak piszesz - marnowanie czasu) i bez podglądania stanu flag timera w pętli (bo to marnowanie jeszcze większe).
Odpowiem banalnie, bo to jest oczywiste.

Przerwanie Timera obsługiwane jest co 10ms, a konwersja ADC trwa 13 - 260 us. Już widzisz, czy jest konieczność sprawdzania ADSC ?

Link do komentarza
Share on other sites

Ale w przerwaniu ADC_vect na który naciskasz dochodzi jeszcze niepotrzebne wysłanie rejestrów na stos i ich ponowny odczyt, więc występuje "marnowanie czasu".

przerwanie od ADC i przerwanie od timera będzie wymagało takiej samej ilości danych odłożonych na stos. Kompilator nie wie kiedy, które przerwanie zostanie wykonane, dlatego wszystkie rejestry wykorzystywane w programie są odkładane w przypadku każdej rutyny ISR, niezależnie od wektora przerwania.

za wykorzystaniem przerwania od timera i każdorazowym startem za pomocą ADSC przemawia możliwość zmiany kanału na którym dokonywany jest pomiar, wykorzystanie powiązania ADC z timerem w rejestrze ADCSRB pozwala tylko na pomiar z jednego kanału.

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.