Dažnai vienas iš
mikrokontrolerių privalumų yra integruotas ADC (analoginis-skaitmeninis
keitiklis). Šiuolaikiniai mikrokontroleriai turi apie 10 bitų ir daugiau ADC
keitiklius, tokio tikslumo visiškai pakanka tolydiniam signalui konvertuoti į
skaitmeninį pavidalą. Taip pat keletą atskirų kanalų-linijų, prie kurių galima
jungti ir paduoti skirtingas matuojamas įtampas. Labai patogu turėti keitiklio
funkciją viename įrenginyje tiek vietos, tiek galimybių prasme. Svarbiausia
mokėti pasinaudoti suteiktu funkcionalumu kai prireikia. Žinoma, rinkoje visada
išlieka ir specializuoti bei spartesni 16bitų ir pan. keitikliai. Šiame
straipsnyje apžvelgsime Atmega ADC naudojimo ypatumus bandant nuskaityti vieno
iš populiariausių analoginio temperatūros sensoriaus LM35DZ išvedamą
informaciją.
I. Sensorius
Pirmiausia pasiaiškinkime
apie sensorių, iš kurio teks gauti informaciją. LM35 tai serija įvairiomis
savybėmis pasižyminčių temperatūros sensorių. Mano nagrinėjamas variantas turbūt
vienas iš paprasčiausių, lengviausiai prieinamų ir greitai pritaikomų. Pats
prietaisas yra pakankamai paprastas, turi tris išvadus, o veikimo principas -
pasyvus. Suteikus atitinkamą 4-20V maitinimą jis nuolat atiduoda temperatūros
duomenis. Viena išvado „koja“ jungiama prie maitinimo, kita – žemė, o vidurinė
– analoginis temperatūros išvedimas. Sensoriaus išvedama temperatūra yra iškart
Celsijaus skalėje, tiesinė, tačiau įtampos (milivoltų) pavidalu. Kiekvienas
10mV proporcingai atitinka 1 Celsijaus laipsnį. Taigi 0 laipsnių – 0mV, 20 laipsnių
– 200mV ir pan. Sensoriaus skalė yra tikrai plati, nuo -55 iki 150 laipsnių
Celsijaus, tikslumas net +/-0.5 laipsnio. Yra galimi du naudojimo būdai – pilno
diapazono ir susiaurinto (0-150 laipsnių). Priklausomai nuo schemos jungimo,
sensorius gali atiduoti skirtingą temperatūra (žiūrėti schemas). Daugiau apie
sensorių galima paskaityti oficialioje jo dokumentacijoje – datasheet.
II. Bandymo schema
Šiam darbeliui
pasirinkau atmega8 mikrokontrolerį, su kitais Atmega modeliais darbas būtų analogiškas.
Sujungimo schema parodyta žemiau. Sensorius bus maitinamas ta pačia 5V įtampa,
kaip ir mikrokontroleris. Reikia pastebėti, kad temperatūros išvedimas
prijungtas prie ADC0 išvado. Schema yra minimali ir to užtenka, kad duomenys
būtų įvesti. Kitas klausimas su rezultatų vaizdavimu. Galima prijungti LCD
ekraną, pasinaudoti LED matrica ar tiesiog elementariai prijungti 10 LED
šviesos diodų, kad būtų matoma visų bitų informacija. Pasirinkimą palieku
skaitytojui.
III. Atmega ADC
Integruotas ADC
pasižymi tokiomis savybėmis – 10 bitų geba, absoliutinis +/- 2LSB (least
significant bit) tikslumas, 13μs - 260μs keitimo laikas, iki 15k SPS (keitimų
per sekundę). Iš to seka, jog iš 10 bitų, 8 bus tikrai tikslūs, o du
paskutiniai nevisada dėl triukšmų ir pan. Keitiklis nepasižymi dideliu keitimo
greičiu (specializuoti sugeba net iki 1M SPS ir daugiau), bet mūsų atveju to
užtenka. Atmega turi integruotą vidinį 2.56V atraminį (reference) įtampos
šaltinį su 10% paklaida, gali dirbti keliais režimais – laisvos eigos (free
running) bei vienintelio konvertavimo (single conversion). Atraminiu įtampos
šaltiniu gali būti naudojamas tiek vidinis, tiek ir išorinis, greičiausiai daug
stabilesnis. Tam paliktas ir naudojamas AREF atmega išvadas, prie kurio
jungiamas išorinis šaltinis. Atraminė įtampa apsprendžia, kokią maksimalią
įtampą iš sensoriaus galima paduoti į ADC įvadą. Tarkime, jei naudojamas
vidinis atraminis šaltinis tai į ADC įvestį neverta paduoti didesnę nei 2.56V
įtampa, nes vis tiek viršijus šią ribą keitiklis atiduos tą pačią maksimalią 0x3FF
reikšmę (t.y. visi 10 bitų yra vienetai 1111111111). Esant kitokios įtampos
matavimo poreikiui, reikia keisti diapazoną arba naudoti kitą atraminį šaltinį.
Šiam darbui mums visiškai pakaks ir vidinio 2.56V atraminio šaltinio.
Tęsiant ADC
galimybių apžvalgą, svarbūs yra veikimo būdai. Free running režime, ADC
keitiklis vieną kartą paleistas dirba tol, kol jis neišjungiamas. Vos tik
baigiamas vienas konvertavimas, tuoj pradedamas kitas. Single režimu, ADC
paleidžiamas ir pabaigęs darbą sustoja, kol vėl nepaleidžiamas. Taip galima
labiau taupyti energiją.
Toliau atmega
palaiko ADC pertraukimus (interrupt), kai ADC konvertavimas baigiasi, todėl
mikrokontroleris gali daryti kitus darbus, kol ADC dirba. Priklausomai nuo
modelio, turi 6 ir daugiau atskirus ADC kanalus/išvadus (channels), prie kurių
galima jungti atskiras matuojamas linijas. Na ir dar kitų privalumų. Bent jau
tiek parašyta oficialioje dokumentacijoje (datasheet). Norint sužinoti plačiau,
siūlau ją pasiskaityti. Su viskuo, ką čia paminėjau susipažinsime visai
netrukus.
IV. ADC veikimo
principai
Bendram supratimui,
aptarkime dar patį keitiklio veikimą. Šį skyrelį galite praleisti, jei viskas
jau žinoma. Taigi, įtampos konvertavimas į skaitmeninį pavidalą atliekamas
keliais etapais. Pirmiausia įtampa Vin iš sensoriaus ADC įvedime (šiuo atveju ADC0)
yra nuskaitoma ir užlaikoma (sample & hold) tam, kad būtų vėliau
kvantuojama. Kvantavimo procesas užtrunka atitinkamą laiko tarpą. Kvantavimo
etape pasinaudojant atraminiu įtampos šaltiniu Vref ir vidiniu įtampos komparatoriumi,
įtampos yra lyginamos tarpusavyje. Keičiama (didinama/mažinama) 10 bitų
skaitmeninė reikšmė ir jos atitinkama įtampa yra lyginama su Vin. Kadangi Atmega
turi 10 bitų keitiklio tikslumą, t.y. 2^10=1024 lygių (kvantų), kiekvienam
bitui (kvantui) tenka Vbit=Vref/1024 įtampos. Įtampoms sutapus iki +/- 1/2LSB,
konvertavimas nutraukiamas ir reikšmė atiduodama apdorojimui į pagrindinę
programą. Dėl aiškumo siūlau dar pasidomėti apie tai internete.
V. Mikrokontrolerio
logika
Technines detales
aptarėme, veikimo principą irgi, belieka išsiaiškinti, kaip teisingai
pasinaudoti integruotu ADC keitikliu. Pagal nutylėjimą, ADC keitiklis atmegoje
yra išjungtas, todėl bus būtina jį įjungti. Tai atliekama panaudojant ADCRA
registrą. Tačiau prieš tai reikia teisingai sukonfigūruoti ADC parametrus.
Pradedame nuo ADMUX
registro, jame turime nurodyti, kokį išorinį atraminį šaltinį naudosime. Kadangi
bus reikalingas vidinis, tai reikia nustatyti REFS0 ir REFS1 bitus. Jų
nenustačius bus naudojamas išorinis atraminis šaltinis prijungtas prie AREF
atmega įvado. Įjungus ADC pagal nutylėjimą yra naudojamas ADC0 įvadas įtampos
nuskaitymui, norint pakeisti kanalą tai galima padaryti nustatant MUX0..3 bitus
pagal lentelę žemiau.
Konfigūravimą
toliau tęsiame su ADCSRA registru. Reikia pasirinkti, kokį konvertavimo režimą
naudosime – free running ar single conversion. Naudojant free running metodą
nustatomas ADFR bitas. Šiuo atveju aš pasirinkau nenustatyti, todėl bus
naudojamas vienkartinis konvertavimo režimas. Tam, kad neužimti
mikroprocesoriaus nereikalingu darbu kaskart tikrinant, ar ADC reikšmė jau paruošta (t.y. naudoti polling),
galima nustatyti pertraukimų bitą ADIE. Tokiu atveju gauname efektyvesnį
veikimą, sunaudojama mažiau energijos, o procesorius galės atlikti kitus
darbus. Reikšmei pasirodžius bus sustabdomas programos vykdymas ir vykdomas
pertraukimo kodas. Taigi taip ir darome. Šio metodo negalėsime taikyti, jei
pertraukimai programoje yra neleidžiami, bet šiuo atveju tai negalioja. Kaip
aprašyti pertraukimų vektorių bus parašyta toliau.
Kadangi ADC dirba
mažesniu dažniu nei atmega mikroprocesorius, tai būtinas dažnio dalinimas
(prescaling). Optimalus dažnis, kuriuo dirba ADC, yra nuo 50kHz iki 200kHz,
tokiu atveju garantuojama 10 bitų geba. Žinoma, galima bandyti naudoti didesnį
spartai padidinti kokybės sąskaitą, bet mūsų atveju tai yra nereikalinga.
Taigi, reikia pasirinkti dalinimo faktorių. Priklausomai nuo atmega taktinio
dažnio yra parenkamas ir daliklis iš galimų reikšmių (2, 4, 8, 16, 32, 64, 128).
Taigi, jei dažnis yra tarkim 1MHz, tai galima naudoti 8, nes 1MHz/8=125kHz, ir
tai jau patenka į reikiamo dažnio diapazoną. Šiam pasirinkimui reikia nustatyti
ADPS1 ir ADPS0 bitus. Kadangi aš naudoju 12MHz kvarcinį rezonatorių, tai 12MHz/64
= 187.5kHz ir reikės nustatyti ADPS2 ir ADPS1 bitus. Manau supratote, kodėl čia
būtina prisitaikyti kiekvienam konkrečiu atveju.
Iki paleidimo liko
tik keli etapai. Lieka įjungti pertraukimus programoje ir paleisti ADC. Pertraukimai
įjungiami nustačius 7 (septintą) bitą: SREG |= (1<<7) arba tiesiog
panaudojant funkciją sei(). Toliau – įjungti ADC, tai daroma į ADCSRA registrą
įrašant ADEN bitą. Galiausiai paleisti ADC konvertavimą – į ADCSRA registrą
įrašomas ADSC bitas. Tai viskas, ko reikia paleidimui. Visus etapus vaizduoja
kodas žemiau.
Kadangi pasirinkome
pertraukimų režimą, tai būtina prieš testuojant aprašyti ir pertraukimų
vektoriaus vykdomą kodą. Kodą rašome vektoriuje ADC_vect taip: ISR(ADC_vect) {
/* kodas */ }
Vektoriuje būtina
paimti ADC konvertuotą reikšmę ir išsisaugoti kokiame nors globaliame kintamajame.
Pirmiausia paimame ADCL reikšmę, po to ADCH, rezultatą sujungiame ir išsaugome.
Sekančiu etapu galime paleisti ADC dar kartą, nes pagal single conversion
režimą, po konvertavimo ADC sustoja. Siekiant paleisti ADC vėl, nustatome ADSC
bitą ADCSRA registre. Toliau su reikšme programoje galite daryti ką tik norite
– atvaizduoti, atlikti kitus skaičiavimus, etc.
Norint konvertuoti
ADC reikšmę į įtampą, naudojama tokia formulė: Vin = ADC_value*Vref/1024. O temperatūrai
Celsijaus laipsniais gauti, reikia turimą rezultatą dar padauginti iš 100.
Taigi temp = Vin*100. Ši reikšmė daug informatyvesnė ir ją patogu vaizduoti naudojant
tik 6 LED diodus, jei temperatūrą matuosite -32 iki +64 laipsnių ribose. Reiktų tik pakoreguoti pagrindinį programos ciklą kaip aprodyta žemiau.
Na ir kaip tai veikia su aprašytu metodu žiūrėkite video.
VI. Pabaiga
Taigi šiame
straipsnyje apžvelgėme ir pasiaiškinome Atmega ADC panaudojimo ypatumus. Nuo
šiol tikiuosi mokėsite pasinaudoti esamu funkcionalumu ir galbūt sukursite
įdomesnių projektų. Visas projekto kodas pateikiamas žemiau. Sėkmės.
Komentarų nėra:
Rašyti komentarą