ATtiny13
3) Analogový vstup
Čtení analogového vstupu je trochu složitější, než čtení
logického stavu.
ATtiny13A obsahuje 10-bitový napěťový A/D převodník.
Referenční napětí je možné nastavit na vnitřní stabilizovaný
zdroj 1,1V.
Druhou možností je nastavit referenci na stejnou hodnotu, jako
je napájecí napětí.
Takže při napájení 5V
dokáže měřit napětí 0 až 5V s rozlišením 5V/1024 (= asi 5mV na číslo).
Tam, kde není třeba takováto přesnost, je možné spodní 2 bity
vynechat. Program se pak zjednoduší, měřená hodnota je stabilnější,
měření je rychlejší, ale rozlišení klesne asi na 20mV na číslo.
O převod z analogové na digitální hodnotu se starají následující
registry:
ADMUX
ADCSRA
ADCH
ADCL
Jak je vidět na obrázku z katalogového listu, registr ADMUX
slouží k výběru jednoho ze 4 analogových vstupů, výběru zdroje
referenčního napětí a určuje způsob, jakým bude ukládán výsledek
měření.
ADMUX = 0b00100001; // nastavení reference na hodnotu napajeciho napeti (REFS0='0')
// zarovnani mereni tak, ze 8 nejvyssich bitu ve vysledku je pohromade (ADLAR=1)
// nastaveni mereni ze vstupu PB2 (=ADC1) (MUX1='0' MUX0=1')
|
Při 8-bitovém měření je výhodnější nastavit ADLAR na '1'. V
tom případě je pak 8 nejvyšších bitů naměřené hodnoty pohromadě.
Při 10-bitovém měření je zase trochu výhodnější dát ADLAR do
'0'.
Pak je pohromadě 8 nejnižších bitů naměřené hodnoty, ke kterým stačí připočítat
(256 * registr ADCH).
V katalogovém listu je názorný obrázek rozdílného ukládání výsledku
při ADLAR='0' a ADLAR='1':
Registr ADCSRA je trochu složitější,
ale pro základní měření postačuje nastavit následující hodnoty:
ADEN ='1'
//
zapnutí A/D převodníku
ADPS[2...0] = '111' // dělič frekvence pro A/D převodník
1:128
Podle kat. listu má být výsledná frekvence pro A/D převodník mezi
50kHz až 200kHz.
Takže při základní frekvenci ATtiny13A, která je 9,6MHz a dělícím
poměru 1:128 vyhází frekvence pro A/D převodník 75kHz.
Když jsou tyto hodnoty nastavené, tak se nastavením bitu ADSC do '1'
spouští vlastní převod.
V okamžiku, kdy je převod ukončen, spadne tento bit zpátky do '0'.
To je signál k tomu, že je možné naměřenou hodnotu přečíst z
registrů ADCH a ADCL.
Pokud není třeba 10-bitová hodnota a je nastaveno zarovnání ADLAR='1', stačí přečíst stav registru ADCH.
Pokud je nutné 10-bitové rozlišení, musí se nejdříve přečíst
hodnota registru ADCL a až potom ADCH.
Takže jednoduchý podprogram pro měření napětí s 10-bitovým
rozlišením na vstupu PB2 by
mohl vypadat takto:
byte spodni;
byte horni;
int vysledek;
void setup()
{
DDRB = 0b00000000; // nastaveni smeru signalu na portu B (cely port na vstup)
PORTB = 0b00000000; // zadne Pull-upy
ADMUX = 0b00000001; // nastavení reference na hodnotu napajeciho napeti (REFS0='0')
// zarovnani mereni tak, ze 8 nejnizsich bitu ve vysledku je pohromade (ADLAR=0)
// nastaveni mereni ze vstupu PB2 (=ADC1) (MUX1='0' MUX0=1')
ADCSRA = 0b10000111; // AD-enable = '1'
// ADPS = dělič frekvence 1:128
}
void loop()
{
ADCSRA |= 0b01000000; // Start prevodu
while (ADCSRA & 0b01000000); // Cekani na signal o ukonceni prevodu
spodni = ADCL; // ADCL obsahuje 8 nejnizsich bitů z namerene hodnoty
horni = ADCH; // ADCH obsahuje 2 nejvyssi bity z namerene hodnoty
vysledek = (horni<<8) + spodni; // v promenne 'vysledek' je 10-bitova hodnota
}
|
Pro ukázkový program použiji zapojení z předchozího příkladu,
akorát místo tlačítka zapojím trimr, jako dělič napětí.
Aby nedocházelo k problémům při nahrávání programu, musí být střední
vývod trimru před nahráním programu odpojitelný.
Požadovaná funkce bude následující:
Napětí na PB2 |
LED na PB3 |
LED na PB4 |
pod 1V |
nesvítí |
nesvítí |
1V až 2V |
svítí |
nesvítí |
2V až 3V |
nesvítí |
svítí |
nad 3V |
svítí |
svítí |
(celé schéma na kliknutí)
V tomto případě použiji jednodušší 8-bitový převod:
// program pro signalizaci velikosti napeti na vstupu PB2 pomoci 2 LED
byte napeti; // promenna, ktera obsahuje 8-bitovou hodnotu namereneho napeti
void setup()
{
DDRB = 0b00011000; // nastaveni smeru signalu na portu B ("1" = vystup ; "0" = vstup)
PORTB = 0b00000000; // zadne Pull-upy a obe LEDky zhasnout
ADMUX = 0b00100001; // nastavení reference na hodnotu napajeciho napeti (REFS0='0')
// zarovnani vysledku mereni tak, ze 8 nejvyssich bitu ve je pohromade (ADLAR=1)
// nastaveni mereni ze vstupu PB2(=ADC1) (MUX1='0' MUX0=1')
ADCSRA = 0b10000111; // AD-enable = '1'
// ADPS (dělic frekvence) 1:128
}
void loop()
{
ADCSRA |= 0b01000000; // Start prevodu nastavenim bitu ADSC na '1'
while (ADCSRA & 0b01000000) // Cekani na signal o ukonceni prevodu (ADSC se preklopi zpatky do '0')
napeti = ADCH; // ADCH obsahuje 8 nejvyssich bitu z namerene hodnoty
if ( napeti < 51) // napeti je pod 1V (1V * 256/5V = 51)
{
PORTB &= 0b11100111; // prepnuti vystupu PB3 a PB4 do LOW
}
else if (napeti < 102) // napeti je mezi 1V a 2V (2V * 256/5V = 102)
{
PORTB &= 0b11101111; // prepnuti vystupu PB4 do LOW
PORTB |= 0b00001000; // prepnuti vystupu PB3 do HIGH
}
else if (napeti < 153) // napeti je mezi 2V a 3V (3V * 256/5V = 153)
{
PORTB &= 0b11110111; // prepnuti vystupu PB3 do LOW
PORTB |= 0b00010000; // prepnuti vystupu PB4 do HIGH
}
else // napeti je vyssi nez 3V
{
PORTB |= 0b00011000; // prepnuti vystupu PB3 a PB4 do HIGH
}
}
|
|