Komparator analogowy


Tematy pokrewne   Podrozdziały
(w budowie)
  Komparator analogowy
APP006 – elementy analogowe
Programowanie komparatora

 

 

Komparator analogowy

 
   
Komparator analogowy jest układem, który porównuje dwa napięcia dostarczane do jego wejść AIN0 i AIN1 (ang. Analog INput) i na wyjściu ACO (ang. Analog Comparator Output) określa, które z tych dwóch napięć jest wyższe. Napięcie na wejściu AIN0 pełni rolę napięcia odniesienia, z którym jest porównywane napięcie na wejściu AIN1. Jeśli UAIN0 > UAIN1, to na wyjściu komparatora otrzymujemy stan logiczny 1, a w przypadku odwrotnym UAIN0 < UAIN1 otrzymujemy stan 0 (zapamiętaj: wyjście ACO ma stan 1, jeśli napięcie odniesienia jest wyższe od porównywanego).

obrazek

Wejścia analogowe AIN0 i AIN1 są wejściami odpowiednio PB0 i PB1 portu B. Należy je ustawić w rejestrze DDRB jako wejścia (bity DDB0 i DDB1 na zero).

obrazek

Dodatkowo w rejestrze PORTB należy wyzerować bity PORTB0 i PORTB1, aby do wejść PB0 i PB1 nie były podłączane oporniki podciągające. Stan komparatora odczytujemy z rejestru ACSR (ang. Analog Comparator control and Status Register - rejestr sterowania i stanu komparatora analogowego) z bitu 5 ACO.

bit 7 6 5 4 3 2 1 0
nazwa ACD ACBG ACO ACI ACIE ACIS1 ACIS0
R/W R/W R/W R R/W R/W R R/W R/W
stan 0 0 N/A 0 0 0 0 0

Rejestr sterowania i stanu komparatora ACSR

 

 

APP006  elementy analogowe

 
   
Do zabawy z komparatorem zaprojektujemy prostą płytkę aplikacyjną APP006. Zastosujemy na niej nowy element elektroniczny – potencjometr. Jest to opornik o regulowanej pokrętłem oporności. Na schemacie elektrycznym potencjometr przedstawiamy za pomocą poniższego symbolu:

obrazek

Oporność pomiędzy zaciskami A–B jest stała i wynosi R. Oporność pomiędzy A–X lub B–X jest regulowana położeniem suwaka i zmienia się w zakresie od 0...R. Oto kilka typów potencjometrów:

obrazek obrazek obrazek
Obrotowy Suwakowy Montażowy (tzw. podkówka)

Musisz jeszcze wiedzieć, że potencjometry dzielą się na trzy grupy:

A: liniowe, oporność zmienna zależy liniowo od położenia suwaka potencjometru. Tego typu potencjometry stosuje się w układach, gdzie trzeba liniowo regulować napięcie.
B: logarytmiczne, oporność na początku ruchu suwaka zmienia się szybko, później coraz wolniej.
C: wykładnicze, oporność zmienia się na początku ruchu suwaka wolno, później coraz szybciej. Takie potencjometry stosuje się np. w sprzęcie audio do regulacji głośności – słuch ludzki posiada charakterystykę wykładniczą.

Do naszych celów najlepsze będą potencjometry liniowe A. Zwróć na to uwagę przy zakupie.

Potencjometry mogą służyć jako regulowane dzielniki napięcia. Rozważmy następujący obwód elektryczny:

obrazek

Napięcie wyjściowe UX zależy od napięcia wejściowego U, wartości oporów R, RX oraz od położenia suwaka X.

Jeśli suwak X jest w punkcie A, to wyjście jest zwarte do masy i napięcie UX = 0V.

Jeśli suwak X jest w punkcie B, to napięcie wyjściowe jest równe:

obrazek

 

Jeśli suwak X znajdzie się pomiędzy punktami A i B, to napięcie wyjściowe będzie miało wartość pośrednią, która zależy od położenia suwaka na materiale oporowym potencjometru:

obrazek

Im bliżej końca B, tym napięcie wyjściowe będzie bliższe napięciu podziałowemu, im bliżej końca A, tym napięcie wyjściowe będzie bliższe 0V. Wynika z tego, że zmieniając położenie suwaka potencjometru, zmieniamy wartość napięcia wyjściowego. Rozważania te są zbliżone do rzeczywistości, jeśli założymy, że potencjometr nie jest obciążany na wyjściu, czyli że w sterowanym obwodzie prąd praktycznie nie płynie. W przeciwnym razie należy dodatkowo uwzględniać opór obciążenia i zadanie się komplikuje. W naszym przypadku możemy założyć, że wejścia mikrokontrolera praktycznie nie będą obciążać dzielnika, ponieważ pobierany prąd wejściowy będzie pomijalnie mały i nie zależy nam na jakiejś super dokładności.

Na płytce APP006 tak dobierzemy oporniki i potencjometry, aby regulacja napięcia przebiegała w granicach od 0 do 1,5V. Najpierw określamy opór potencjometru od 10...22kΩ. Takie potencjometry bez problemu dostaniesz w każdym sklepie elektronicznym. Gdy znamy RX, policzymy R:

obrazek

Dla U = 5V, UX = 1,5V i RX = 10k otrzymujemy:

obrazek

Prąd w układzie (przy założeniu pomijalnego obciążenia dzielnika):

obrazek

Moc wydzielana na oporniku R:

obrazek

Możemy zastosować dowolny opornik, np. 0,125W lub 0,25W. Bez trudu taki dostaniesz w sklepie elektronicznym.

Gdy mamy policzony dzielnik, możemy przystąpić do projektowania płytki APP006. Schemat płytki jest następujący:

obrazek  
Spis elementów
Element Ilość Opis
Opornik 270Ω/0,125W 3 –(                )–
Opornik 22kΩ/0,125W 2 –(                )–
Potencjometr 10kΩ liniowy 2  
Przełącznik 2-obwodowy 2  
Dioda LED czerwona 2  
Dioda LED niebieska/zielona 1  
Złącze kątowe męskie 2 x 4 Goldpin 1  

Uwaga, projekt Eagle korzysta z biblioteki mynewlib.lbr. Bibliotekę pobierz do katalogu eagle/lbr. Wykorzystane elementy:

frames  A5L-LOC  (ramka)

mynewlib.lbr:

INT_2X4_LONG (złącze kątowe goldpin 2 x 4)
6_PIN_DPDT_7X7 (przełączniki x 2)
GND (masa x 6)
R_POT_ROTARY (potencjometry x 2)
R-EU 0204/7 (oporniki x 5)
LRD5MM (diody LED x 3)
Schemat wygląda następująco:
obrazek

 

Płytka drukowana:

obrazek

 

Na płytce APP006 znajdują się dwa potencjometry P0 i P1, dwa przełączniki SW0 i SW1 oraz dwie diody LED D0 i D1 (trzecia dioda D2 pełni funkcję dodatkową). Potencjometr wraz z opornikiem (P0 + R0, P1 + R1) tworzy dzielnik napięcia. Suwak potencjometru pozwala regulować napięcie wyjściowe w zakresie od 0 do około 1,2V. Napięcie to trafia na odpowiednią linię portu, która jest wybierana przełącznikiem. Poniższa tabelka wyjaśnia sposób podłączenia tych elementów do portów mikrokontrolera:
  SW0
off
SW0
on
SW1
off
SW1
on
Suwak P0 PB0 PB2 X X
Dioda LED D0 PB2 PB0 X X
Suwak P1 X X PB1 PB3
Dioda LED D1 X X PB3 PB1

Dioda LED D2 jest zawsze podłączona do linii PB4.

 

 

 

Programowanie komparatora

 
   
Pierwszy program będzie pokazywał stan bitu ACO (ang. Analog Compataror Output – Wyjście Komparatora Analogowego) z rejestru ACSR (ang. Analog Comparator Status Register – Rejestr Stanu Komparatora Analogowego) na diodzie D2.

 

/*
 * main.c
 *
 *  Created on: 03 kwi 2016
 *      Author: Jerzy
 *  Opis:
 *  Program odczytuje stan bitu ACO w rejestrze ACSR
 *  Ustaw oba przyciski w położeniu wyciśniętym
 */

#include <avr/io.h>

int main()
{
    DDRB  = 0b11100; // DB0 i DB1 jako wejścia
    PORTB = 0b00000;

    while(1)
    {
        // Odczytujemy cyklicznie ACO i przesyłamy jego stan
        // na linię DB4, do której jest podłączona dioda D2
        // niebieska
        PORTB = (ACSR & (1<<ACO)) >> 1;
    }
}

 

Oba przełączniki SW0 i SW1 należy ustawić w stan wyciśnięty. Wtedy do PB0 będzie podłączony potencjometr P0, a do PB1 potencjometr P1. Potencjometrem P0 ustawiasz napięcie odniesienia, które trafia do wejścia AIN0 (PB0). Potencjometrem P1 ustawiasz napięcie porównywane, które trafia do AIN1 (PB1). Jeśli napięcie na potencjometrze P1 jest niższe od napięcia ustawionego na P0, to bit AC0 przyjmuje stan 1 i zapala się dioda niebieska D2. Aby to sprawdzić, ustaw P1 w skrajne prawe położenie (maksymalne napięcie), a P0 ustaw w połowie zakresu. Dioda D2 powinna być zgaszona. Teraz powoli przekręcaj pokrętło potencjometru P1 w lewo. Gdy przyjmie mniej więcej takie samo położenie jak w P0, dioda D2 powinna się zaświecić.

Teraz przekręć pokrętło P1 całkowicie w lewo. Dioda D2 powinna być zaświecona. Przekręcaj pokrętłem P1 w prawo. Gdy przyjmie mniej więcej takie samo położenie jak P0, dioda powinna zgasnąć.

Zapamiętaj:

Jeśli napięcie na PB0 (wejście dodatnie AIN0) jest wyższe od napięcia na PB1 (wejście ujemne AIN1), bit ACO ustawia się w stan 1.

Jeśli napięcie na PB0 jest niższe od napięcia na PB1, bit ACO ustawia się w stan 0.

 

Drobna modyfikacja programu daje nieco inny wynik. Teraz zapalana jest dioda D0 przy napięciu dodatnim większym od ujemnego, lub D1 przy napięciu ujemnym większym od dodatniego:

/*
 * main.c
 *
 *  Created on: 03 kwi 2016
 *      Author: Jerzy
 *  Opis:
 *  Program odczytuje stan bitu ACO w rejestrze ACSR
 *  Ustaw oba przyciski w położeniu wyciśniętym
 */

#include <avr/io.h>

int main()
{
    DDRB  = 0b11100; // DB0 i DB1 jako wejścia
    PORTB = 0b00000;

    while(1)
    {
        if(ACSR & (1<<ACO)) PORTB = 0b00100; // Zapala D0, gasi D1
        else                PORTB = 0b01000; // Gasi D0, zapala D1
    }
}

 

Więcej wydobędziemy z komparatora, gdy poznamy dokładnie jego budowę. Przyjrzyjmy się wyprowadzeniom mikrokontrolera, z których może korzystać komparator:

obrazek

Oprócz opisanych wcześniej dwóch wejść AIN0 i AIN1 widzimy tutaj dodatkowe cztery wejścia ADC0...ADC3. Są to wejścia dla przetwornika analogowo cyfrowego (ang. ADC: Analog to Digital Converter), którym zajmiemy się w następnym rozdziale. Jedno z tych wejść może zastąpić wejście AIN1, dzięki czemu mamy możliwość porównywania większej liczby sygnałów. Wejście ADC0 jest podpięte do pinu RESET, i z tego powodu raczej nie powinno być używane (ponieważ przy spadku napięcia do 0V, mikrokontroler ulegnie resetowi). Zwróć uwagę, że numeracja tych wejść nie odpowiada numeracji linii portu B.

obrazek

Przeanalizujmy teraz podany powyżej schemat logiczny komparatora analogowego (zrób to dokładnie, ponieważ w innych mikrokontrolerach AVR komparator pracuje podobnie). Po lewej stronie masz sygnały, które mogą być doprowadzone do wejść komparatora (żółty trójkąt w środku schematu). Do wejścia dodatniego (+) można doprowadzić wewnętrzne napięcie odniesienia (ang. Bandgap Reference) lub napięcie z końcówki AIN0 (PB0). Źródła te są wybierane bitem ACBG (ang. Analog Comparator Bandgap Select), który znajdziesz w opisanym na początku rozdziału rejestrze ACSR:

bit 7 6 5 4 3 2 1 0
nazwa ACD ACBG ACO ACI ACIE ACIS1 ACIS0
R/W R/W R/W R R/W R/W R R/W R/W
stan 0 0 N/A 0 0 0 0 0

Rejestr sterowania i stanu komparatora ACSR

Bit ACBG jest standardowo ustawiany na 0, czyli do wejścia dodatniego komparatora dochodzi napięcie z końcówki AIN0 mikrokontrolera. Napięcie odniesienia jest wykorzystywane do różnych celów wewnątrz mikrokontrolera. Wynosi ono około 1,1V. Po przyłączeniu napięcia odniesienia, należy odczekać krótką chwilę, aby się ustaliło.

Dwa kolejne sygnały ACME (ang. Analog Comparator Multiplexer Enable – włączenie multipleksera dla komparatora analogowego) w rejestrze ADCSRB (ang. ADC Control and Status Register B – rejestr sterowania i stanu przetwornika analogowo-cyfrowego) i ADEN (ang. ADC Enable – włączenie przetwornika analogowo-cyfrowego) w rejestrze ADCSRA (ang. ADC Control and Status Register A – rejestr sterowania i stanu przetwornika analogowo-cyfrowego) określają, czy do wejścia ujemnego komparatora zostanie dołączone napięcie z końcówki AIN1 (ACME=0, ADEN=X lub ACME=1, ADEN=1) lub z jednego z wejść ADC0...ADC3 (ACME=1,ADEN=0). W tym drugim przypadku wyjście ADC0...ADC1 jest wybierane przez bity MUX1 i MUX0 w rejestrze ADMUX (ang. ADC Multiplexer Selection Register – rejestr wyboru multipleksera przetwornika analogowo-cyfrowego). Standardowo jest wybierane wejście AIN1.

bit 7 6 5 4 3 2 1 0
nazwa ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
R/W R/W R/W R/W R/W R/W R/W R/W R/W
stan 0 0 0 0 0 0 0 0

Rejestr sterowania i stanu przetwornika analogowo-cyfrowego ADCSRA

 
bit 7 6 5 4 3 2 1 0
nazwa ACME ADTS2 ADTS1 ADTS0
R/W R R/W R R R R/W R/W R/W
stan 0 0 0 0 0 0 0 0

Rejestr sterowania i stanu przetwornika analogowo-cyfrowego ADCSRB

 

bit 7 6 5 4 3 2 1 0
nazwa REFS0 ADLAR MUX1 MUX0
R/W R R/W R/W R R R R/W R/W
stan 0 0 0 0 0 0 0 0

Rejestr wyboru multipleksera przetwornika analogowo-cyfrowego ADMUX

Obowiązuje tutaj poniższa tabelka funkcji:

ACME ADEN MUX1 MUX0 Wejście ujemne komparatora
0 X X X AIN1
1 1 X X AIN1
1 0 0 0 ADC0 (RESET)
1 0 0 1 ADC1 (PB2)
1 0 1 0 ADC2 (PB4)
1 0 1 1 ADC3 (PB3)

Opisaliśmy wejścia komparatora analogowego. Teraz opiszemy sygnały sterujące oraz system przerwań. Aby nie przewijać ciągle strony w górę i w dół, poniżej umieściliśmy ponownie schemat logiczny komparatora:

obrazek

Bit ACD (ang. Analog Comparator Disable – wyłączenie komparatora analogowego) z rejestru ACSR powoduje przy stanie 1 wyłączenie zasilania komparatora. Standardowo komparator jest włączony.

bit 7 6 5 4 3 2 1 0
nazwa ACD ACBG ACO ACI ACIE ACIS1 ACIS0
R/W R/W R/W R R/W R/W R R/W R/W
stan 0 0 N/A 0 0 0 0 0

Rejestr sterowania i stanu komparatora ACSR

Po wyłączeniu zmniejsza się zużycie energii przez mikrokontroler, zatem jeśli nie potrzebujesz w swojej aplikacji porównywać napięcia i pracujesz na bateriach, wyłącz komparator. Mikrokontroler ATTINY13 posiada jeszcze kilka innych opcji, które umożliwiają oszczędzanie baterii, może nawet się zupełnie wyłączyć i przejść w stan czuwania przy minimalnym poborze prądu. O tym później.

Wyjście z komparatora możesz zawsze odczytać programowo z bitu ACO w rejestrze ACSR, co już przerabialiśmy. Dodatkiem jest możliwość generowania przerwań przez komparator. Aby było to możliwe, należy ustawić na 1 bit ACIE (ang. Analog Comparator Interrupt Enable – włączenie przerwań z komparatora analogowego) w rejestrze ACSR. Jeśli pojawi się przerwanie, to zostaje automatycznie ustawiony na 1 bit ACI (ang. Analog Comparator Interrupt – przerwanie z komparatora analogowego). Bit ten zerujemy wpisując do niego 1, nie 0! Gdy oba bity ACIE oraz ACI są ustawione na 1, zostaje wykonana procedura obsługi przerwania spod wektora 0x005 o nazwie ANA_COMP_vect. Oczywiście należy włączyć wcześniej reakcję na przerwania za pomocą funkcji sei(). Pisaliśmy o tym w rozdziale o przerwaniach. Bity ACIS1 i ACIS0 (ang. Analog Comparator Interrupt Mode Select – wybór trybu przerwania od komparatora analogowego) umożliwiają określenie, kiedy powstanie przerwanie. W każdym przypadku chodzi o zachowanie się sygnału ACO.

ACIS1 ACIS0 Tryb przerwania
0 0 Przerwanie przy zmianie stanu ACO
0 1 Zarezerwowane
1 0 Przerwanie przy zboczu opadającym ACO
1 1 Przerwanie przy zboczu narastającym ACO

Należy jeszcze wspomnieć o rejestrze DIDR0 (ang. Digital Input Disable Register 0 – rejestr wyłączania wejść cyfrowych).

      (PINB5) (PINB4) (PINB3) (PINB2) (PINB1) (PINB0)
bit 7 6 5 4 3 2 1 0
nazwa ADC0D ADC2D ADC3D ADC1D AIN1D AIN0D
R/W R R R/W R/W R/W R/W R/W R/W
stan 0 0 N/A 0 0 0 0 0

Rejestr wyłączania wejść cyfrowych DIDR0

Bity w tym rejestrze sterują wejściami cyfrowymi PINB0...PINB5, jednakże zostały nazwane zgodnie z ich funkcjami w komparatorze analogowym i przetworniku analogowo-cyfrowym. Jeśli jeden z bitów zostanie ustawiony na 1, to odpowiadające mu wejście cyfrowe będzie wyłączone, co zmniejszy zużycie prądu przez mikrokontroler. Opcję tą wykorzystuje się wtedy, gdy dane wejście służy tylko do pomiaru napięć analogowych i nie jest używane jako wejście cyfrowe. Wejście wyłączone daje przy odczycie w PINB zawsze stan 0. W normalnym stanie wszystkie wejścia cyfrowe są włączone.

 

Teraz pobawimy się trochę płytką APP006 i komparatorem ATTINY13. Poniższy program działa identycznie jak ten, który podaliśmy wcześniej w tym rozdziale. Różnica polega na tym, iż wejście ujemne komparatora podłączamy do ADC3 (PB3). Przed uruchomieniem ustaw przełącznik SW1 w pozycji wciśniętej. Spowoduje to dołączenie potencjometru do ADC3, natomiast dioda D1 będzie podłączona do DB1.

/*
 * main.c
 *
 *  Created on: 06 kwi 2015
 *      Author: Jerzy
 *  Opis:
 *  Program odczytuje stan bitu ACO w rejestrze ACSR
 *  Przełącznik SW0 w stanie wyciśniętym
 *  Przełącznik SW1 w stanie wciśniętym
 */

#include <avr/io.h>

int main()
{
    DDRB  = 0b00010;    // DB1 jako wyjście
    PORTB = 0b00000;
    DIDR0 = 0b11111;    // Wyłączamy wejścia cyfrowe
    ADCSRB = (1<<ACME); // Włączamy multiplekser
    ADMUX = 0b11;       // Do (-) podłączamy ADC3 (PB3)
    while(1)
    {
        // Odczytujemy cyklicznie ACO i przesyłamy jego stan
        // na linię PB1, do której jest podłączona dioda d1
        // czerwona
        PORTB = (ACSR & (1<<ACO))>>4;
    }
}

Potencjometr P0 reguluje napięcie dodatnie na wejściu AIN0 (PB0). Potencjometr P1 reguluje napięcie ujemne na wejściu ADC3 (PB3). Jeśli napięcie dodatnie jest większe od ujemnego, to zapali się dioda D1. Inaczej dioda D1 jest zgaszona.

Drobna modyfikacja programu powoduje zapalenie diody D0, gdy napięcie dodatnie jest większe, lub D1, gdy napięcie ujemne jest większe.

/*
 * main.c
 *
 *  Created on: 06 kwi 2015
 *      Author: Jerzy
 *  Opis:
 *  Program odczytuje stan bitu ACO w rejestrze ACSR
 *  Przełącznik SW0 w stanie wyciśniętym
 *  Przełącznik SW1 w stanie wciśniętym
 */

#include <avr/io.h>

int main()
{
    DDRB  = 0b00110;    // DB1 i DB2 jako wyjścia
    PORTB = 0b00000;
    DIDR0 = 0b11111;    // Wyłączamy wejścia cyfrowe
    ADCSRB = (1<<ACME); // Włączamy multiplekser
    ADMUX = 0b11;       // Do (-) podłączamy ADC3 (PB3)
    while(1)
    {
        if(ACSR & (1<<ACO)) PORTB = 0b00100; // Zapala D0, gasi D1
        else                PORTB = 0b00010; // Gasi D0, zapala D1
    }
}

W następnym programie łączymy wejście dodatnie komparatora z wewnętrznym napięciem odniesienia. Potencjometry będą natomiast podłączone do wejść:

  • P0 → ADC1 (PB2)
  • P2 → ADC3 (PB3)

Dzięki temu możemy niezależnie sprawdzać komparatorem napięcia na potencjometrach. Oba przełączniki należy wcisnąć.

/*
 * main.c
 *
 *  Created on: 06 kwi 2015
 *      Author: Jerzy
 *  Opis:
 *  Program porównuje napięcia na potencjometrach P0 i P1
 *  z wewnętrznym napięciem odniesienia. Jeśli napięcie na
 *  danym potencjometrze będzie wyższe od napięcia odniesienia,
 *  to zostanie zapalona dioda związana z danym potencjometrem.
 *  Gdy napięcia na obu potencjometrach będą wyższe od napięcia
 *  odniesienia, zostanie dodatkowo zapalona dioda D2 niebieska.
 *
 *  Oba przełączniki SW0 i SW1 w stanie wciśniętym
 */

#include <avr/io.h>
#include <avr/delay.h>

int main()
{
    DDRB  = 0b10011;    // Jako wyjścia:
                        // PB4 - dioda niebieska
                        // PB1 - dioda D1
                        // PB0 - dioda D0
    PORTB  = 0b00000;
    DIDR0  = 0b11111;   // Wyłączamy wszystkie wejścia cyfrowe
    ADCSRB = (1<<ACME); // Włączamy multiplekser
    ACSR   = (1<<ACBG); // Do wejścia (+) napięcie odniesienia
    while(1)
    {
    	ADMUX = 0b01;   // Do (-) ADC1 (P0)
    	_delay_ms(1);   // Opóźnienie na ustabilizowanie się portów
    	if (ACSR & (1<<ACO)) PORTB &= 0b11110; // Gasimy D0
    	else                 PORTB |= 0b00001; // Zapalamy D0
    	ADMUX = 0b11;   // Do (-) ADC3 (P1)
    	_delay_ms(1);   // Opóźnienie na ustabilizowanie się portów
    	if (ACSR & (1<<ACO)) PORTB &= 0b00001; // Gasimy D1
    	else                 PORTB |= 0b00010; // Zapalamy D1
    	if((PORTB & 0b00011) == 0b00011) PORTB =  0b10011; // Zapalamy D2
    	else                             PORTB &= 0b00011; // Gasimy D2
    }
}

Program działa następująco:

Na początku ustawiamy odpowiednio rejestry sterujące. Jako wyjścia będą używane linie PB4, PB1 i PB0, ponieważ do nich zostaną dołączone diody D2,D1 i D0 (po wciśnięciu przełączników SW0 i SW1 na płytce APP006). Port B jest wstępnie zerowany. Dalej włączamy multiplekser analogowy ustawiając na 1 bit ACME w rejestrze ADCSRB. Do wejścia dodatniego komparatora podłączamy wewnętrzne napięcie odniesienia przez ustawienie na 1 bitu ACBG w rejestrze ACSR.

Po tych czynnościach wstępnych program wchodzi w pętlę nieskończoną, w której kolejno przełącza wejście ujemne komparatora na linie ADC1 (potencjometr P0) i ADC3 (potencjometr P1). Po przełączeniu należy wprowadzić małe opóźnienie, aby porty multipleksera faktycznie się przełączyły. Powinno wystarczyć 1...3 ms. Po przyłączeniu odpowiedniej linii do komparatora odczytujemy bit ACO w rejestrze ACSR. Jeśli jest ustawiony na 1, to wewnętrzne napięcie odniesienia jest wyższe od napięcia na suwaku potencjometru. W takim przypadku gasimy diodę LED skojarzoną z potencjometrem. Inaczej zapalamy tę diodę.

Na koniec sprawdzamy, czy obie diody są zaświecone (ostatnie dwa bity PORTB równe 0b11). Jeśli tak, zapalamy diodę D2 (niebieską). Inaczej gasimy D2.

 

W następnym programie wykorzystamy przerwania od komparatora analogowego. Oba przełączniki SW0 i SW1 ustaw w położeniu wyciśniętym.

/*
 * main.c
 *
 *  Created on: 07 kwi 2015
 *      Author: Jerzy
 *  Opis:
 *  Program cyklicznie mruga diodą niebieską. Komparator obsługuje
 *  przerwanie przy zmianie stanu wyjścia ACO. Gdy ACO = 1, zostaje
 *  zapalona dioda D0, dioda D1 jest gaszona. Gdy ACO = 0, zostaje
 *  zapalona dioda D1, a D0 jest gaszona.
 *  Oba przełączniki SW0 i SW1 w stanie wyciśniętym
 */

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/delay.h>

// Procedura obsługi przerwania z komparatora analogowego
ISR(ANA_COMP_vect)
{
    if(ACSR & (1<<ACO)) PORTB = (PORTB & 0b10011) | 0b00100;
    else                PORTB = (PORTB & 0b10011) | 0b01000;
}

int main()
{
    cli();              // Wyłączamy przerwania
    DDRB  = 0b11100;    // Jako wyjścia:
                        // DB4 - dioda niebieska
                        // DB3 - dioda D1
                        // DB2 - dioda D0
    PORTB = 0b00000;
    DIDR0 = 0b11111;    // Wyłączamy wejścia cyfrowe
    ACSR = (1<<ACIE);   // Uaktywniamy przerwania od komparatora
    sei();              // Włączamy przerwania

    while(1)
    {
        _delay_ms(500);
        PINB = 0b10000; // Cyklicznie zapalamy i gasimy D2
    }
}

 

 


   I Liceum Ogólnokształcące   
im. Kazimierza Brodzińskiego
w Tarnowie

©2024 mgr Jerzy Wałaszek

Dokument ten rozpowszechniany jest zgodnie z zasadami licencji
GNU Free Documentation License.

Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl

W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe