|
1. Povezava zgornje in spodnje ravni V tem članku bomo obravnavali funkcijo spanja in način prebujanja pri CC2430. V dejanski uporabi je CC2430 vozlišče običajno napajano z baterijami, zato je nadzor porabe energije ključen. Spodaj je odlomek iz kitajskega priročnika CC2430 za uvedbo štirih načinov porabe energije pri CC2430:
Kot lahko vidite iz zgornje tabele, ima CC2430 skupaj 4 načine moči:PM0(popolnoma buden),PM1(malo zaspan),PM2(napol buden in pol zaspan),PM3(Zelo trdno spi). Bolj kot je zadaj, več funkcij je izklopljenih in poraba energije je vedno nižja. Razmerje med njima je naslednje:
PutPM1、PM2Zbudi sePM0, obstajajo trije načini: ponastavitev, zunanja prekinitev, prekinitev časovnika spanja; Ampak dajPM3Zbudi sePM0, obstajata le dva načina: ponastavitev, zunanja prekinitev (to je zato, ker vPM3Vsi oscilatorji so prenehali delovati, seveda pa je bil tudi časovnik za spanje izklopljen~) Poglejmo majhen eksperiment, da predstavimo, kako vstopiti v način spanja in kako se zbuditiPM0državi. 2. Sistematični poskusi spanja in prekinjenega prebujanja(1) Uvod v eksperimentInicializacija sistema, vPM0
→ vstopPM1
→ Zbudim se ob časovniku spanja po 1 sekundiPM0
→ vstopPM2
→ se je zbudil zaradi časovnika spanja po 2 sekundahPM0
→ vstopPM3
→ Počakaj, da pritisneš tipko S1, sprožiš zunanji prekinitev in se prebudišPM0
(2) Shema poteka programa
(Opomba: Zaokroženo polje na zgornji sliki prikazuje zdravstveno stanje sistema)
(3) Eksperimentalna izvorna koda in analiza (Naslednja polja lahko kliknete~)Datoteka glave in definicija makrov[url=]
[/url]
/* Eksperimentalni opis: Eksperiment prekinjenega prebujanja spanja, ki uvaja budnost v treh načinih spanja
*/
#include #define LED_ON 0 #define LED_OFF 1#defineLED1 P1_0
#defineLED2 P1_1
#defineLED3 P1_2
#defineLED4 P1_3 [url=] [/url]
Podfunkcije[url=] [/url]
/*Inicializacija sistemske ure -------------------------------------------------------*/
prazninaxtal_init(praznina)
{ SPANJE &= ~0x04; //Vsi so napajani
medtem ko(! (SPANJE &0x40)); //Kristalni oscilator je vklopljen in stabilen
CLKCON &= ~0x47; //Izberite 32MHz kristalni oscilator
SPANJE |=0x04;
}
/*Inicializacija LED -------------------------------------------------------*/
prazninaled_init(praznina)
{ P1SEL =0x00; //P1 je običajen vhodno-izhodni priključek
P1DIR |=0x0F; //izhod P1.0 P1.1 P1.2 P1.3
led1 = LED_OFF; //Ugasnite vse LED diode
led2 = LED_OFF; led3 = LED_OFF; led4 = LED_OFF;
}
/*Inicializacija zunanjih prekinitev -------------------------------------------------------*/
prazninaio_init(praznina)
{ P0INP &= ~0X02; //P0.1 ima dvigovanje in dvigovanje navzdol
EA =1; //Popolna prekinitev dovoljena
IEN1 |= 0X20; //P0IE = 1, P0 prekinitve so omogočene
PICTL |= 0X09; //P0.1 dovoljuje prekinitve, sprožilce na robu
P0IFG &= ~0x02; //P0.1 Oznaka prekinitve clear00
}
/*Inicializacija prekinitve časovnika spanja -------------------------------------------------------*/
prazninasleepTimer_init(praznina)
{ STIF=0; //Oznaka prekinitve časovnika spanja je jasna 0
STIE=1; //Vklop časovnika za spanje prekinjen
EA=1; //Odpri popolno prekinitev
}
/*Nastavite načrtovani interval za časovnik spanja -------------------------------------------------------*/
prazninasetSleepTimer (nepodpisanointsec)
{ nepodpisanodolgosleepTimer =0;
sleepTimer |= ST0; //Pridobite vrednost trenutnega časovnika za spanje
sleepTimer |= (brez znakadolgo)ST1 <<8; sleepTimer |= (brez znakadolgo)ST2 <<16;
sleepTimer += ((unsigneddolgo)sec * (brez podpisadolgo)32768); //Poleg tega je potrebna časovna dolžina
ST2 = (brez znakachar(SleepTimer >>16); //Nastavite primerjalno vrednost časovnika za spanje
ST1 = (brez znakachar(SleepTimer >>8); ST0 = (brez znakachar)sleepTimer;
}
/*Izberite način napajanja -------------------------------------------------------*/
prazninaPowerMode(unsignedcharnačin)
{
če(način <4) { SPANJE &=0xfc; //Počisti SLEEP.MODE na 0
SLEEP |= način; //Izberite način napajanja
PCON |=0x01; //Omogočite ta način napajanja
}
}
/*Funkcija zakasnitve -------------------------------------------------------*/
prazninaZakasnitev(nepodpisano)intn)
{ nepodpisanointi,j;
za(i=0; i<n; i++)
za(j=0; j <1000; j++);
}
[url=] [/url]
Glavna funkcija[url=] [/url]
/*Glavna funkcija -------------------------------------------------------*/
prazninamain(praznina)
{ xtal_init(); led_init();
//PM0 status, lučka prižgana in zamuda
led1 = LED_ON; //LED1 svetlosti kaže, da sistem deluje v načinu PM0
Zakasnitev(10);
//PM1 stanje, luči ugasnjene
setSleepTimer(1); //Nastavite časovni interval časovnika spanja na 1 s
sleepTimer_init(); //Vklop časovnika za spanje prekinjen
led1 = LED_OFF; PowerMode(1); //Nastavite način napajanja na PM1
//Po 1 sekundi PM1 vstopi v PM0, se prižge in se zamakne
led1 = LED_ON; Zakasnitev(50);
//PM2, luči ugasnjene
setSleepTimer(2); //Nastavite časovni interval za časovnik spanja na 2 sekundi
led1 = LED_OFF; PowerMode(2); //Nastavite način napajanja na PM2
//Po 2 sekundah PM2 vstopi v PM0, se prižge in zamudi
led1=0; Zakasnitev(50);
//PM3, luči ugasnjene
io_init(); //Inicializacija zunanjih prekinitev
led1 = LED_OFF; PowerMode(3); //Nastavi način napajanja na PM3
//Ko pride do zunanje prekinitve, PM3 vstopi v PM0 in se prižge
led1 = LED_ON;
medtem ko(1);
}
[url=] [/url]
Postopki storitve prekinitev[url=] [/url]
/*Program za storitve zunanjih prekinitev -------------------------------------------------------*/
#pragmavektor = P0INT_VECTOR __interruptprazninaP0_ISR(praznina)
{ EA =0; //Vrata so prekinjena
Zakasnitev(50);
če((P0IFG &0x02) >0) //Tipke so prekinjene
{ P0IFG &= ~0x02; //P0.1 Oznaka prekinitve clear00
} P0IF =0; //P0 prekinitev oznaka clear00
EA =1; //Odprta prekinitev
}
/*Časovnik za spanje prekine servisne programe -------------------------------------------------------*/
#pragmavektor= ST_VECTOR __interruptprazninasleepTimer_IRQ(praznina)
{ EA=0; //Vrata so prekinjena
STIF=0; //Oznaka prekinitve časovnika spanja je jasna 0
EA=1; //Odprta prekinitev
}
[url=] [/url]
Kako uporabiti časovnik spanja za prebujanje sistema lahko povzamemo takole:Odpri prekinitev časovnika spanja → nastavi časovni interval spanja → nastavi način napajanja (Opomba: Korak "Nastavi interval časovnika spanja" mora biti pred "Nastavi način napajanja", saj sistem po vstopu v spanje ne bo nadaljeval z izvajanjem programa) Nato se osredotočimo na podfunkcijo, ki določa interval spanja:setSleepTimer Najprej kratek uvod v časovnik spanja: deluje naprej32,768 kHzod24. mestoTimer, ko sistem tečePoleg PM3V vseh načinih napajanja bo časovnik spanjaNeprekinjeno delovanje。 Registri, ki jih uporabljajo časovniki spanja, so:ST0,ST1,ST2。 Spodaj je podroben uvod v njegove funkcije iz kitajskega priročnika CC2430:
Vidimo lahko, da njihove funkcije vključujejo dva vidika:Preberite,piši。 Preberite: Uporablja se za branje vrednosti štetja trenutnega časovnika, vrstnega reda, v katerem je treba meritve slediti:Preberi ST0 → preberi ST1 → preberi ST2 piši: Uporablja se za nastavitev vrednosti primerjave časovnika (ko števec števca = vrednost primerjave, pride do prekinitve), mora biti vrstni red zapisovanja naslednji:Zapišite ST2 → zapišite ST1 → zapišite ST0 V redu, razložimo to v kombinaciji z izvorno kodo: (1) Najprej definirajte nepredznakiran dolgi spremenljivec (32-bitni) SleepTimer, da prejmete trenutno vrednost števila časovnika spanja: nepodpisanodolgosleepTimer =0;
sleepTimer |= ST0; //Pridobite vrednost trenutnega časovnika za spanje
sleepTimer |= (brez znakadolgo)ST1 <<8; sleepTimer |= (brez znakadolgo)ST2 <<16;
(2) Nato dodamo zahtevani časovni interval: sleepTimer += ((unsigneddolgo)sec * (brez podpisadolgo)32768); //Poleg tega je potrebna časovna dolžina
Tukaj je kratka razlaga: Zakaj 1s predstavlja 32768? Ker časovnik deluje pod 32,768 kHz, za vsak dodani 1 sekundo traja 1/32768 s; Dodaj 32768 in potreboval boš 1s; (3) Nazadnje se vrednost sleepTimer uporabi kot primerjalna vrednost timerja: ST2 = (brez znakachar(SleepTimer >>16); //Nastavite primerjalno vrednost časovnika za spanje
ST1 = (brez znakachar(SleepTimer >>8); ST0 = (brez znakachar)sleepTimer;
Na ta način lahko uspešno nastavite časovno obdobje časovnika~ (Opomba: Kar zadeva ostale dele izvorne kode, verjamem, da jih v kombinaciji s podrobnimi opombami lahko enostavno razumete, in tega tukaj ne bom ponavljal) (4) Eksperimentalni rezultatiMed izvajanjem programa, opazovanjem LED1, pojav je:LED1 utripa (tj. vklopljeno-> izklopljeno enkrat), ponovno utripa po 1 sekundi, ponovno utripa po 2 sekundah, nato ostane ugasnjeno, nato pritisne S1, LED 1 se prižge. Eksperimentalni pojav je popolnoma skladen s pričakovanjem, Čez~
3. ZaključekOh~ Po dveh dneh prostega časa sem končno dobil ta dnevnik. Res sem ugotovil, da je pisanje bloga, še posebej "bralcu prijaznega" bloga, resnično fizično delo: strogost, estetika, logika... Vse je v razumevanju. Vsakič, ko objavim kodo, mislim, da je predolga, a sem zadržan pri uporabi orodja za zlaganje, ki je priloženo vrtu bloga. Zato je avtor v tem blog zapisu previdno dodal nekaj JQuery elementov, da bi dosegel gladko prepogibanje kode, in še vedno je prisoten majhen občutek dosežka, hehe (JQuery rookie, ne smej se mojstru~). Ampak ne vem, ali to res izboljša berljivost članka, bralci in prijatelji pa so vabljeni, da komentirajo :) Ta mesec se je avtorica resnično odločila, da se bo uveljavila v blogerskem vrtu, zato sem veliko prostega časa porabila za pisanje blog objav. Ko sem prvič pisal blog, čeprav je bilo komentarjev malo, je večina dnevnikov imela več kot 500 klikov, kar mi je bila majhna spodbuda! Za objavo vsebin o mikrokontrolerjih v blog vrtu je potrebna pogum, a bom vztrajal~ Devet blog objav od začetka do danes se osredotoča na uporabo osnovnih strojnih modulov na čipu CC2430. Do zdaj smo v bistvu pregledali večino perifernih naprav na CC2430, vendar še vedno obstajajo stvari, kot so dostop do Flasha, generator naključnih števil, AES koprocesor, RF komunikacija itd., ki niso bile obravnavane. Vendar Zigbeejeva pot še ni končana, avtor namerava te pomanjkljivosti selektivno zapolniti v naslednji temi (implementacija protokola Z-Stack). V naslednji objavi na blogu nameravam zaključiti prvo potovanje Zigbeeja z nekoliko bolj celovitim in razširjenim eksperimentom – "sistemom za merjenje temperature" ter pojasniti, kako celovito uporabiti znanje, pridobljeno prej. Pravzaprav ni kvalificiran, da bi ga imenovali "RazlagaKot začetnik si avtor želi le spodbujati drug drugega in skupaj napredovati pri pisanju doktorata! </n; i++)
|