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
- Az analóg komparátor regiszterkészlete
- Az analóg komparátor programozása
- Analóg-digitális átalakító (ADC)
- Az ADC programozása
- Digitális-analóg átalakító (DAC)
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 impulzus-szélesség modulációt (PWM) használunk, 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.
Megjegyzés: az analóg perifériáknál használt 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.
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
Az analóg
komparátor regiszterkészlete
Az analóg komparátor modul használatba vétele előtt a
rendszer-integrációs modul SIM_SCGC4
regiszterében engedélyezni kell azt. Például:SIM->SCGC4 |= SIM_SCGC4_CMP_MASK; // A komparátor modul engedélyezése
Az analóg komparátor működését az alábbi táblázatban felsorolt
regiszterek szabályozzák. A regiszterek CMSIS nevét megkapjuk,
ha
a regiszter nevében szereplő aláhúzást "->" jelre
cseréljük.
Például: a CMP0_SCR regiszter
CMSIS neve: CMP0->SCR.1. táblázat: Az analóg komparátor regiszterkészlete
Memória cím |
Regiszter név |
Méret |
Elérés |
Reset érték |
---|---|---|---|---|
4007_3000 | CMP0_CR0 Control register 0 (0. vezérlő
regiszter) |
8 bit |
R/W | 00h |
4007_3001 | CMP0_CR1 Control Register 1 (1. vezérlő
regiszter) |
8 bit | R/W | 00h |
4007_3002 | CMP0_FPR Filter Period Register (szűrési
periódus) |
8 bit | R/W | 00h |
4007_3003 | CMP0_SCR CMP Status and Control Register
(állapotjelző és vezérlő regiszter) |
8 bit | R/W | 00h |
4007_3004 | CMP0_DACCR DAC Control Register (DAC
vezérlő) |
8 bit | R/W | 00h |
4007_3005 | CMP0_MUXCR MUX Control Register
(Csatornaválasztó) |
8 bit | R/W | 00h |
CMP0_CR0
vezérlő regiszter
- FILTER_CNT - megadja azt a mintaszámot, amelynek egyeznie kell, mielőtt új kimeneti állapotot fogadnánk el. A 000 megadása illegális, ha a szűrés engedélyezve van (SE = 1).
- HSTCTR - hiszterézis megadása (00: 5 mV, 01: 10 mV, 10: 20 mV, 11: 30mV)
CMP0_CR1
vezérlő regiszter
A mintavételezési mód és az ablakozó mód nem lehet egyidejűleg
engedélyezve, azaz SE
és WE közül egyidejűleg
csak az egyik lehetne 1-be állítva. Az MKL25Z128VLK4
mikrovezérlő esetén azonban az ablakozó mód nincs implementálva,
a
mintavételezési mód pedig csak korlátozottan használható, ezért
az SE és WE biteket egyaránt '0'-ba
kell állítani!- SE - Mintavételezés engedélyezése (0: letiltva, 1: engedélyezve). Az MKL25Z128VLK4 mikrovezérlő esetén a mintavételezési mód csak korlátozottan, belső mintavételezési órajellel használható, csak az SE = 0 beállítás használható!
- WE - ablakozó mód engedélyezése (0: letiltva, 1: engedélyezve). Az MKL25Z128VLK4 mikrovezérlő esetén ez az üzemmód nincs implementálva, ezért csak a WE = 0 beállítás használható!
- TRIGM - Trigger
mód
engedélyezés. Ha 1-be állítjuk ezt a bitet, akkor a
komparátor és a
referencia DAC alvás módba kerül, s csak külső triggerjel
hatására
élednek fel.Az MKL25Z128VLK4
mikrovezérlő esetén a triggerjel az LPTMR időzítő TCF jele, s az indító
impulzusok gyakorisága az LPTMR
beállításaitól függ.
- PMODE - Power mode választás (0: kisfogyasztású, lassú mód, 1: gyors, de nagyobb fogyasztású mód)
- INV - Komparátor invertálás, mely ellenkezőjére változtatja a komparátor kimenetét (0: nincs invertálás, 1: invertált mód)
- COS - Komparátor
kimenőjel választás (0: a szűrt kimenet választása, 1:
szűretlen kimenőjel választása)
- OPE - Kimenet
engedélyezése (0: tiltás, 1: engedélyezés). A komparátor
kimenőjele a PTC0, PTC5,
PTE0 kivezetések valamelyikén jelenhet meg.
- EN - A komparátor egység engedélyezése.
CMP0_FPR
szűrési periódus regiszter
A mintavételezési periódust
adja meg busz órajel periódusokban, ha CMP0_CR1[SE] = 0. A nulla érték a
szűrést letiltja.
CMP0_SCR
állapotjelző és vezérlő regiszter
- DMAEN - Engedélyezi, hogy a komparátor modul DMA átvitelt indítson. Ha ez a bit '1'-be van állítva, DMA kérelem keletkezik, amikor a CFR vagy CFF bit '1'-be billen.
- IER - Megszakítás engedélyezés felfutó élre (0: megszakítás tiltás, 1: megszakítás engedélyezése, amikor CFR '1'-be billen)
- IEF - Megszakítás engedélyezés lefutó élre (0: megszakítás tiltás, 1: megszakítás engedélyezése, amikor CFF '1'-be billen)
- CFR -Felfutó él detektálása a komparátor modul kimenetén (amikor COUT '1'-be billen)
- CFF -Lefutó él detektálása a komparátor modul kimenetén (amikor COUT '0'-ba billen)
- COUT - Ez a csak olvasható bit a komparátor modul pillanatnyi kimeneti állapotát tükrözi. Ha a komparátor le van tiltva (CMP0_CR1[EN]=0), akkor COUT értéke a CMP1_CR1[INV] bit beállított értékével egyezik meg.
CMP0_DACCR DAC vezérlő regiszter
Ezzel a regiszterrel engedélyezhetjük és állíthatjuk be a 6 bites referencia DAC-ot.- DACEN - A 6 bites DAC engedélyezése (0: letiltva és kikapcsolva, 1: engedélyezve)
- VRSEL - A DAC referencia feszültségég kiválasztása (0: VREFH, 0: VDD)
- VOSEL - A DAC kimenőfeszültség beállítása 64 lépésben. VDAC = Vin/64 * VOSEL, ahol Vin értéke vagy VREFH vagy VDD, a VRSEL bit beállításától függően.
CMPx_MUXCR csatornaválasztó regiszter
A komparátor modul két 8 bemenetű analóg csatornaválasztójával (analóg multiplexer) a komparátor invertáló (INM) és neminvertáló (INP) bemenetét külön-külön átirányíthatjuk a kiválasztott bemenetekre. A multiplexerek 8db. közösített bemenete közül kettő belső referenciaforrásokra csatlakozik, 6 db bemenet pedig a mikrovezérlő kivezetéseihez csatlakozik. A kiosztás a 2. táblázatban látható.- PSTM - Pass
through mode (átvezetés) engedélyezés (0: tiltás, 1:
engedélyezés). A MKL25Z128VLK4 mikrovezérlő esetén ez az üzemmód
nincs implementálva, ezért csak a PSTM = 0 beállítás használható!
- PSEL - Az INP (neminvertáló) bemenethez tartozó kivezetés vagy belső jelforrás kiválasztása (a 2. táblázat szerinti csatorna sorszámot kell beleírni)
- MSEL - Az INM (invertáló) bemenethez tartozó kivezetés vagy belső jelforrás kiválasztása (a 2. táblázat szerinti csatorna sorszámot kell beleírni) mikrovezérlő esetén ez a mód nem használható, a PSTM bitet 0-ba kell állítani!
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 Bandgap referencia |
||
111 | IN7 | belső 6-bites DAC |
- Belső
referenciaforrás használatakor (bandgap vagy DAC) a
csatornához nem tartozik külső kivezetés.
- PTE30 - ez a kivezetés egyúttal a 12 bites DAC kimenete.
- A Bandgap referencia használatához engedélyezni kell azt a PMC_REGSC regiszter BGBE bitjének '1'-be állításával. Kisfogyasztású üzemmódokban a Bandgap referencia használatához a PMC_REGSC regiszter BGEN bitjét is '1'-be kell állítani.
Az analóg komparátor programozása
A KL25P80M48SF0RM: Freescale KL2x Reference Manual 29. fejezete részletesen tárgyalja az Analóg Komparátor modult, s a 29.8.1 CMP functional modes alfejezet számos üzemmódot ismertet. Azonban ugyanennek a dokumentumnak a 3.7.2 CMP Configuration alfejezetéből kiderül, hogy a bennünket érdeklő KL25 mikrovezérlő család esetén ezen üzemmódok nincsenek mind implementálva, vagy csak korlátozottan használhatók. Nem használhatók például az ablakozó üzemmódok, s korlátozottan (csak a belső buszfrekvenciával) használható a mintavételező mód.Az alábbi mintapéldában mi csak a legegyszerűbb, folyamatos üzemmódot használjuk. A többi lehetőség felderítését és kipróbálását az olvasóra hagyjuk.
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 belső, 6 bites DAC (digitális-analóg átalakító) kimenetéhez rendeljük, 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 szereplő CMP0->DACCR = 0xD3; beállítással a komparálási szint (19 + 1) * 3,3 V / 64, azaz kb. 1 V lesz. A 0xD3 = 0b1101011 adat felső két bitje a DEC engedélyezésére és a referencia feszültség kiválasztására ('1': VDD) szolgál.
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 főprogramban a CMP0->SCR regiszter CFR (felfutó él) és CFF (lefutó él) állapotjelző bitjeinek vizsgálatával állapítjuk meg, hogy történt-e változás a legutóbbi lekérdezés óta. Változás detektálása esetén a jelzőbitet '1' beírásával törölni kell, s a zöld LED állapotának átkapcsolásával kijelezzük a változást.
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 zöld LED világít.
- 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 comparator_1/main.c program listája
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 VDD, illetve VREFH (alapértelmezetten ezek gyárilag össze vannak kötve a kártyán) értékét 3,3 V-nak állítottuk be./* Comparator_1: analóg komparátor demó
*
* Az analóg komparátor bebillenésekor a zöld LED kigyullad,
* a komparátor visszabillenésekor pedig kialszik.
* Az analóg komparátor INP bemenetét a PTE29 kivezetésre konfiguráljuk,
* az INM referencia bemenet pedig a belso 6-bites DAC-ra kapcsolódik,
* amit kb. 1 V-ra állítunk be.
*/
#include "MKL25Z4.h"
void delayMs(int n);
int main(void) {
//--- LED-ek konfigurálása ----
SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK; // PORTB engedélyezése (zöld LED)
PORTB->PCR[19] = 0x100; // PTB19 legyen GPIO módban
PTB->PDDR |= 0x80000; // PTB19 legyen kimenet
PTB->PCOR = 0x80000; // LED felkapcsolása
delayMs(100);
PTB->PSOR = 0x80000; // LED lekapcsolása
//--- CMP0 konfigurálása -----
SIM->SCGC4 |= SIM_SCGC4_CMP_MASK; // A komparátor engedélyezése
CMP0->CR0 = 0x00; // Filter és hiszterézis letiltva
CMP0->CR1 = 0x17; // Folyamatos mód, gyors mód, nincs kimenet
CMP0->FPR = 0x00; // Szűrés letiltása
CMP0->SCR = 0x06; // Megszakítás letiltása, jelzőbitek törlése
CMP0->DACCR = 0xD3; // DAC engedélyezés és 1V-ra állítás
//--- PTE29 konfigurálása ----
SIM->SCGC5 |= SIM_SCGC5_PORTE_MASK; // PORTE engedélyezése
PORTE->PCR[29] = 0x000; // PTE29 legyen analóg módban
CMP0->MUXCR = 0x2F; // INP: IN5 (PTE29), INM: IN7 (DAC)
delayMs(500);
while(1) {
//--- Felfutó él vizsgálata ---
if((CMP0->SCR & CMP_SCR_CFR_MASK)==CMP_SCR_CFR_MASK) {
CMP0->SCR |= CMP_SCR_CFR_MASK; // Jelzőbit törlése
PTB->PCOR = 0x80000; // LED felkapcsolása
}
//--- Lefutó él vizsgálata ---
if((CMP0->SCR & CMP_SCR_CFF_MASK)==CMP_SCR_CFF_MASK) {
CMP0->SCR |= CMP_SCR_CFF_MASK; // Jelzőbit törlése
PTB->PSOR = 0x80000; // LED lekapcsolása
}
delayMs(5);
}
}
//--------------------------------------------------------------
// Késleltető függvény alapértelmezett órajelhez (20.97152 MHz)
//--------------------------------------------------------------
void delayMs(int n) {
int i, j;
for(i = 0 ; i < n; i++)
for (j = 0; j < 3500; j++);
}
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 legfeljebb 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 független 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 |
Szám |
Arduino |
Megjegyzés |
---|---|---|---|---|
PTE20 |
ADC0_SE0 |
0 |
Arduino kompatibilis csatlakozón
nem érhető el! |
|
PTE21 |
ADC0_SE4a | 4 |
Arduino kompatibilis csatlakozón nem érhető el! | |
PTE22 |
ADC0_SE3 | 3 |
Arduino kompatibilis csatlakozón nem érhető el! | |
PTE23 |
ADC0_SE7a | 7 |
Arduino kompatibilis csatlakozón nem érhető el! | |
PTE29 |
ADC0_SE4b | 4 |
Arduino kompatibilis csatlakozón nem érhető el! | |
PTE30 |
ADC0_SE23 | 23 |
Ugyanide csatlakozik a DAC
kimenete is! |
|
PTB0 |
ADC0_SE8 | 8 |
A0 |
Arduino kompatibilis analóg
csatorna |
PTB1 |
ADC0_SE9 | 9 |
A1 |
Arduino kompatibilis analóg csatorna |
PTB2 |
ADC0_SE12 | 12 |
A2 |
Arduino kompatibilis analóg csatorna |
PTB3 |
ADC0_SE13 | 13 |
A3 |
Arduino kompatibilis analóg csatorna |
PTC0 |
ADC0_SE14 | 14 |
Arduino kompatibilis csatlakozón nem érhető el! | |
PTC1 |
ADC0_SE15 | 15 |
A5 |
Arduino kompatibilis analóg csatorna |
PTC2 |
ADC0_SE11 | 11 |
A4 |
Arduino kompatibilis analóg csatorna |
PTD1 |
ADC0_SE5b | 5 |
D13 |
Az Arduinonál ez digitális
csatorna |
PTD5 |
ADC0_SE6b | 6 |
D9 |
Az Arduinonál ez digitális csatorna |
PTD6 |
ADC0_SE7b | 7 |
Arduino kompatibilis csatlakozón nem érhető el! | |
- |
belső hőmérő |
26 |
csatlakozón nem érhető el | |
- |
1V bandgap referencia |
27 |
csatlakozón nem érhető el | |
VREFH |
29 |
pozitív referencia |
||
VREFL |
30 |
negatív referencia |
||
letiltás |
31 |
Letiltja az ADC modult |
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é, melyek minden részletére nem térünk ki.
6. ábra: Az ADC blokkvázlata
Az ADC programozása
Az ADC engedélyezéseAz ADC használatához először is engedélyezni kell az ADC0 modul órajelét a SIM_SCGC6 regiszter 27. bitjének '1'-be állításával. A SIM_SCGC6 regiszter a rendszer-integrációs modul (SIM) része. Fizikai címe: 0x4004 7000 + 103C = 0x4000 803C.
Az ADC regiszterkészlete
Az ADC terjedelmes regiszterkészletéből csak azokat soroltuk fel, amelyeket a mintapéldákban használni fogunk az ADC üzemmódjában beállítása és a legegyszerűbb üzemmód, a szoftveres triggerelés és lekérdezés módban.
5. táblázat: Az analóg digitális átalakító legfontosabb regiszterei
Memória cím |
Regiszter név |
Reset érték |
---|---|---|
4003_B000 | ADC0_SC1A Status and Control register 1 (1. állapot- és vezérlő reg.) |
0x0000_001F |
4003_B008 | ADC0_CFG1 Configuration Register 1 (1. konfigurációs regiszter) |
0 |
4003_B00C | ADC0_CFG2 Configuration Register 2 (2. konfigurációs regiszter) | 0 |
4003_B010 | ADC0_RA ADC Data Result Register (eredmény regiszter) |
0 |
4003_B020 | ADC0_SC2 Status and Control register 2 (2. állapot- és vezérlő reg.) | 0 |
4003_B024 | ADC0_SC3 Status and Control register 3 (3. állapot- és vezérlő reg.) | 0 |
A konverzió indítására (trigger) két lehetőség közül választhatunk: hardveres vagy szoftveres triggerelés. A kiválasztást az ADC0_SC2 regiszter ADTRG bitjének beállításával tehetjük meg (0: szoftveres triggerelés, 1: hardveres triggerelés). A hardveres indítójel érkezhet kívülről, a komparátorból vagy valamelyik időzítőből. Hogy melyik jelet használjuk fel, azt a SIM_SOPT7 regiszterben választhatjuk ki. Az alapértelmezett a szoftveres triggerelés, mi is ezt fogjuk használni, s az ADC0_SC2 regiszter többi bitjét is alapértelmezett (nulla) állásban hagyjuk. Ebben a regiszterben választhatnánk az analóg referenciák közül (VDDA vagy VREFH), de ennek esetünkben nincs jelentősége, mivel ezek a jelek a FRDM-KL25Z kártyán alapértelmezetten össze vannak kötve.
ADTRG - ADC trigger mód (0: szoftveres triggerelés, 1: hardveres triggerelés)
ACFE - Összehasonlítás mód engedélyezés
ACFGT - Összehasonlítási mód: (0: kisebb mint, 1: nagyobb vagy egyenlő)
ACREN - Összehasonlítási tartomány engedélyezés (0: tiltás, csak a CV1 szint számít, 1: engedélyezés: CV1, és CV2 is számít)
DMAEN - DMA átvitel engedélyezés (0: letiltva, 1: engedélyezve), amikor a konverzió befejeződik.
REFSEL - Referencia választása (00: a VREFH, VREFL lábakra kötött feszültség, 01: a VDDA, VSSA lábakra kötött feszültség a referencia, a többi beállítás érvénytelen)
A mérendő csatorna kiválasztása
A mérendő csatorna sorszámát (lásd pl. a 4. táblázatban a "Szám" oszlopot) az ADC0_SC1A regiszterben kell megadni, az ADCH bitcsoportban.
COCO - Konverzió vége jelzőbit (csak olvasható, az eredmény kiolvasásakor, vagy az ADC0_SC1A regiszter újraírásakor automatikusan törlődik)
AIEN - Programmegszakítás engedélyezése
DIFF - Differenciális mód engedélyezése (0: aszimmetrikus mód, 1: differenciális mód)
ADCH - Mérendő csatorna sorszáma
Megjegyzések:
- Több ADC0_SC1n regiszter is tartozhat a mikrovezérlőhöz, de ezek csak hardveres triggerelés esetén használhatók. Szoftveres triggerelésnél csak az ADC0_SC1A használható.
- CMSIS jelöléssel az ADC0_SC1A regiszter címzése, elérése ADC0->SC[0] névvel történik.
Az ADC konverzió végén, vagy hardveres átlagolás esetén az átlagolási periódus végén az ADC0_SC1A regiszter COCO bitje '1'-be billen. Ennek a bitnek a figyelésével detektálhatjuk, hogy mikor fejeződik be a konverzió, s az eredmény kiolvasható az ADC0_RA regiszterből. A másik lehetőség a megszakítás használata, melynek engedélyezéséhez a ADC0_SC1A regiszter AIEN bitjét '1'-be kell állítani. A megszakítási kérelem az eredmény kiolvasásakor, vagy az ADC0_SC1A regiszter újraírásakor automatikusan törlődik.
Az eredmény kiolvasása
A konverzió (vagy hardveres átlagolás esetén az átlagolási periódus) végén az eredmény az ADC0_RA regiszterbe kerül. Megjegyezzük, hogy az ADC0_SC1n regiszterekhez hasonlóan hardveres triggerelésnél az eredmény regiszterekből is lehet több, de szoftveres indítás esetén csak az ADC0_RA regiszter áll rendelkezésre. Ennek CMSIS elnevezése ADC0->R[0].
Az eredmény regiszter 32 bites, de csak az alsó 16 bit van használatban. Kisebb (8, 10, 12 bites) felbontás használata esetén az eredmény jobbra igazítva kerül elhelyezésre. Ha az eredmény előjeles (differenciális módban), akkor a regiszter nem használt bitjei előjel kiterjesztéssel lesznek feltöltve (nem negatív szám esetén nullával, negatív szám esetén 1-gyel).
A felbontás beállítása
Az MKL25Z128VLK4 mikrovezérlő analóg-digitális átalakítója többféle felbontással is használható (a kisebb felbontású módok előnye a gyorsabb konverzió). Az ADC0_CFG1 regiszter segítségével választhatjuk meg a felbontást. Ugyanez a regiszter szolgál az ADC órajel forrásának kiválasztására és az esetleges leosztás beállítására.
ADIV - ADC órajel leosztás (2ADIV-szoros leosztás)
ADLSMP - mintavételezési idő (0: rövid mintavételezés, 1: nyújtott idejű mintavételezés)
MODE - ADC felbontás beállítása (00: 8-bit, 01: 12-bit, 10: 10-bit, 11: 16-bit, differenciális módban pedig előjeles 00: 9-bit, 01: 13-bit, 10: 11-bit, 11: 16-bit)
ADICLK - órajel forrás kiválasztása (00: busz órajel, 01: busz órajel / 2, 10: Alternatív órajel (ALTCLK), 11: saját órajel (ADACK)
Az órajel forrásának és leosztásának megválasztásánál arra kell törekedni, hogy:
- az órajel rendelkezésre álljon az adott körülmények között is (pl. mérés energiatakarékos módban),
- frekvenciája az adatlap 25. táblázatában megadott határok között legyen (pl. 16 bites módban 2 - 12 MHz közötti érték legyen).
MUXSEL - ADC multiplexer választás (0: az xxa csatornákat, 1: az xxb csatornákat választja ki)
ADACKEN - Az ADC beépített aszinkron órájának (ADICLK) engedélyezése
ADHSC - Nagysebességű konfiguráció (0: normál mód, 1: nagysebességű módban két ADCK ciklussal meghosszabbítja a mintavételi időt)
ADLSTS - Hosszabb mintavételi idő beállítása, amikor az ADC0_CFG1 regiszter ADLSMP bitje '1'-be van állítva (00: 20, 01: 12, 10: 6, 11: 2 ADCK ciklussal nyújtja meg a mintavételi időt)
A mintavételi idő és a konverzió teljes ideje
Az ADC-vel úgy történik a mérés, hogy a kiválasztott csatorna analóg jelével egy egységnyi erősítésű buffer erősítő feltölti a mintavevő-tartó áramkör kondenzátorát, majd az ADC leválasztja a feltöltött kondenzátort la bemenetről, s fokozatos megközelítéssel meghatározza a mintavételezett feszültség értékét. A pontos mérés érdekében a mintavételezési időnek kellően hosszúnak kell lennie (hogy a kondenzátor feszültsége minél pontosabban beálljon a bejövő feszültségre), a konverziónak pedig lehetőleg gyorsnak kell lennie (hogy a mintavevő-tartó áramkör kondenzátorának önkisülése ne rontsa le a mérés pontosságát).
A mintavételezési idő alapértelmezetten 4 ADCK ciklus, ami meghosszabbítható, ha az ADC0_CFG1 regiszter ADLSMP bitje '1'-be van állítva. Az ADC0_CFG2 regiszter ADLSTS bitcsoportjának beállításával további 2, 6, 12, vagy 20 ADCK ciklussal hosszabbíthatjuk meg a mintavételezés idejét. Az ADHSC bit '1'-be állításával további 2 ADCK ciklussal növelhetjük meg a mintavétel idejét. Az egyedi méréseknél, vagy folyamatos módú konverziónál az első mérés esetében további 2 ADCK ciklussal lesz megnövelve a mintavételi idő.
A szűken vett konverzió idejét (amin a mintavételezett jel értékének számszerűsítését értjük) az ADC órajelének frekvenciája szabja meg, amit az ADC0_CFG1 regiszter ADIV és ADICLK bitcsoportjai szabályoznak. A Freescale KL2x Reference Manual 28. fejezetében ez a BCT-vel jelölt időtartam (BCT = Base Conversion Time) aszimmetrikus jelnél felbontástól függően 17 - 25 ADCK ciklus, míg differenciális módban ugyanez 27 - 34 ADCK ciklus.
A konverzió teljes ideje (amibe most beleértjük a mintavételezés idejét is) a következő képlettel számítható:
Conversion Time = SFCAdder + AverageNum*(BCT + LSTadder + HSCAdder)
- SFCAdder - Az első (vagy szingli) mérés többletideje, ami tipikusan 5 ADCK + 5 busz órajelciklus
- AverageNum - a hardveresen átlagolt mérések száma (1, 4, 8, 16, 32)
- BCT - a felbontástól és üzemmódtól függő alap konverziós idő (17 - 34 ADCK órajelciklus)
- LSTAdder - A nyújtott mintavételezés többletideje (2, 6, 12, 20 ADCK ciklus)
- HSCAdder - ADHSC bit beállításától függően 0, vagy 2 ADCK ciklus.
Program7_1: ADC konverzió a 0. csatornán
Ez a program a 0. analóg csatornára (PTE20 kivezetés) adott bemenőjel feszültségét méri periodikusan, szoftveres indítással. A 12 bites felbontású eredmény 8-10. bitjeit az RGB LED segítségével kijelezzük. Végeredményben a 0 - 1,65 V közötti tartományt 8 sávban detektáljuk. Ha a jel nagysága változik, a LED színe is megváltozik.Hardver követelmények
- Kössünk egy potmétert a 3.3V és a GND közé, a csúszkáját pedig csatlakoztassuk a PTE20 lábra! Ha a jel nagysága változik, a LED
Az ADC konfigurálást végző ADC0_init() függvény az alábbi lépésekből áll:
- Engedélyezzük az E portot és analóg módba állítjuk a 0. ADC csatornához tartozó PTE20 kivezetést. Az analóg mód az Alt 0 funkciónak felel meg, tehát nullát írunk a PORTE->PCR[20] portvezérlő regiszter MUX bitcsoportjába (is).
- Engedélyezzük az ADC működését a SIM->SCGC6 regiszter 27. bitjének '1'-be állításával.
- Szoftveres triggerelést állítunk be az ADC0->SC2 regiszterében az ADTRG bit törlésével.
- Beállítjuk az ADC órajelét (buszfrekvencia/4, ami esetünkben kb. 5.25 MHz) és a felbontást (12 bit) az ADC0->CFG1 = regiszterben, s a leghosszabb mintavételi időt választjuk (24 ADCK ciklus);
A főprogram végtelen ciklusában az ADC0->SC1[0] regiszter írásával kiválasztjuk a mérendő csatornát, s ez egyúttal elindítja a konverziót is. Ezután várunk a COCO jelzőbit bebillenésére, majd kiolvassuk és kijelezzük az eredményt.
2. lista: A Program7_1/main.cpp program listája
/* program7_1: ADC konverzió a 0. csatornán
* Ez a program a 0. analóg csatornán (PTE20) mér, szoftveres indítással,
* folyamatosan. Az eredmény 8-10. bitjeit az RGB LED segítségével
* kijelezzük. A LED vezérlő kódot a Program2_7-ből emeltük át.
*
* Kössön egy potmétert a 3.3V és a GND közé, vagy csatlakoztasson más
* analóg jelforrást a PTE20 lábra! Ha a jel nagysága változik, a LED
* színe is megváltozik.
*
* A program forrása: Mazidi et al., Freescale ARM Cortex-M Embedded Programming
* http://www.microdigitaled.com/ARM/Freescale_ARM/Code/Freescale_ARM_codes.htm
*/
#include "MKL25Z4.h"
void ADC0_init(void);
void LED_set(int s);
void LED_init(void);
int main (void) {
int result;
LED_init(); // RGB LED konfigurálás
ADC0_init(); // ADC0 konfigurálás
while (1) {
ADC0->SC1[0] = 0; // ADC konverzió indítása
while(!(ADC0->SC1[0] & 0x80)); // Konverzió végére várunk
result = ADC0->R[0]; // Eredmény kiolvasása, COCO bit törlése
LED_set(result >> 7); // Az eredmény kijelzése
}
}
void ADC0_init(void) {
SIM->SCGC5 |= 0x2000; // PORTE engedélyezése
PORTE->PCR[20] = 0; // PTE20 analóg bemenet legyen
SIM->SCGC6 |= 0x8000000; // ADC0 engedélyezése
ADC0->SC2 &= ~0x40; // szoftveres triggerelés
// clock divide by 4, long sample time, single ended 12 bit, bus clock
ADC0->CFG1 = 0x40 | 0x10 | 0x04 | 0x00;
}
/* RGB LED inicializálása Program2_7 alapján */
void LED_init(void) {
SIM->SCGC5 |= 0x400; // Port B engedélyezése
SIM->SCGC5 |= 0x1000; // Port D engedélyezése
PORTB->PCR[18] = 0x100; // PTB18 legyen GPIO (MUX = 1)
PTB->PDDR |= 0x40000; // PTB18 legyen kimenet (bit18)
PTB->PSOR = 0x40000; // Piros LED lekapcsolása (negatív logika!)
PORTB->PCR[19] = 0x100; // PTB19 legyen GPIO (MUX = 1)
PTB->PDDR |= 0x80000; // PTB19 legyen kimenet (bit19=1)
PTB->PSOR = 0x80000; // Zöld LED lekapcsolása (negatív logika!)
PORTD->PCR[1] = 0x100; // PTD1 legyen GPIO (MUX = 1)
PTD->PDDR |= 0x02; // PTD1 legyen GPIO (MUX = 1)
PTD->PSOR = 0x02; // Kék LED lekapcsolása (negatív logika!)
}
// LED-ek ki/bekapcsolása a kapott adat bitjeinek megfelelően
void LED_set(int value) {
if (value & 1) // A 0. bit a piros LED-et vezérli
PTB->PCOR = 0x40000; // Piros LED be
else
PTB->PSOR = 0x40000; // Piros LED ki
if (value & 2) // Az 1. bit a zöld LED-et vezérli
PTB->PCOR = 0x80000; // Zöld LED be
else
PTB->PSOR = 0x80000; // Zöld LED ki
if (value & 4) // A 2. bit a kék LED-et vezérli
PTD->PCOR = 0x02; // Kék LED be
else
PTD->PSOR = 0x02; // Kék LED ki
}
Program7_2: A beépített hőmérő használata
Ebben a programban a beépített hőmérőt használjuk, melynek jele a 26.
ADC csatorna kiválasztásával érhető el. A Mazidi könyv eredi
mintapéldáját egy kicsit átdolgoztuk:- 16 bites konverziót használunk
- Felhasználjuk az ADC hardveres átlagoló képességét, s 32 mérés átlagát olvassuk ki és jelenítjük meg.
- A bugyuta LED színezgetés helyett a soros porton kiíratjuk az eredményt. Ehhez felhasználjuk a 4. fejezet mintapéldái (Lab04) között található uart_retarget mintaprojektet: a Proram7_2 projektbe be kell másolni és a projektbe fel kell venni az uart_funcs.c és a retarget.c állományokat.
Az ADC konfigurálása Program7_1 projekthez képest így módosul:
- Engedélyezzük a hardveres átlagolást és a 32 minta átlagolása opciót választjuk ki:
ADC0->SC3 = ADC_SC3_AVGE_MASK // Hardveres átlagolás engedélyezése
| ADC_SC3_AVGS(3); // 32 minta átlagolása - Az ADC órajele az előző programtól eltérő rendszeróra konfigurálás miatt kb. 6 MHz lesz (ez jelentéktelen változás), a felbontást pedig 16 bitre állítjuk a korábbi 12 helyett.
Temp = 25 - (VTemp - V25)/m
ahol VTemp az általunk mért feszültség mV-ban, V25 és m pedig az adatlapból kiolvasható paraméterek (V25 a 25 ºC-on mért feszültség, kb. 716 mV, m pedig a meredekség, kb. 1620 µV/ºC).
Megjegyzés: Ebben a programban a CPU frekvenciát 48 MHz-re, a buszfrekvenciát 24 MHz-re, a soros port sebességét pedig 9600 Baudra konfiguráltuk.
3. lista: A Program7_2/main.cpp program listája
/* program7_2: a belsö hömérö használata
* Ez a program a 26. analóg csatornán (belső hőmérő) mér az ADC-vel,
* szoftveres indítással, folyamatosan.
* A 16 bites eredményből számolt feszültség és hőmérséklet értékeket
* A Lab04-ben található uart_retarget mintaprogramban bemutatottak szerint
* Az UART0 soros porton íratjuk ki.
*
* A program a Mazidi et al., Freescale ARM Cortex-M Embedded Programming
* http://www.microdigitaled.com/ARM/Freescale_ARM/Code/Freescale_ARM_codes.htm
* honlapon közzétett program7_2 mintaprogram átdolgozott változatának tekinthető.
* Változtatások az eredeti programhoz képest:
* - Az ADC-vel 16-bites módban mérünk, 32 mintánkénti hardveres átlagolással
* - Az eredményeket soros porton kiíratjuk, az RGB LED vezérlése helyett
*/
#include <MKL25Z4.H>
#include "stdio.h"
// Rendszer órajel: 48MHz
// UART0: 9600 bps, 8 bit adat, nincs paritás, 1 stop bit
// UART függvények
extern void UART_config(void);
extern char UART_putc(char ch);
extern char UART_getc(void);
extern void UART_echo(void);
extern void UART_puts(char * mytext);
void ADC0_init(void) {
SIM->SCGC6 |= 0x8000000; // ADC0 engedélyezése
ADC0->SC2 &= ~0x40; // szoftveres triggerelés
ADC0->SC3 = ADC_SC3_AVGE_MASK // Hardveres átlagolás engedélyezése
| ADC_SC3_AVGS(3); // 32 minta átlagolása
// Div4, Long sampling, single ended 16-bit, bus clock
ADC0->CFG1 = 0x40 | 0x10 | 0x0C | 0x00;
}
//---------------------------------------
// KésleltetőKéslelteto füMHz órajelhez
//---------------------------------------
void delayMs(int n) {
int i, j;
for(i = 0 ; i < n; i++)
for (j = 0; j < 8010; j++);
}
int main(void) {
int result,v,temp;
SystemCoreClockUpdate();
ADC0_init(); // ADC0 konfigurálás
UART_config(); // UART konfigurálás
printf("\r\nInternal temperature sensor\r\n");
while(1){
ADC0->SC1[0] = 26; // Mérés a 26. csatornán (belsö hömérö)
while(!(ADC0->SC1[0] & 0x80)); // Konverzió végére várunk
result = ADC0->R[0]; //Eredmény kiolvasás, COCO bit törlése
v = result*3300/65536;
temp = 25 - (v - 716)*1000/1620;
printf("volt: %d mV temp: %d C\r\n",v,temp);
delayMs(2000);
}
}
A program futási eredménye az alábbi ábrán látható:7. ábra: Program7_2 futási eredménye
Program7_3: külső 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 előző programhoz hasonlóan az UART0 soros
portra íratjuk ki. A program nagyon hasonlít az előzőhöz, csak most a 8. analóg csatonán (PTB0) mérünk, ami az Arduion kompatibilis csatlakozó kiosztás szerinti A0 bemenetnek felel meg, s nem a belső hőmérőt, hanem egy külsőt használunk.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
8. ábra: Az MCP9700 hőmérő bekötése
4. lista: A Program7_3/main.cpp program listája
/* program7_3: Külső analóg hőmérő használata
* Ez a program a 8. analóg csatornán (PTB0) méri az ADC-vel
* egy MCP9700 analóg hőmérő jelét (10 mV/C, 500 mV offset).
* A 16 bites eedményből számolt feszültség és hőmérséklet értékeket
* A Lab04-ben található uart_retarget mintaprogramban bemutatottak szerint
* Az UART0 soros porton íratjuk ki.
*
* A program a Mazidi et al., Freescale ARM Cortex-M Embedded Programming
* http://www.microdigitaled.com/ARM/Freescale_ARM/Code/Freescale_ARM_codes.htm
* honlapon közzétett program7_3 mintaprogram átdolgozott változatának tekinthető.
* Változtatások az eredeti programhoz képest:
* - MCP9700 hömérövel mérünk a PTB0 lábon
* - Az ADC-vel 16-bites módban mérünk, 32 mintánkénti hardveres átlagolással
* - Az eredményeket soros porton kiíratjuk, az RGB LED vezérlése helyett
*/
#include <MKL25Z4.H>
#include "stdio.h"
// Rendszer órajel: 48MHz
// UART0: 9600 bps, 8 bit adat, nincs paritás, 1 stop bit
// UART függvények
extern void UART_config(void);
extern char UART_putc(char ch);
extern char UART_getc(void);
extern void UART_echo(void);
extern void UART_puts(char * mytext);
void ADC0_init(void) {
SIM->SCGC5 |= 0x400; // PORTB engedélyezése
PORTB->PCR[0] = 0; // PTB0 legyen analóg módban
SIM->SCGC6 |= 0x8000000; // ADC0 engedélyezése
ADC0->SC2 &= ~0x40; // szoftveres triggerelés
ADC0->SC3 = ADC_SC3_AVGE_MASK // Hardveres átlagolás engedélyezése
| ADC_SC3_AVGS(3); // 32 minta átlagolása
// Div4, Long sampling, single ended 16-bit, bus clock
ADC0->CFG1 = 0x40 | 0x10 | 0x0C | 0x00;
}
//---------------------------------------
// Késleltető függvény 48 MHz órajelhez
//---------------------------------------
void delayMs(int n) {
int i, j;
for(i = 0 ; i < n; i++)
for (j = 0; j < 8010; j++);
}
int main(void) {
int result,v,temp;
SystemCoreClockUpdate();
ADC0_init(); // ADC0 konfigurálás
UART_config(); // UART konfigurálás
printf("\r\nMCP9700 temperature sensor\r\n");
while(1){
ADC0->SC1[0] = 8; // Mérés a 8. csatornán (PTB0)
while(!(ADC0->SC1[0] & 0x80)); // Konverzió végére várunk
result = ADC0->R[0]; // Eredmény kiolvasás, COCO bit törlése
v = result*3300/65536;
temp = (v - 500)/10;
printf("volt: %d mV temp: %d C\r\n",v,temp);
delayMs(2000);
}
}
A programban két másodpercenként kiíratjuk a feszültségre átszámolt mért é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: Program7_3 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.
10. ábra: A
12-bites DAC blokkvázlata
A DAC bonyolult bufferelt és harveresen triggerelt üzemmódjaival itt nem fogalalkozunk, így a DAC regiszterkészletéből is csak a számunkra relevánsakat ismertetjük.
11. ábra: A DAC regiszterkészlete
DA0_C0 vezérlő regiszter
Ennek a regiszternek a segítségével engedélyezzük a DAC működését, választjuk ki a referencia forrást (bát a FRDM-KL25Z kártyán gyárilag össze van kötve a VREFH és a VDDA pont),a többi bitet alapértelmezett beállításban hagyhatjuk.
DACEN - A DAC működésének engedélyezése (0: letiltva, 1: engedélyezve)
DACRFS - Referencia forrás választása (0: VREFH, 1: VDDA)
DACTRGSEL - Trigger mód választás (0: hardveres, 1: szoftveres)
DACSWTRG - Szoftveres triggerelés és bufferelt mód esetén a triggereléshez '1'-et kell írnunk bele.
LPEN - Alacsonyfogyasztású mód engedélyezése (0: normál mód, 1: kisfogyasztású, lassabb mód)
DACBTIEN - DAC buffer felső mutató megszakítás engedélyezés
DACBBIEN - DAC buffer alsó mutató megszakítás engedélyezés
DAC0_C1 vezérlő regiszter
Ebben a regiszterben állíthatjuk be az egyszerű módot a bufferelés letiltásával (DACBFEN = 0).
DMAEN - DMA átvitel engedélyezése (0: letiltva, 1: engedélyezve)
DACBFMD - DAC buffer működési mód (0: normál mód, 1: csak egyszeri pásztázás)
DACBFEN - DAC bufferelt mód engedélyezése (0: letiltva, 1: engedélyezve)
DAC0_DAT0L és DAC0_DATH adatregiszterek
A DAC 12 bites adatoka konvertál arányos feszültséggé. Az adatokat a DAC0_DAT0L és DAC0_DATH adatregiszterekbe kell beírni (előbbibe az alsó 8 bitet, utóbbiba a maradék 4 bitet, jobbra igazítva). A bufferelés letiltott állapotában az adat azonnal a DAC bemenetére kerül.
Program7_4: A DAC kimenőfeszültségének léptetése
Oszcilloszkóp híján egy LED-del is ellenőrizhetjük az alábbi programot, amelyben 256 lépésben kb. 3,9 Hz-es fűrészfog jelet állítunk elő.Hardver követelmények:
- FRDM-KL25Z kártya
- Áramkorlátozással (max. 1 mA) ellátott LED a GND és a PTE30 kivezetések közé kötve.
5. lista: A Program7_4/main.cpp program listája
/* program7_4: furészfog hzullámforma generálása DAC-kal
* A DAC-ot bufferelés nélküli, szoftveresen triggerelt módba konfiguráljuk,
* így minden írás az adatregiszterbe módosítja a kimenö analóg jelet.
* A for ciklusváltozóját minden iterációnál 0x0010-nal növeljük.
* A 12-bites DAC így 256 lépésben jut el a végkitéréshez. Ha ciklusonként
* 1 ms-ot várakozunk, akkor 256 ms lesz egy fürészfog periódusideje,
* ami kb 3.9 Hz-nek felel meg.
*
* A program forrása: Mazidi et al., Freescale ARM Cortex-M Embedded Programming
* http://www.microdigitaled.com/ARM/Freescale_ARM/Code/Freescale_ARM_codes.htm
*/
#include "MKL25Z4.h"
void DAC0_init(void);
void delayMs(int n);
int main (void) {
int i;
DAC0_init(); // DAC konfigurálása
while (1) {
for (i = 0; i < 0x1000; i += 0x0010) {
DAC0->DAT[0].DATL = i & 0xff; // Alsó bájt írása
DAC0->DAT[0].DATH = (i >> 8) & 0x0f; // Felsö bitek írása
delayMs(1); // Késleltetés
}
}
}
void DAC0_init(void) {
SIM->SCGC5 |= 0x2000; // PORTE engedélyezése
PORTE->PCR[30] = 0; // PTE30 analóg módban legyen
SIM->SCGC6 |= 0x80000000; // DAC modul engedélyezése
DAC0->C1 = 0; // Bufferelt mód letiltása
DAC0->C0 = 0x80 | 0x20; // DAC engedélyezés és szoftveres triggerelés
}
//--------------------------------------------------------------
// Késleltető függvény alapértelmezett órajelhez (20.97152 MHz)
//--------------------------------------------------------------
void delayMs(int n) {
int i, j;
for(i = 0 ; i < n; i++)
for (j = 0; j < 3500; j++);
}
A program működését egy, a PTE30
kivezetésre kötött LED segítségével ellenörizhetjük. Ne feledjünk
sorba kötni vele egy áramkorlátozó ellenállást (a dióda
nyitófeszültségétől függően 1 - 2 kOhm kellhet)! Az adatlap szerint a
DAC maximális kimenő árama 1 mA lehet. A kimenő jel frekvenciáját csökkenthetjük a késleltetés idő növelésével (pl. delayMs(10) jobban megfigyelhetővé teszi a LED esetén az időbeli változást).
A kimenő jel frekvenciájának növeléséhez a késleltető eljárásban használt konstans értékét csökkentsük.