Analóg perifériák
A fejezet tartalma:
- Analóg jelfeldolgozás
- A FRDM-KL25Z kártya analóg perifériái
- Analóg komparátor
- A ComparatorIn periféria-könyvtár
- Analóg-digitális átalakító (ADC)
- Az AnalogIn periféria-könyvtár
- Digitális-analóg átalakító (DAC)
- Az AnalogOut periféria-könyvtár
Analóg jelfeldolgozás
A körülöttünk levő világ fizikai jellemzői (pl. hőmérséklet, nyomás, szélsebesség) általában folytonosan változó mennyiségek. Az ezeket elektromos jellé alakító érzékelők (szenzorok) kimenőjele a fizikai mennyiséggel analóg (arányos) módon változó folytonos x(t) mennyiség, ahol t az időbeli változásra utal. Mivel e jelek feldolgozását digitális működésű mikrovezérlővel szeretnénk megoldani, szükséges az érzékelőkből bejövő analóg jel mintavételezése és kvantálása (digitalizálása) egy esetleges jelkondicionálás után. A feldolgozás ezután már digitális adatokkal operál. A mintavételezés és kvantálás feladatát az analóg-digitális átalakító (ADC - Analog to Digital Converter) végzi el, amely lehet a mikrovezérlő beépített perifériája, vagy külön beszerezhető külső periféria.Előfordulhat olyan eset, hogy nincs szükségünk a bejövő analóg jel értékének ismeretére (nem kell digitalizálnunk), csupán arra vagyunk kíváncsiak, hogy a bejövő jel nagysága egy kijelölt szintet meghalad-e, vagy sem. Ilyen esetekben a bonyolult működésű ADC helyett egy analóg komparátor (összehasonlító) is megfelel. A legtöbb mikrovezérlő rendelkezik egy vagy több beépített analóg komparátorral, de külső IC-t is használhatunk erre a célra. Az analóg komparátor kimenőjele logikai jel, amelyet a mikrovezérlővel vizsgálhatunk, vagy más perifériák indítására (triggerelés) is felhasználhatjuk.
Ha a jelfeldolgozás eredményeként analóg beavatkozójelet kell előállítanunk, akkor vagy digitális-analóg átalakítót (DAC - Digital to Analog Converter) használunk (amely a mikrovezérlő belső vagy külső perifériája), vagy a PWM fejezetben ismertetett impulzus-szélesség modulációt használjuk, s ha szükséges, egy aluláteresztő jellel "simíthatjuk" a jelet. Természetesen mindkét esetben kvantált, azaz lépcsős lesz a kimenőjel, de kellően finom felbontásnál a "lépcsők" hatása elhanyagolható.
1.
ábra: Analóg világban élünk, de digitális mikrovezérlővel dolgozunk
Az analóg adatgyűjtő ág elemei
- Szenzor: a folytonos fizikai mennyiséget (pl. hőmérséklet, nyomás, szélsebesség) elektromos jellé (feszültség, áram, ellenállás megváltozása) alakító érzékelő
- Jel kondicionálása: a mérendő mennyiség elektromos jellé történő alakítása után még szűrésre, erősítésre, eltolásra, linearizálásra, galvanikus elválasztásra lehet szükség
- Analóg-digitális átalakító (ADC): a mérendő jelet kvantálja, a mérendő jellel arányos digitális számmá alakítja
2.
ábra: Az analóg adatgyűjtő ág elemei
Az analóg beavatkozó ág elemei
- Digitális-analóg átalakító: a digitális számokkal arányos jelet állít elő DAC vagy PWM segítségével
- Jel kondicionálása: terhelhetőséget növelő erősítő vagy szűrés/integrálás (PWM esetén)
A FRDM-KL25Z kártya analóg perifériái
A FRDM-KL25Z kártya az alábbi analóg perifériákkal rendelkezik:Analóg komparátor: amelynek az invertáló és neminvertáló bemenete egy-egy analóg multiplexer segítségével 6 külső kivezetés, illetve 1 belső referencia közül választható ki. A belső referencia egy 6 bites DAC kimenete.
Analóg-digitális átalakító: amely 16 bites felbontású, fokozatos megközelítés elvén működő (SAR), s a mérendő csatorna két differenciális, vagy legfeljebb 14 db single-ended bemenet közül választható ki.
Digitális-analóg átalakító: amely 12 bites felbontású, s amelynek kimenőjele kivezethető (PTE30), vagy valamelyik periféria rendelkezésére bocsátható referencia jelként (pl. Analóg komparátor, ADC).
Az alábbiakban részletesen ismertetjük ezen perifériák felépítését, illetve használatát.
Analóg komparátor
Az analóg komparátor a műveleti erősítőkhöz hasonlóan egy invertáló (Vin-) és egy neminvertáló (Vin+) bemenettel rendelkezik, s kimenete logikai '1', ha a neminvertáló bemenetre kapcsolt feszültség nagyobb, mint az invertáló bemenetre kapcsolt feszültség, egyébként pedig logikai '0'.3.
ábra: Az analóg komparátor működésének szemléltetése állandó Vin-
jelszint esetén
Az MKL25Z128VLK4 mikrovezérlő analóg komparátorának blokkvázlata a 4. ábrán látható. A komparátor neminvertáló (INP) és invertáló (INM) bemenetei egy-egy analóg multiplexer segítségével rendelhetők kivezetésekhez, vagy belső referenciához. A belső referencia lehet a komparátor modulhoz tartozó 6 bites DAC, vagy a 12 bites DAC kimenőjele. A legegyszerűbb, folyamatos üzemmódon kívül lehetőség van a kimenőjel mintavételezésére, (digitális) szűrésére és invertálására is. A kimenőjel kivetéshez rendelhető (PTC0, PTC5, PTE0 valamelyike), vagy a belső perifériák indítására (triggerelés), illetve programmegszakítás keltésére használható.
4.
ábra: Az MKL25Z128VLK4 mikrovezérlő analóg komparátorának blokkvázlata
A ComparatorIn periféria-könyvtár
Az analóg komparátor használatát a standard mbed API nem támogatja, külön programkönyvtárt kell készíteni vagy beszerezni hozzá. Az alábbiakban a Frank Vannieuwkerke által készített és közzétett ComparatorIn periféria-könyvtár használatát mutatjuk be.A ComaparatorIn objektumosztály az analóg komparátor konfigurálására és kezelésére szolgál. Az alábbi táblázatban csak a legfontosabb tagfüggvényeit foglaltuk össze. A részletes dokumentáció a ComparatorIn periféria-könyvtár honlapján található.
1. táblázat: A ComparatorIn objektumosztály legfontosabb tagfüggvényei
Függvény |
Használat |
---|---|
ComparatorIn
név(pinP, pinM) |
Létrehoz egy "név" nevű ComparatorIn objektumot és a
pinP paraméterrel megadott kivezetést a neminvertáló, a pinM
paraméterrel megadott kivezetést az invertáló bemenethez rendeli. |
OutputPin(pin) |
A komparátor kimenetének
hozzárendelése a megadott kivezetéshez |
treshold(float t) |
A belső referenciaforrást
t*VREFH értékre állítja (t: 0-1.0 közötti float érték, VREFH pedig a
kártyán beállított (általában 3.3V) analóg referencia értéke. |
rising(*fptr) |
A felfutáshoz tartozó
megszakítást engedélyezi és visszahívási függvényt rendel hozzá (*fptr:
függvény pointer) |
falling(*fptr) |
A lefutáshoz tartozó megszakítást engedélyezi és visszahívási függvényt rendel hozzá (*fptr: függvény pointer) |
status() |
A komparátor kimeneti
állapotának lekérdezése (0: ha VinP < VinM, 1: ha VinP > VinM) |
2.
táblázat: Az analóg komparátor bemeneteihez rendelhető kivezetések
Kivezetés | Csatorna | Funkció | Megjegyzés | |
---|---|---|---|---|
PTC6 | 000 | IN0 | CMP0_IN0 | |
PTC7 | 001 | IN1 | CMP0_IN1 | |
PTC8 | 010 | IN2 | CMP0_IN2 | |
PTC9 | 011 | IN3 | CMP0_IN3 | |
PTE30 | 100 | IN4 | CMP0_IN4 | 12-bit DAC kimenet |
PTE29 | 101 | IN5 | CMP0_IN5 | |
110 | IN6 | 1V internal Bandgap* | ||
NC | 111 | IN7 | belső 6-bites DAC |
* Még nincs implementálva!
Speciális kivezetések:
- NC - ez a név azt jelzi, hogy a belső referenciaforrást (6 bites DAC) rendeljük a bemenethez
- PTE30 - ez a kivezetés egyúttal a 12 bites DAC kimenete
Mintapélda: az analóg komparátor használata
Az alábbi programban az analóg komparátor működését vizsgáljuk. A mikrovezérlő PTE29 kivezetését rendeljük az analóg komparátor neminvertáló bemenetéhez, s erre a bemenetre egy fotoellenállásból és egy 10 kΩ-os ellenállásból kialakított osztó közös pontját kötjük (lásd 5. ábra). Az általunk használt kadmiumszulfid (CdS) fotoellenállás ellenállása megvilágított állapotban kicsiny (100 Lux esetén kb. 3 kΩ), sötét állapotban viszont nagy (akár 100-300 kΩ is lehet).Az analóg komparátor invertáló lábát a mikrovezérlő PTE30 kivezetéséhez rendeljük. Ez a kivezetés egyúttal a 12 bites DAC kimenete is, tehát az analóg komparátor referencia feszültségét (a komparátor viszonyítási szintjét) a DAC segítségével állíthatjuk be.
A programban a referencia feszültséget 1 V-ra állítjuk. Megvilágított állapotban a fotoellenállás ellenállása kicsiny, a PTE29 lábra csatlakoztatott feszültség kisebb lesz, mint a beállított 1 V-os küszöb, a komparátor nem billen, kimenetén '0' érték olvasható. Eltakart állapotban, vagy sötét környezetben a fotoellenállás ellenállása megnövekszik, így az analóg komparátor neminvertáló bemenetére (esetünkben PTE29) jutó jel feszültsége meghaladja az 1 V-os referencia feszültséget. A komparátor állapota átbillen, a kimenetén '1' logikai szint olvasható.
A programban a komparátor kimenetének vizsgálatára kétféle módszert is mutatunk:
- A komparátor állapotát a status() tagfüggvény hívásával kérdezzük le (polling)
- Az analóg komparátor állapotváltásaival programmegszakításokat is kiválthatunk. Engedélyezésükhöz a megfelelő megszakítási eseményhez visszahívási (callback) függvényt kell rendelni. A felfutó élhez (amikor '1' állapotba billen a kimenet) tartozó megszakításhoz a rising() tagfüggvénnyel, a lefutó élhez (amikor a komparátor kimenete '0'-ba billen) pedig a falling() tagfüggvénnyel.
Megszakítás szinten minden állapotváltáskor a megfelelő visszahívási függvény (cmp_rise_ISR, vagy cmp_fall_ISR) meghívásra kerül, s a zöld LED kigyullad, vagy kialszik).
Van a programnak még egy érdekessége: a mikrovezérlő PTE29-es kivezetését nem csak az analóg komparátor, hanem az analóg-digitális átalakító (ADC) egyik bemenetéhez is hozzárendeljük, így az 5. ábrán látható osztó feszültségét meg tudjuk mérni és a kapott értéket ki tudjuk íratni.
A program működése összefoglalva:
- Ha a CdS ellenállást fény éri, akkor az osztón mért feszültség alacsonyabb, mint a beállított küszöb. A komparátor nem billen be, s a zöld LED nem világít.
- Ha CdS ellenállást beárnyékoljuk, akkor az osztón mért feszültség magasabb lesz, mint a beállított küszöb. A komparátor bebillen, a kimeneten a "Treshold reached" üzenet jelenik meg, a zöld LED világít.
Hardver követelmények:
- FRDM-KL25Z kártya
- CdS fotoellenállás a PTE29 bemenet és a GND közé, 10 kΩ-mal tápfeszültségre húzva az 5. ábra szerint
5. ábra: Analóg jel előállítása CdS fotoellenállás és egy 10 kΩ-os ellenállás felhasználásával
1.
lista: A 05_comparator_demo/main.cpp program listája
/** 05_comparator_demo
* Based on library ComparatorIn and example program ComparatorIn_demo
* written by Frank Vannieuwkerke
* Link: https://developer.mbed.org/users/frankvnk/code/ComparatorIn_demo/
*/
#include "mbed.h"
#include "ComparatorIn.h"
DigitalOut blinker(LED_BLUE); // blinking LED
DigitalOut cmpled(LED_GREEN); // signing comparator status
AnalogIn cmp_lvl(PTE29); // ADC input to check comparator input
ComparatorIn compi(PTE29, PTE30); // in+ = PTE29, in- = 12-bit DAC
// Comparator interrupt callback functions
void cmp_rise_ISR(void)
{
cmpled = 0; // LED ON at rising edge
}
void cmp_fall_ISR(void)
{
cmpled = 1; // LED OFF at falling edge
}
int main()
{
cmpled = 1; // LED OFF at the beginning
compi.rising(&cmp_rise_ISR); // Set pointer to rising interrupt function
compi.falling(&cmp_fall_ISR); // Set pointer to falling interrupt function
compi.treshold(0.3); // Set comparator threshold to 1V = 0.3 * 3.3V
while(1)
{
printf("Light sensor : %7.5f Volt\n",cmp_lvl*3.3);
blinker = 1; // binking LED OFF
wait(2); // wait for 2 sec
blinker = 0; // blinking LED ON
wait(0.2);
if (compi.status() == 0x01) // poll comparator status
{
printf("*** Treshold reached : %7.5f\n",cmp_lvl*3.3);
}
}
}
A blinker
nevű digitális kimenetet a kék LED-hez rendeltük. Ennek felvillanásai
jelzik, hogy mikor vizsgáljuk szoftveresen a komparátor kimenetét. A
működéshez természetesen nincs szükség erre a LED-re.A cmpled nevű digitális kimenetet a zöld LED-hez rendeltünk. Ezt a LED-et az analóg komparátor megszakításai kapcsolgatják (felfutó élre bekapcsol, lefutó élre kikapcsol).
A kártya PTE29 kivezetését egyidejűleg két eszköz bemenetéhez is hozzárendeljük: az analóg komparátor neminvertáló bemenetéhez és az ADC bemenetéhez. Ez utóbbira cmp_lvl (komparátor jelszint) néven hivatkozhatunk lekérdezéskor. A PTE29 kivezetésre kapcsolt feszültség (az 5. ábrán bemutatott osztó jele) tehát működteti az analóg komparátort és ugyanakkor meg tudjuk mérni az ADC segítségével.
Az analóg komparátort kezelő objektumot compi néven definiáltuk, ezzel a névvel hivatkozhatunk rá.
A cmp_rise_ISR és cmp_fall_ISR nevű függvényeket azért definiáltuk, mert ezeket fogjuk meghívatni az analóg komparátor megszakításaiból. A hozzárendeléseket a compi.rising(), illetve compi.falling() tagfüggvények hívásával végezhetjük el, nem feledve, hogy ezek paramétere függvénymutató, tehát paraméterként a függvény neve elé egy '&' jelet kell írnunk. A LED kapcsolgatásánál pedig tartsuk észben, hogy a közös anódú LED-ek a megfelelő katód lehúzására világítanak ('0' szint a kimeneten)!
A komparálási szint a compi.treshold() tagfüggvény hívásával állítható be, melynek paramétere 0.0 - 1.0 közötti szám, s a VREFH analóg referencia-feszültség megfelelő hányadát jelenti.
Megjegyzés: a VREFH referencia-feszültség tényleges értéke a FRDM-KL25Z kártya verziójától és konfigurálásától függ:
- A régebbi kiadású (Rev D) kártyánál a tápellátó ágba kötött D1 dióda miatt 3,3 V helyett 2,9 V körüli volt a tápfeszültség és VREFH értéke is. A D1 dióda áthidalásával a feszültség 3,3 V-ra állítható.
- Az újabb kiadású (Rev E) kártyánál a tápellátó ágban található D12 dióda áthidalható a J20 átkötéssel, ekkor a tápfeszültség és VREFH értéke is 3,3 V lesz.
- Átforrasztással lehetőség van az Arduino kártyához hasonló módon külső analóg referenciaforrás használatára (ennek részleteit a FRDM-KL25Z kártya dokumentációjából kell kideríteni).
- További lehetőség az újabb kiadású kártyáknál az, hogy a D9 Zener dióda (3,0V), az R77 ellenállás (1k) beforrasztása és az R80 rövidzár eltávolítása után 3,0 V lesz VREFH értéke.
A fenti programnál azt feltételezzük, hogy a kártya verziójától (Rev D, vagy Rev E) függően az 1. vagy a 2. pont választásával a VREFH értékét 3,3 V-nak állítottuk be. A programban szereplő compi.treshold(0.3) beállítással a komparálási szint 0,3 * 3,3 V azaz kb. 1 V lesz.
A printf kiíratás az alapértelmezett stdio-ra, az UART0 soros portra történik, amely az OpenSDA által biztosított USB-UART protokoll konverteren keresztül kommunikál a számítógéppel.
A cmp_lvl objektumra történő hivatkozás a cmp_lvl.read() tagfüggvény hívás rövidített változatának felel meg, ami egy-egy ADC konverziót indít és annak eredményével tér vissza. A visszatérési érték 0 - 1.0 közötti érték, amely a mért feszültséget a VREFH megfelelő hányadaként fejezi ki. Ha a mért feszültséget Voltban akarjuk kifejezni, akkor szorozzuk meg a kapott értéket 3,3V-tal, VREFH értékével.
Analóg-digitális átalakító (ADC)
Az MKL25Z128VLK4 mikrovezérlő analóg-digitális átalakítója (ADC) lehetővé teszi, hogy a bejövő analóg feszültséget 65536 jelszintet megkülönböztetni tudó eszközzel a bejövő jel nagyságával arányos 16 bites számmá konvertáljuk (differenciális bemenet használata esetén előjeles eredményt kapunk, aszimmetrikus bemenet esetén pedig előjel nélkülit). Az elektronikában különféle elven működő ADC-ket használnak, amelyek sebességben, pontosságban és természetesen az árukban is jelentősen eltérnek egymástól.Az MKL25Z128VLK4 mikrovezérlő analóg-digitális átalakítója a fokozatos megközelítés (successive approximation, SAR) elvén működik. E módszer lényege a következő: a mintavételezett jelet először összehasonlítjuk a referenciafeszültség felével. Ha a vizsgált jel ennél nagyobb, akkor a legmagasabb helyiértékre 1-et, különben pedig 0-át írunk. A következő lépésben a referenciafeszültség azon tartományát felezzük meg, amelyikbe a bemenő jel az előző vizsgálatnál esett. Tehát ha az első vizsgálatnál a referencia feszültség felénél kisebb volt a vizsgált jel, akkor a második lépésben a referenciafeszültség negyedével hasonlítjuk össze, ellenkező esetben pedig a referenciafeszültség háromnegyedével. Ha a bejövő jel nagyobb volt, mint az összehasonlításhoz használt jel, akkor a soron következő helyiértékre 1-et írunk, különben pedig 0-át. Az eljárást tovább folytatva, tizenhat lépésben megkapjuk a 16 bites eredményt. Ezt a digitalizálási folyamatot a továbbiakban konverziónak hívjuk.
Az ADC előtt a beépített többcsatornás analóg multiplexerek segítségével választhatjuk ki a megmérni kívánt analóg jel bemenetét. A kiválasztást léptethetjük is, így többcsatornás analóg adatgyűjtőt is kialakíthatunk, természetesen az egyes csatornákat csak egymás után, nem pedig egyidejűleg konvertálhatjuk. Az MKL25Z128VLK4 mikrovezérlő analóg-digitális átalakítója bemenetén található analóg multiplexerek segítségével elvileg 4 differenciális vagy 24 aszimmetrikus (single-ended) bemenet közül választhatunk, a gyakorlatban azonban csak két differenciális, vagy legfeljebb 14 db single-ended mérőcsatorna közül választhatunk (a többi bemenet nincs kivezetve). Az ADC differenciális bemenetű csatornái a 3. táblázatban, az aszimmetrikus bemenetű csatornái pedig a 4. táblázatban felsorolt kivezetéseken érhetők el.
3. táblázat: Az ADC differenciális csatornáinak elérhetősége
Kivezetés |
ADC csatorna |
Funkció |
---|---|---|
PTE20 |
ADC0_DP0 |
ADC 0. differenciális csatorna +
ága |
PTE21 |
ADC0_DM0 |
ADC 0. differenciális csatorna - ága |
PTE22 |
ADC0_DP3 | ADC 3. differenciális csatorna + ága |
PTE23 |
ADC0_DM3 | ADC 3. differenciális csatorna - ága |
Kivezetés |
ADC csatorna |
Arduino |
Megjegyzés |
---|---|---|---|
PTE20 |
ADC0_SE0 |
Arduino kompatibilis csatlakozón
nem érhető el! |
|
PTE21 |
ADC0_SE4a | Arduino kompatibilis csatlakozón nem érhető el! | |
PTE22 |
ADC0_SE3 | Arduino kompatibilis csatlakozón nem érhető el! | |
PTE23 |
ADC0_SE7a | Arduino kompatibilis csatlakozón nem érhető el! | |
PTE29 |
ADC0_SE23 | Arduino kompatibilis csatlakozón nem érhető el! | |
PTE30 |
ADC0_SE4b | Ugyanide csatlakozik a DAC
kimenete is! |
|
PTB0 |
ADC0_SE8 | A0 |
Arduino kompatibilis analóg
csatorna |
PTB1 |
ADC0_SE9 | A1 |
Arduino kompatibilis analóg csatorna |
PTB2 |
ADC0_SE12 | A2 |
Arduino kompatibilis analóg csatorna |
PTB3 |
ADC0_SE13 | A3 |
Arduino kompatibilis analóg csatorna |
PTC0 |
ADC0_SE14 | Arduino kompatibilis csatlakozón nem érhető el! | |
PTC1 |
ADC0_SE15 | A5 |
Arduino kompatibilis analóg csatorna |
PTC2 |
ADC0_SE11 | A4 |
Arduino kompatibilis analóg csatorna |
PTD1 |
ADC0_SE5b | D13 |
Az Arduinonál ez digitális
csatorna |
PTD5 |
ADC0_SE6b | D9 |
Az Arduinonál ez digitális csatorna |
PTD6 |
ADC0_SE7b | Arduino kompatibilis csatlakozón nem érhető el! |
Az MKL25Z128VLK4 mikrovezérlő analóg-digitális átalakítójának blokkvázlata az alábbi ábrán látható. A bonyolult felépítés sokféle üzemmódot tesz lehetővé, de ennek részleteivel itt nem foglalkozunk. Az mbed API standard periféria-könyvtára ugyanis az ADC-nek csupán a legegyszerűbb üzemmódját támogatja.
6. ábra: Az ADC blokkvázlata
Az AnalogIn periféria-könyvtár
Az AnalogIn objektumosztály az ADC konfigurálására és kezelésére szolgál. Mivel része a standard mbed API-nak, így nem kell külön importálni.5. táblázat: Az AnalogIn objektumosztály legfontosabb tagfüggvényei
Függvény |
Használat |
---|---|
AnalogIn név(pin) |
Létrehoz egy "név" nevű AnalogIn objektumot és a pin paraméterrel megadott
kivezetést az ADC egyik analóg bemeneteként konfigurálja. |
read() |
Egy
konverziót indít, majd visszatér az eredménnyel. A visszatérési érték 0
- 1.0 közötti float érték, amely a mért feszültséget a VREFH
analóg referencia megfelelő hányadaként fejezi ki. Ha a mért
feszültséget Voltban akarjuk kifejezni, akkor szorozzuk meg a kapott
értéket VREFH értékével (a
tápáramkör D1, vagy D12 diódájának áthidalása esetén ez
3,3 V). |
read_u16() |
Egy konverziót indít, majd visszatér az eredménnyel. A visszatérési érték 0 - 0xFFFF közötti uint16 érték, amely a mért feszültséget VREFH/65536 egységekben fejezi ki. |
operator
float() |
Rövidített alak read() helyett |
Mintapélda: Analóg
hőmérő használata
Az alábbi programban egy Microchip MCP9700A analóg hőmérő
kimenő feszültségét mérjük meg az ADC segítségével, s az eredményt az
alapértelmezett stdio
kimenetre (az UART0 soros
portra) kiíratjuk. Az MCP9700A analóg hőmérő az alábbi paraméterekkel rendelkezik:
- Tápfeszültség tartomány: 2,5 V - 5,5 V
- Tokozás: TO-92 (bekötési rajza a 7. ábrán látható)
- Széles hőfoktartományban képes mérni: -40°C - +150°C
- Nagy pontosságú hőmérséklet-feszültség
konverzió: max. ± 2 °C a 0 -70 °C tartományban - -2°C/+6°C pontosság a teljes mérési tartományban
(-40°C-től +150°C-ig)
- Lineáris hőmérsékletfüggés: 0 °C-on 500 mV,
25 °C-on 750 mV,
meredekség = 10mV/°C - Kis áramfelvétel: tipikusan 12 µA
- Nem igényel kiegészítő alkatrészt
Hardver követelmények:
- FRDM-KL25Z kártya
- MCP9700A analóg hőmérő a 8. ábra szerint bekötve
2. lista: A 05_analog_thermometer/main.cpp program listája
#include "mbed.h"
AnalogIn ain(A0); // Analog input at PTB0
int main()
{
printf("\r\n05_analog_thermometer program\r\n");
while(1) {
uint16_t raw = ain.read_u16(); // read raw 16-bit data
float voltage = ain.read()*3300; // read voltage in millivolts
float tempC = (voltage -500)/10; // tempereature in Celsius
printf("ADC: 0x%04X voltage: %5.0f temp: %5.1f C\r\n",raw,voltage,tempC);
wait(2);
}
}
A programban két másodpercenként kiíratjuk a nyers, 16 bites adatokat (hexadecimálisan), továbbá a feszültségre átszámolt értéket (mV-okban) és a hőmérő karakterisztikája alapján kiszámolt hőmérsékletet is (Celsius fokokban). A program futási eredménye a 9. ábrán látható.
9. ábra: A 05_analog_thermometer program futási eredménye
Mintapélda: Analóg hőmérő átlagolással
Ha megnézzük az előző program futási eredményét a 9. ábrán, akkor láthatjuk, hogy az egyes mérések szórása (ingadozása) nagy. Az alábbi programban ezért pontonként több mérést végzünk, s az eredményeket átlagoljuk, hogy az elektromos zavarjelek okozta ingadozásokat a kiátlagolás révén lecsökkentsük.Az átlagolásra több lehetőségünk is van: hardveres és szoftveres átlagolás.
Hardveres átlagolás: az MKL25Z128VLK4 mikrovezérlő analóg-digitális átalakítója hardveresen is támogatja az ADC mérések átlagolását (több mérést végez, s a mérések átlagát adja meg eredményül). Az ADC SC3 vezérlőregiszterének AVGE bitjének '1'-be állítása engedélyezi az átlagolást, s az SC3 regiszter kétbites AVGS bitcsoportja szabja meg, hogy hány mérést átlagoljunk (00: 4, 01: 8, 10: 16, 11: 32 minta átlagolása). Alapértelmezetten az AnalogIn objektumok lekérdezésekor 4 mérés átlagát kapjuk. Az alábbi utasítás beszúrásával (célszerűen a main() függvény elején) az előző programban a hardveres átlagolást átállíthatjuk 32-re.
ADC0->SC3 = ADC_SC3_AVGE_MASK // Hardware Average Enable
| ADC_SC3_AVGS(3); // 32 Samples Averaged
Szoftveres átlagolás: A következő programban az átlagolást 16 bites nyers adatokon végezzük, hogy elkerüljük a lebegőpontos (float) számábrázolásból adódó hibák felhamozódását és a lebegőpontos műveletek miatti többletszámolást (a lebegőpontos műveleteket csak a Cortex-M4F kategóriájú mikrovezérlők képesek hatékonyan elvégezni). Az összegzéshez egy 32 bites előjel nélküli változót deklarálunk mysum néven.
Az átlagolás általában úgy történik, hogy nullázzuk az összegzésre használt változót, majd n darab mérés eredményét hozzáadjuk, s végül az eredményt n-nel elosztjuk. Nekünk viszont a feszültség kiszámításához az átlagértéket 3300-zal meg kell szorozni (ez VREFH értéke mV-okban), majd a kapott eredményt 216 = 65536-tal el kell osztani.
Vegyük észre, hogy ha 3300 mintavétel eredményét adjuk össze, akkor az n = 3300-zal történő osztás, majd az azt követö 3300-zal történő szorzás megtakarítható! A 216 = 65536-tal történő osztás pedig 16 bináris helyiértékkel történő jobbraléptetéssel elvégezhető. A jobbraléptetés műveleti jele a C nyelvben ">>".
3. lista: A 05_analog_thermometer2/main.cpp program listája
#include "mbed.h"
AnalogIn ain(A0); // Analog input at PTB0
uint32_t mysum; // Used for summation
int main()
{
printf("\r\n05_analog_thermometer2 - with averaging\r\n");
while(1) {
mysum = 0;
for(int i=0; i<3300; i++) {
mysum += ain.read_u16(); // sum up raw 16-bit data
}
float voltage = mysum>>16; // voltage in millivolts
float tempC = (voltage -500)/10; // tempereature in Celsius
printf("voltage: %5.0f mV temp: %5.1f C\r\n",voltage,tempC);
wait(2);
}
}
A nyers értékekekt ebben a programban nem íratjuk ki, csak az átlagértékből kiszámolt feszültség és hőmérséklet adatokat. A program futási eredménye a 10. ábrán látható.
10. ábra: A 05_analog_thermometer2 program futási eredménye
Látható, hogy a nagyszámú mintavételből átlagolt eredmények már nem ingadoznak. Változás csak az utolsó három adatnál észlelhető, amikor "kézrátétellel" melegíteni kezdtük a hőmérőt.
Mintapélda: Az ADC extra funkcióinak használata
Az alábbi programban bemutatjuk, hogy hogyan használhatjuk az ADC belső
csatornáit a beépített hőmérő és a megmérésére. megmutatjuk, hogy
az ADC belső hőérzékelőjének kiválasztásával (az ADC 26-os csatornája) hogyan mérhetünk hőmérsékletet, s hogyan mérhetjük meg a beépített bandgap referencia feszültségét (ADC 27-es csatorna). Egyúttal bekapcsoljuk a 32 mintából történő hardver átlagolást is.Az ADC kezeléséhez nem írtunk teljes inicializálást végző eljárást, csupán felülírjuk az mbed API AnalogIn konstruktor függvényének inicializálását (csak azokat a regisztereket írjuk felül, amelyeket módosítani akarunk). Ezért fontos, hogy ne felejtsük ki az AnalogIn objektumosztály példányosítását mindazon analóg bemenetekre, amelyeket használni akarunk, s amelyek fizikai kivezetéshez rendelhetők. A beépített hőmérő és a bandgap referencia nincs kivezetve, ezért ezeket nem kell külön inicializálni, ellenben a bandgap referenciát be kell kapcsolnunk a PMC->REGSC regiszter BGBE bitjének 1-be állításávan (alapértelmezetten nincs bekapcsolva).
Az ADC inicializálás felülírásához és az extra csatornák kiolvashatóságához készítettünk egy adc_read() függvényt. A változtatások lényege:
- Az ADC0->SC3 regiszter módosításával 32 mintavételes hardver átlagolást írunk elő. Ennek részletei (AVGE bit = 1, AVGS bitek = 3) a Freescale KL25xx Reference Manual (KL25P80M48SF0RM.pdf) 28.3 alfejezetéből olvasható ki.
- Az ADC0->SC1[0] regiszter (a fent említett dokumentum jelölése szerint SC1A regiszter) beírása indítja a konverziót. Ebben a regiszterben kell megadnunk a kiolvasandó csatorna sorszámát.
- A konverzió elindítása után blokkoló várakozást indítunk, amelyben az ADC0->SC1[0] regiszter COCO bitjét vizsgáluk. Amikor ez a bit 1-be vált, akkor van vége a mérésnek, s a 16 bites eredményt az ADC0->R[0] regiszterból olvashatjuk ki.
- Az adc_read() függvény paramétereként meg kell adnunk a mérendő ADC csatorna sorszámát. Az A0 (PTB0) bemenetre adott jel a 8-as számú csatornában, a belső hőmérő jele a 26-es csatornában, a bandgap referencia feszültsége pedig a 27-es csatornában mérhető.
A belső hőmérő jelének feldolgozását a Freescale KL25xx Reference Manual (KL25P80M48SF0RM.pdf) 28.4.8 alfejezete ismerteti:
Temp = 25 - (VTemp - V25)/m
ahol V25 a 25 ºC-on mért feszültség (kb. 716 mV), m pedig a meredekség (kb. 1620 µV/ºC)
Azt ne feledjük, hogy a belső hőmérő mindig a lapka hőmérsékletét méri, ami a mikrovezérlő pillanatnyi fogyasztásától függően több fokkal is magasabb lehet a környezeti hőmérsékletnél.
Hardver követelmények:
- FRDM-KL25z kártya
- Analóg jel az A0 (PTB0) bemeneten
#include "mbed.h"
AnalogIn adc(A0);
uint16_t adc_read(uint32_t ch) {
ADC0->SC3 = ADC_SC3_AVGE_MASK // Hardware Average Enable
| ADC_SC3_AVGS(3); // 32 Samples Averaged
// start conversion
ADC0->SC1[0] = ch;
// Wait Conversion Complete
while ((ADC0->SC1[0] & ADC_SC1_COCO_MASK) != ADC_SC1_COCO_MASK);
// Return value
return (uint16_t)ADC0->R[0];
}
int main() {
/*
* The v25 value is the voltage reading at 25C, it comes from the ADC
* electricals table in the processor manual. V25 is in millivolts.
*/
int32_t v25 = 716;
/*
* The m value is slope of the temperature sensor values, again from
* the ADC electricals table in the processor manual.
* M in microvolts per degree.
*/
int32_t m = 1620;
PMC->REGSC |= PMC_REGSC_BGBE_MASK; //Enable bandgap reference
while (true) {
uint16_t a1 = adc_read(8);
uint16_t a2 = adc_read(26);
uint16_t a3 = adc_read(27);
float v1 = a1*3.3f/65536;
float v2 = a2*3300.0f/65536;
float temp = 25.0f-(v2-v25)*1000.0f/m;
float v3 = a3*3.3f/65536;
printf("A0 = %6.3f V Temp = %5.2f C Bgap = %6.3f V\n",v1,temp,v3);
wait_ms(2000);
}
}
A program futási eredménye az alábbi ábrán látható.11. ábra: A 05_ADC_extra program futási eredménye
Digitális-analóg átalakító (DAC)
Az MKL25Z128VLK4 mikrovezérlő digitális-analóg átalakítója (DAC) 12 bites felbontású, kimenőjele kivezethető (PTE30), vagy valamelyik periféria rendelkezésére bocsátható referencia jelként (pl. analóg komparátor, ADC). Kimenő feszültsége 0 - 3.3V (azaz 0 - VREFH) között 4096 fokozatban változtatható. A DAC blokkvázlata a 12. ábrán látható. DACREF_1 (VREFH) és DACREF_2 (VDDA) választása esetünkben irreleváns, mivela két bemenet a kártyán gyárilag össze van kötve. A két referencia bemenet (VREFH és VDDA) szétválasztása csak forrasztással lehetséges.
12. ábra: A
12-bites DAC blokkvázlata
Az AnalogOut periféria-könyvtár
Az AnalogOut objektumosztály a DAC konfigurálására és kezelésére szolgál. Mivel része a standard mbed API-nak, így nem kell külön importálni.6. táblázat: Az AnalogOut objektumosztály tagfüggvényei
Függvény |
Használat |
---|---|
AnalogOut név(pin) |
Létrehoz egy "név" nevű AnalogOut objektumot és a pin paraméterrel megadott
kivezetést a DAC analóg kimeneteként konfigurálja. Esetünkben a pin
értéke csak PTE30, vagy NC lehet (NC = nincs kapcsolat). |
write(data) |
A DAC kimenetet beállítja a data*VREFH feszültségre. A
paraméter 0
- 1.0 közötti float érték, amely a beállítandó feszültséget a VREFH
analóg referencia megfelelő hányadaként fejezi ki. |
write_u16(data) |
A DAC kimenetét beállítja a data/0xFFFF*VREFH feszültségre. A paraméter értéke 0 - 0xFFFF közötti uint16 érték, amely a mért feszültséget VREFH/65535 egységekben fejezi ki. |
read() |
Visszaolvassa a legutoljára
beállított értéket (0 - 1.0 közötti float érték) |
operator
= data |
Rövidített alak write(data) helyett |
operator
float() |
Rövidített alak read() helyett |
Mintapélda: DAC kimenőfeszültségének léptetése
Oszcilloszkóp híján az alábbi programban 5 másodpercenként léptetjük a DAC kimenő feszültségét, így egy egyszerű voltmérő segítségével ellenőrizhetjük a működést. A lépésköz kb. 0,42 V, ennyivel nő a feszültség minden lépésben, amíg a ciklusban a maximális értéket (esetünkben kb. 2.94 V) el nem érjük.Hardver követelmények:
- FRDM-KL25Z kártya
- Digitális voltmérő a GND és a PTE30 kivezetések közé kötve
5. lista: A 05_dac12_test/main.cpp program listája
#include "mbed.h"
AnalogOut aout(PTE30);
int main()
{
while(1) {
for (uint16_t i = 0; i < 0xffff; i += 0x2000) {
aout.write_u16(i);
wait(5);
}
}
}
A működést a PTE30 kivezetésen
megjelenő feszültség mérésével ellenőrizhetjük.