Przejdź do głównej zawartości

Programowanie AVR cz.8: Przetwornik analogowo-cyfrowy oraz modulacja szerokości impulsu.

Dziś kolejny wgląd w wyposażenie mikrokontrolera ATmega48P - tym razem przyglądamy się wbudowanemu w układ przetwornikowi analogowo-cyfrowemu oraz - dostępnej również w modelach ATtiny - modulacji szerokości impulsu realizowanej przez timery.

Artykuł ten jest w pewnym sensie wstępem do następnego, który pojawi się już wkrótce, a którego tematykę zdradziłem na końcu.

Przetwornik A-C (skrót spotykany w anglojęzycznej literaturze to ADC od Analog to Digital Converter) to układ pozwalający na zamianę wartości napięcia (elektrycznego sygnału analogowego ;-)) na liczbę. W przypadku mojej ATmegi przetwornik ma rozdzielczość 10-bitową, co oznacza, że wartość napięcia podawanego na wejście przetwornika może być po konwersji zapisana jako liczba z przedziału od 0 do 1023 (musimy użyć zmiennej word do zapamiętania tej liczby). Jeśli jesteśmy w posiadaniu mikrokontrolera w obudowie PDIP 28-wyprowadzeniowej, to mamy do dyspozycji sześć kanałów (niezależnych wejść) przetwornika A-C, przyporządkowanych wyprowadzeniom od 23 do 28. W sumie wszystkich kanałów jest osiem plus jeden dodatkowy, o którego przeznaczeniu napiszę w następnym artykule. Kwestie zasilania układu podczas korzystania z ADC przedstawiłem krótko na końcu posta.

Obsługa przetwornika analogowo-cyfrowego w BASCOMie wymaga wstępnej konfiguracji, podczas której ustawiamy m. in. tryb działania przetwornika (ciągły lub "na żądanie") oraz wartość napięcia odniesienia (najczęściej wartość doprowadzona do wyprowadzenia AVCC układu lub wewnętrzna wartość domyślna 1,1V). Szczegóły znajdziecie na stronie pomocy BASCOMa. Przykład konfiguracji (patrz: listing):

' Konfiguracja przetwornika analogowo-cyfrowego; napięcie odniesienia ustalone na 5V 
' (patrz: wyprowadzenie AVCC mikrokontrolera), czyli przedział od 0 do około 5V będzie 
' "rzutowany" na 10-bitową liczbę (od 0 do 1023). 
Config Adc = Single , Prescaler = Auto , Reference = Avcc 

Pojedyncze odczyty wykonywane są (w trybie "single") za pomocą funkcji getadc, która jako parametr przyjmuje numer kanału (w przypadku kanałów dostępnych fizycznie jest to liczba z przedziału od 0 do 5). Musimy pamiętać, że konwersja sygnału analogowego na cyfrowy wymaga czasu, dlatego też żeby otrzymać wiarygodne odczyty, należy unikać "lawinowego" wywoływania funkcji getadc. Wywołanie funkcji getadc w znakomitej większości przypadków sprowadza się do podania jako parametru numeru kanału przetwornika i zapamiętania wyniku w zmiennej typu word:

Dim Odczyt_0 As Word 
... 
Odczyt_0 = Getadc(0) 

Zawartość zmiennej Odczyt_0 możemy teraz swobodnie interpretować.

Kolejny opisywany dziś element wyposażenia ATmegi to generator PWM (ang. Pulse Width Modulation). Modulacja szerokości impulsu realizowana jest przez każdy z trzech timerów, jednak trzeba pamiętać, że tylko jeden z nich (timer1) jest 16-bitowy - pozostałe dwa to liczniki/timery 8-bitowe.
Jeśli chodzi o istotę zjawiska, modulacja szerokości impulsu to nic innego jak zmiana współczynnika wypełnienia dla fali prostokątnej o określonej częstotliwości.

Konfigurując timer jako generator PWM musimy ustalić, z jaką częstotliwością mają być generowane impulsy, jaki ma być zakres licznika (8, 9 czy 10 bitów; dotyczy tylko timera 16-bitowego - w przypadku liczników 8-bitowych nie ma możliwości zmiany zakresu) i czy rejestr porównania (przedstawiony w dalszym ciągu artykułu) ma decydować o szerokości (czasie trwania) logicznego zera bądź jedynki logicznej.

Przykład konfiguracji ośmiobitowego timera jako generatora PWM (szczegóły znajdziecie w dokumentacji BASCOMa - Timer0 i Timer1):

' Timer0 pracujący z największą szybkością w trybie PWM; porównywanie wartości timera 
' w systemie "clear up" spowoduje zwiększanie szerokości impulsu wraz ze wzrostem wartości zmiennych 
' PWM0A i PWM0B (patrz dalej). 
Config Timer0 = Pwm , Prescale = 1 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up 

W dalszej części artykułu skupimy się właśnie na 8-bitowym timerze 0.

Każdy timer pracujący w trybie PWM posiada dwa wyjścia (stąd wniosek, że mamy do dyspozycji 6 kanałów PWM) - dla timera 0 są to OC0A i OC0B, przypisane odpowiednio wyprowadzeniom 11 i 12 układu. Każde z tych wyjść może być osobno konfigurowane ze względu na współczynnik wypełnienia przebiegu, czyli na dobrą sprawę mogą one pracować niezależnie (przynajmniej z punktu widzenia programu).

Za zmianę szerokości impulsu odpowiadają tzw. rejestry porównania, które w BASCOMie dostępne są poprzez zmienne (a raczej identyfikatory, symbole) Pwm0a i Pwm0b (dla timera 0; w przypadku pozostałych timerów używamy identyfikatorów z odpowiednio podmienioną cyfrą, zresztą podobnie rzecz ma się ze wspomnianymi wcześniej wyjściami). Wartości tych zmiennych, których rozmiar jest uzależniony od konfiguracji timera (w przypadku timera 0 są to zmienne 8-bitowe), mogą być ustalane programowo. Są one cyklicznie porównywane ze stanem licznika i w oparciu o wynik tego porównania (i konfigurację generatora) ustalany jest - że użyję szalenie skompresowanego skrótu - czas trwania jedynki logicznej lub zera logicznego na wyjściu generatora PWM.

Wyczerpujący opis działania timerów jako generatorów PWM w mikrokontrolerach AVR przedstawił Piotr Górecki w swojej książce Mikrokontrolery dla początkujących (Wydawnictwo BTC, Warszawa 2006) - polecam.

Ilustracją do tego artykułu jest prosty układ, przedstawiony na poniższym schemacie:


Za pomocą potencjometrów, które pełnią tutaj rolę regulowanych dzielników napięcia, podajemy na kanały 0 i 1 przetwornika analogowo-cyfrowego napięcie o wartościach między 0 a 5V (uwaga: program zakłada, że pracujemy z napięciem zasilania równym 5V; można obniżyć napięcie, ale wyniki wyświetlane na LCD będą przekłamane, chyba, że zmienimy w programie przelicznik). Wartość odczytanego z ADC napięcia, przetworzona na postać liczbową, a następnie na wolty według zaszytego w programie przelicznika, jest wizualizowana na opcjonalnie dołączonym do układu wyświetlaczu LCD (opisywany przeze mnie moduł wyświetlacza sterowany przez port szeregowy UART), natomiast za jasność świecenia diod LED odpowiada właśnie współczynnik wypełnienia przebiegu prostokątnego pozyskanego z generatora PWM. Współczynnik ten zależy w sposób pośredni od wartości napięcia odczytanej przez ADC, więc za pomocą potencjometrów regulujemy jasność świecenia diod.

Program z przedstawionego niżej listingu nie powinien zawierać żadnego zaskakującego elementu - kod sam dla siebie stanowi komentarz, choć parę rzeczy dorzuciłem.

Na koniec uwaga dotycząca zasilania mikrokontrolera podczas korzystania z przetwornika analogowo-cyfrowego. Zapewne zauważyliście, że lewa strona schematu zawiera mnóstwo kondensatorów o wartości 100nF oraz cewkę 10μH. Jest to po prostu standardowe podłączenie zasilania, zgodne z kartą katalogową ATmegi, szalenie ważne ze względu na prawidłową filtrację napięcia, pozwalającą uniknąć niestabilnego działania układu, a w niektórych przypadkach nawet umożliwić w ogóle działania.

W następnym poście przedstawię schemat układu szalenie prądożernego termometru mikroprocesorowego - oczywiście wykorzystującego m. in. opisane tutaj ficzery.

Komentarze

Popularne posty z tego bloga

Niesamowicie prosty czujnik zmierzchowy.

Tym razem zero programowania, będzie natomiast nostalgiczno-wspomnieniowy układzik, lekko zmodyfikowany.
Otóż kilka dni temu rozmawialiśmy w gronie znajomych o różnego rodzaju czujnikach zmierzchowych i czujnikach ruchu. Ponieważ należę do tych wariatów, co to hołdują jeszcze owej przestarzałej i kompletnie odrealnionej dziś zasadzie: "po co kupować, gdy można zrobić", stwierdziłem, że poskładam takie coś (czujnik zmierzchowy; sensor ruchu faktycznie lepiej nabyć, choćby ze względu na rozmiary ;)) i być może podłączę do jakiegoś mikrokontrolera. Przypomniało mi się też przy okazji, że znalazłem ostatnio w elektronicznych śmieciach stary fotorezystor (dla niewtajemniczonych: element zmieniający rezystancję, czyli opór elektryczny, pod wpływem działania strumienia światła) RPP130, jeden z kilku pozostałych po montowanych wieki temu układach tranzystorowych do zdalnego sterowania pracą urządzeń za pomocą latarki... No OK, nie było to specjalnie rozbudowane zdalne sterowanie ;)

Android i zewnętrzny moduł GPS

Od kilku dni jestem w posiadaniu smyrfona z Androidem 4.1.1 na pokładzie. Kwestie związane z wyborem systemu roztrząsałem już na G+, a ten artykuł tutaj ma konkretny temat, więc nie będę wyjaśniał po raz n-ty. Po prostu zwyciężyły popularność i ekosystem oraz przywiązanie do produktów sieciowych Google. Mniejsza.

Zbliża się sezon urlopowy :-) Moi podopieczni już mają wakacje, a ja wyjeżdżam wkrótce. W każdym bądź razie wakacje to podróże - samochodem, rowerem, na piechotę, żaglówką, motorówką, samolotem... Zaawansowane urządzenia mobilne przyzwyczaiły nas już do usług lokalizacyjnych, z których najważniejszą jest GPS (na dalszym planie mamy A-GPS, lokalizacje w oparciu o sieci WiFi itp.). Często korzystamy z programów, które w coraz ciekawszy sposób wiążą naszą lokalizację, pobraną z np. GPS-a, z przeróżnymi danymi, nieraz ocierając się o AR.
Każdy współczesny smartfon, a przynajmniej znakomita ich większość, wyposażona jest we wbudowany odbiornik sygnału lokalizacyjnego (GPS, GLONASS…

Po co mi to całe Arduino?

Oczywiście tytuł ma być jedynie prowokacją. Chociaż nie do końca - artykuł jest właśnie poświęcony pracy w Arduino IDE z mikrokontrolerami, ale bez płytek Arduino.
Czym jest Arduino - wiemy wszyscy, zarówno początkujący fani programowania elektroniki, jak i zaawansowani mikrokontrolerowcy. Jeśli jednak nie do końca wiemy, zachęcam do odwiedzenia strony domowej projektu (link 5 na końcu artykułu) oraz zerknięcia np. w poradnik (link 4).

Jakiś czas temu, przełamując się i zmieniając zdanie ("o 180 stopni" ;-)) nabyłem sobie Arduino Leonardo, głównie w celu jego "obwąchania" i zapoznania się z bogatym zbiorem bibliotek dostępnych dla tej platformy. Zgoda, różne biblioteki są dostępne niezależnie od Arduino, ale i tak się zdecydowałem. Dlaczego Leonardo? Otóż miałem ochotę przyrządzić dwie pieczenie na jednym ogniu - mieć Arduino i przetestować ATmegę 32u4. Dziś doskonale zdaję sobie sprawę, że żeby pobawić się Arduino nie trzeba go w ogóle posiadać... Ale po kolei.

Pi…