To jest nasz dziewiąty samouczek dotyczący nauki mikrokontrolerów PIC przy użyciu MPLAB i XC8. Do tej pory omówiliśmy wiele podstawowych samouczków, takich jak rozpoczęcie pracy z MPLABX, miganie diody LED z PIC, timery w PIC, interfejs LCD, interfejs 7-segmentowy itp. Jeśli jesteś absolutnie początkującym, zapoznaj się z pełną listą samouczków PIC tutaj i zacznij się uczyć.
W tym samouczku nauczymy się, jak używać ADC z naszym mikrokontrolerem PIC PICF877A. Większość projektów mikrokontrolerów będzie obejmowała przetwornik ADC (przetwornik analogowo-cyfrowy), ponieważ jest to jeden z najczęściej używanych sposobów odczytu danych ze świata rzeczywistego. Prawie wszystkie czujniki, takie jak czujnik temperatury, czujnik strumienia, czujnik ciśnienia, czujniki prądu, czujniki napięcia, żyroskopy, akcelerometry, czujnik odległości i prawie każdy znany czujnik lub przetwornik wytwarza napięcie analogowe od 0 V do 5 V na podstawie odczytu czujników. Na przykład czujnik temperatury może dawać 2,1 V, gdy temperatura wynosi 25 ° C i zwiększać się do 4,7, gdy temperatura wynosi 60 ° C. Aby poznać temperaturę w rzeczywistym świecie, MCU musi po prostu odczytać napięcie wyjściowe tego czujnika temperatury i powiązać je z rzeczywistą temperaturą. Dlatego ADC jest ważnym narzędziem pracy dla projektów MCU i pozwala dowiedzieć się, jak możemy go używać na naszym PIC16F877A.
Sprawdź również nasze poprzednie artykuły na temat używania ADC w innych mikrokontrolerach:
- Jak korzystać z ADC w Arduino Uno?
- Samouczek Raspberry Pi ADC
- Połączenie ADC0808 z mikrokontrolerem 8051
ADC w mikrokontrolerze PIC PIC16F877A:
Dostępnych jest wiele typów przetworników ADC, a każdy z nich ma swoją własną szybkość i rozdzielczość. Najpopularniejsze typy przetworników ADC to flash, kolejne przybliżanie i sigma-delta. Typu ADC stosowane w PIC16F877A nazywa się kolejnych przybliżeń ADC SAR w skrócie. Nauczmy się więc trochę o SAR ADC, zanim zaczniemy go używać.
Kolejne przybliżanie ADC: SAR ADC działa z pomocą komparatora i kilku rozmów logicznych. Ten typ ADC wykorzystuje napięcie odniesienia (które jest zmienne) i porównuje napięcie wejściowe z napięciem odniesienia za pomocą komparatora, a różnica, która będzie wyjściem cyfrowym, jest zapisywana z najbardziej znaczącego bitu (MSB). Szybkość porównania zależy od częstotliwości zegara (Fosc), na której działa PIC.
Teraz, gdy znamy już podstawy dotyczące ADC, otwórzmy nasz arkusz danych i dowiedz się, jak korzystać z ADC w naszym MCU PIC16F877A. PIC, którego używamy, ma 10-bitowy 8-kanałowy przetwornik ADC. Oznacza to, że wartość wyjściowa naszego ADC będzie wynosić 0-1024 (2 ^ 10), a na naszym MCU jest 8 pinów (kanałów), które mogą odczytywać napięcie analogowe. Wartość 1024 jest uzyskiwana przez 2 ^ 10, ponieważ nasz ADC ma 10 bitów. Osiem pinów, które mogą odczytać napięcie analogowe, jest wymienionych w arkuszu danych. Spójrzmy na poniższe zdjęcie.
Podświetlone są kanały analogowe od AN0 do AN7. Tylko te piny będą w stanie odczytać napięcie analogowe. Dlatego przed odczytaniem napięcia wejściowego musimy określić w naszym kodzie, który kanał ma być używany do odczytu napięcia wejściowego. W tym samouczku użyjemy kanału 4 z potencjometrem do odczytu napięcia analogowego na tym kanale.
Moduł A / D ma cztery rejestry, które należy skonfigurować do odczytu danych z pinów wejściowych. Te rejestry to:
• Rejestr wyników A / D High (ADRESH)
• Niski rejestr wyników A / D (ADRESL)
• Rejestr sterowania A / D 0 (ADCON0)
• Rejestr sterowania A / D 1 (ADCON1)
Programowanie dla ADC:
Program do korzystania z ADC mikrokontrolera PIC jest bardzo prosta, po prostu trzeba zrozumieć tych czterech rejestrów, a następnie czyta dowolne napięcie analogowe będzie proste. Jak zwykle zainicjalizuj bity konfiguracyjne i zacznijmy od void main ().
Wewnątrz void main () musimy zainicjować nasz ADC przy użyciu rejestru ADCON1 i rejestru ADCON0. Rejestr ADCON0 ma następujące bity:
W tym rejestrze musimy włączyć moduł ADC, ustawiając ADON = 1 i włączyć zegar konwersji A / D za pomocą bitów ADCS1 i bitów ADCS0, reszta nie zostanie na razie ustawiona. W naszym programie zegar konwersji A / D wybrany jako Fosc / 16 możesz wypróbować własne częstotliwości i zobaczyć, jak zmienia się wynik. Pełne dane dostępne na stronie 127 arkusza danych. Dlatego ADCON0 zostanie zainicjowany w następujący sposób.
ADCON0 = 0b01000001;
Teraz rejestr ADCON1 ma następujące bity:
W tym rejestrze musimy ustawić format wyniku A / D Wybierz wysoki bit przez ADFM = 1 i ustawić ADCS2 = 1, aby ponownie wybrać Fosc / 16. Pozostałe bity pozostają zerowe, ponieważ planowaliśmy użyć wewnętrznego napięcia odniesienia. Pełne informacje są dostępne w arkuszu danych na stronie 128. Stąd ADCON1 ustawimy w następujący sposób.
ADCON1 = 0x11000000;
Teraz po zainicjowaniu modułu ADC wewnątrz naszej głównej funkcji, przejdźmy do pętli while i zacznijmy odczytywać wartości ADC. Aby odczytać wartość ADC, należy wykonać następujące kroki.
- Zainicjuj moduł ADC
- Wybierz kanał analogowy
- Uruchom ADC, ustawiając Go / Done trochę wysoko
- Poczekaj, aż bit Go / DONE spadnie
- Uzyskaj wynik ADC z rejestru ADRESH i ADRESL
1. Zainicjuj moduł ADC: Nauczyliśmy się już, jak zainicjować ADC, więc wywołujemy tę funkcję poniżej, aby zainicjować ADC
Funkcja void ADC_Initialize () wygląda następująco.
void ADC_Initialize () {ADCON0 = 0b01000001; // ADC ON i wybrano Fosc / 16 ADCON1 = 0b11000000; // Wybrano wewnętrzne napięcie odniesienia}
2. Wybierz kanał analogowy: Teraz musimy wybrać kanał, którego będziemy używać do odczytywania wartości ADC. Pozwala utworzyć funkcję dla tego, tak, że będzie nam łatwo przełączać się między każdego kanału wewnątrz while pętli.
unsigned int ADC_Read (unsigned char channel) {// **** Wybieranie kanału ** /// ADCON0 & = 0x11000101; // Czyszczenie bitów wyboru kanału ADCON0 - = kanał << 3; // Ustawianie wymaganych bitów // ** Wybór kanału zakończony *** ///}
Następnie kanał, który ma zostać wybrany, jest odbierany wewnątrz kanału zmiennego. W linii
ADCON0 & = 0x1100101;
Poprzedni wybór kanału (jeśli istnieje) zostanie wyczyszczony. Odbywa się to za pomocą bitowego i operatora „&”. Bity 3, 4 i 5 są wymuszane na 0, podczas gdy pozostałe mają swoje poprzednie wartości.
Następnie żądany kanał jest wybierany przez trzykrotne przesunięcie numeru kanału w lewo i ustawienie bitów za pomocą bitowego lub operatora „-”.
ADCON0 - = kanał << 3; // Ustawienie wymaganych bitów
3. Uruchom ADC, ustawiając wartość Go / Done na wysokim poziomie: Po wybraniu kanału musimy rozpocząć konwersję ADC, po prostu ustawiając wysoki bit GO_nDONE :
GO_nDONE = 1; // Inicjuje konwersję A / D
4. Poczekaj, aż bit Go / DONE spadnie do niskiego poziomu: bit GO / DONE pozostanie wysoki do zakończenia konwersji ADC, stąd musimy poczekać, aż ten bit ponownie spadnie. Można to zrobić za pomocą while pętli.
podczas (GO_nDONE); // Poczekaj na zakończenie konwersji A / D
5. Pobierz wynik ADC z rejestru ADRESH i ADRESL: Kiedy bit Go / DONE ponownie spadnie do stanu niskiego, oznacza to, że konwersja ADC została zakończona. Wynik ADC będzie wartością 10-bitową. Ponieważ nasz MCU jest 8-bitowym MCU, wynik jest dzielony na górne 8-bitowe i dolne 2-bity. Górny 8-bitowy wynik jest przechowywany w rejestrze ADRESH, a dolny 2-bitowy jest przechowywany w rejestrze ADRESL. Dlatego musimy dodać je do rejestrów, aby uzyskać naszą 10-bitową wartość ADC. Ten wynik jest zwracany przez funkcję, jak pokazano poniżej:
return ((ADRESH << 8) + ADRESL); // Zwraca wynik
Pełna funkcja używana do wyboru kanału ADC, wyzwalania ADC i zwracania wyniku jest pokazana tutaj.
unsigned int ADC_Read (kanał bez znaku) {ADCON0 & = 0x11000101; // Czyszczenie bitów wyboru kanału ADCON0 - = kanał << 3; // Ustawienie wymaganych bitów __delay_ms (2); // Czas akwizycji do naładowania kondensatora GO_nDONE = 1; // Inicjuje konwersję A / D while (GO_nDONE); // Czekaj na zakończenie konwersji A / D return ((ADRESH << 8) + ADRESL); // Zwraca wynik}
Teraz mamy funkcję, która przyjmie wybór kanału jako wejście i zwróci nam wartość ADC. Można zatem bezpośrednio wywoływać tę funkcję w naszych while pętli, ponieważ jest odczyt napięcia analogowego z kanału 4 w tym kursie wywołanie funkcji będzie następujący.
i = (ADC_Read (4)); // zapisz wynik adc w „i”.
W celu wizualizacji wyjścia naszego ADC będziemy potrzebować jakiegoś rodzaju modułów wyświetlających, takich jak LCD lub 7-segmentowy. W tym samouczku do weryfikacji danych wyjściowych używamy 7-segmentowego wyświetlacza. Jeśli chcesz wiedzieć, jak korzystać z 7-segmentowego obrazu, postępuj zgodnie z samouczkiem tutaj.
Kompletny kod znajduje się poniżej, a proces jest również wyjaśnione w Wideo na końcu.
Konfiguracja i testowanie sprzętu:
Jak zwykle zasymuluj kod za pomocą Proteusa, zanim faktycznie przejdzie do naszego sprzętu, schemat projektu pokazano poniżej:
Połączenia czterocyfrowego siedmiosegmentowego modułu wyświetlacza z mikrokontrolerem PIC są takie same jak w poprzednim projekcie, właśnie dodaliśmy potencjometr do pinu 7, który jest kanałem analogowym 4. Zmieniając potencjometr, zmienne napięcie będzie wysyłane do MCU które zostaną odczytane przez moduł ADC i wyświetlone na 7-segmentowym module wyświetlacza. Sprawdź poprzedni samouczek, aby dowiedzieć się więcej o 4-cyfrowym 7-segmentowym wyświetlaczu i jego połączeniu z PIC MCU.
Tutaj użyliśmy tej samej płytki mikrokontrolera PIC, którą stworzyliśmy w samouczku migania diod LED. Po zapewnieniu połączenia prześlij program do PIC i powinieneś zobaczyć takie wyjście
Tutaj odczytaliśmy wartość ADC z potencjometru i przekonwertowaliśmy ją na rzeczywiste napięcie, odwzorowując wyjście 0-1024 na 0-5 woltów (jak pokazano w programie). Wartość jest następnie wyświetlana na 7-segmentach i weryfikowana za pomocą multimetru.
To wszystko, teraz jesteśmy gotowi do korzystania ze wszystkich czujników analogowych dostępnych na rynku, śmiało i wypróbuj to, a jeśli masz jakiekolwiek problemy, jak zwykle, skorzystaj z sekcji komentarzy, z przyjemnością Ci pomożemy.