|
1. Forbindelse mellem øvre og nedre niveauer I denne artikel vil vi diskutere søvnfunktionen og opvågningsmetoden for CC2430. I praktisk brug drives CC2430-noden generelt af batterier, så kontrol over dens strømforbrug er afgørende. Følgende er et uddrag fra CC2430 kinesiske manual til introduktionen af CC2430's 4 strømforbrugstilstande:
Som du kan se i tabellen ovenfor, har CC2430 i alt 4 strømtilstande:PM0(helt vågen),PM1(lidt søvnig),PM2(halvvågen og halvsovende),PM3(Sover meget tungt). Jo længere tilbage, desto flere funktioner slås fra, og strømforbruget bliver lavere og lavere. Konversionsforholdet mellem dem er som følger:
SætPM1、PM2Vågn opPM0, der er tre måder: nulstilling, ekstern afbrydelse, afbrydelse af søvntimer; Men sætPM3Vågn opPM0, der er kun to måder: nulstilling, ekstern afbrydelse (dette er fordi iPM3Alle oscillatorer holdt op med at virke, og selvfølgelig var søvntimeren slået fra~) Lad os gennemgå et lille eksperiment for at introducere, hvordan man går i dvaletilstand og vågner opPM0stat. 2. Systematisk søvn og afbrudte opvågningsforsøg(1) Introduktion til eksperimentetsysteminitialisering, iPM0
→ kom indPM1
→ Vågne op ved søvnuret efter 1 sekunderPM0
→ kom indPM2
→ blev vækket af søvnuret efter 2 sekunderPM0
→ kom indPM3
→ Vent på, at tasten S1 bliver trykket, hvilket udløser et eksternt interrupt og vågner opPM0
(2) Programflowdiagram
(Bemærk: Den afrundede boks på billedet ovenfor angiver systemets sundhedsstatus)
(3) Eksperimentel kildekode og analyse (Følgende bokse kan klikkes på~)Headerfil og makrodefinition[url=]
[/url]
/* Eksperimentel beskrivelse: Eksperiment med afbrudt opvågningssøvn, som introducerer vågenhed i tre søvntilstande
*/
#include #define LED_ON 0 #define LED_OFF 1#defineled1 P1_0
#defineled2 P1_1
#defineled3 P1_2
#defineled4 P1_3 [url=] [/url]
Underfunktioner[url=] [/url]
/*Systemur-initialisering -------------------------------------------------------*/
tomrumxtal_init(tomrum)
{ SOV &= ~0x04; //Alle er strømførende
mens(! (SØVN &0x40)); //Krystaloscillatoren er tændt og stabil
CLKCON &= ~0x47; //Vælg en 32MHz krystaloscillator
SØVN |=0x04;
}
/*LED-initialisering -------------------------------------------------------*/
tomrumled_init(tomrum)
{ P1SEL =0x00; //P1 er den normale I/O-port
P1DIR |=0x0F; //P1.0 P1.1 P1.2 P1.3 output
led1 = LED_OFF; //Sluk alle LED'er
led2 = LED_OFF; led3 = LED_OFF; led4 = LED_OFF;
}
/*Ekstern afbrydelsesinitialisering -------------------------------------------------------*/
tomrumio_init(tomrum)
{ P0INP &= ~0X02; //P0.1 har pull-up og pull-down
EA =1; //Total afbrydelse tilladt
IEN1 |= 0X20; //P0IE = 1, P0-interrupts aktiverer
PICTL |= 0X09; //P0.1 tillader afbrydelser, drop edge-triggere
P0IFG &= ~0x02; //P0.1 Interrupt mark clear0
}
/*Initialisering af søvntimer-interrupt -------------------------------------------------------*/
tomrumsleepTimer_init(tomrum)
{ STIF=0; //Afbrydelsesmærket for søvntimeren er klart 0
STIE=1; //Tænd for søvntimeren afbrudt
EA=1; //Åbn den totale afbrydelse
}
/*Sæt det planlagte interval for søvntimeren -------------------------------------------------------*/
tomrumsetSleepTimer (usigneretintsec)
{ UsigneretLangsleepTimer =0;
sleepTimer |= ST0; //Få tælleværdien af den aktuelle dvaletimer
sleepTimer |= (usigneretLang)ST1 <<8; sleepTimer |= (usigneretLang)ST2 <<16;
sleepTimer += ((usigneret)Lang)sec * (usigneretLang)32768); //Plus den nødvendige tidsvarighed
ST2 = (usigneret)Char(sleepTimer >>16); //Indstil sammenligningsværdien af søvntimeren
ST1 = (usigneret)Char(sleepTimer >>8); ST0 = (usigneretChar)sleepTimer;
}
/*Vælg strømtilstand -------------------------------------------------------*/
tomrumPowerMode (usigneretChartilstand)
{
hvis(tilstand <4) { SLEEP &=0xfc; //Ryd SLEEP.MODE til 0
SLEEP |= tilstand; //Vælg strømtilstand
PCON |=0x01; //Aktivér denne strømtilstand
}
}
/*Forsinkelsesfunktion -------------------------------------------------------*/
tomrumForsinkelse (usigneretintn)
{ Usigneretinti,j;
for(i=0; i<n; i++)
for(j=0; j <1000; j++);
}
[url=] [/url]
Hovedfunktion[url=] [/url]
/*Hovedfunktion -------------------------------------------------------*/
tomrumhoved(tomrum)
{ xtal_init(); led_init();
//PM0-status, lys tændt og forsinkelse
led1 = LED_ON; //Lysstyrke LED1 indikerer, at systemet arbejder i PM0-tilstand
Forsinkelse(10);
//PM1-tilstand, lyset slukket
setSleepTimer(1); //Sæt tidsintervallet for søvntimeren til 1 sekunder
sleepTimer_init(); //Tænd for søvntimeren afbrudt
led1 = LED_OFF; PowerMode(1); //Sæt strømtilstanden til PM1
//Efter 1 sekunder går PM1 ind i PM0, lyser op og forsinker
led1 = LED_ON; Forsinkelse(50);
//PM2, sluk lyset
setSleepTimer(2); //Sæt tidsintervallet for søvntimeren til 2 sekunder
led1 = LED_OFF; PowerMode(2); //Sæt strømtilstanden til PM2
//Efter 2 sekunder går PM2 ind i PM0, tænder og forsinker
led1=0; Forsinkelse(50);
//PM3, lyset slukkes
io_init(); //Initialiser eksterne interrupts
led1 = LED_OFF; PowerMode(3); //Sæt strømtilstanden til PM3
//Når en ekstern afbrydelse opstår, går PM3 ind i PM0 og lyser op
led1 = LED_ON;
mens(1);
}
[url=] [/url]
Afbrydelsesserviceprocedurer[url=] [/url]
/*Eksternt afbrydelsesserviceprogram -------------------------------------------------------*/
#pragmavektor = P0INT_VECTOR __interrupttomrumP0_ISR(tomrum)
{ EA =0; //Porten er afbrudt
Forsinkelse(50);
hvis((P0IFG &0x02) >0) //Nøglerne bliver afbrudt
{ P0IFG &= ~0x02; //P0.1 Interrupt mark clear0
} P0IF =0; //P0 interrupt mark clear0
EA =1; //Åben afbrydelse
}
/*Søvntimerafbrydning afbryder serviceprogrammer -------------------------------------------------------*/
#pragmavektor= ST_VECTOR __interrupttomrumsleepTimer_IRQ(tomrum)
{ EA=0; //Porten er afbrudt
STIF=0; //Afbrydelsesmærket for søvntimeren er klart 0
EA=1; //Åben afbrydelse
}
[url=] [/url]
Hvordan man bruger en søvntimer til at vække systemet kan opsummeres således:Åbn dvaletimer-interrupt → sæt dvaletimerens tidsinterval → sæt strøm-tilstanden (Bemærk: "Indstil dvaletidsintervallet" trin skal være før "Indstil strømtilstand", fordi systemet ikke fortsætter med at udføre programmet efter dvale) Dernæst fokuserer vi på den delfunktion, der fastsætter søvntimerintervallet:setSleepTimer Først og fremmest en kort introduktion til søvntimeren: den kører på32,768kHzaf24. pladsTimer, når systemet kørerUd over PM3I alle strømtilstande vil dvaletimeren væreUafbrudt drift。 De registre, der bruges af søvntimere, er:ST0,ST1,ST2。 Følgende er en detaljeret introduktion til dens funktioner fra CC2430 kinesiske manual:
Det kan ses, at deres funktioner omfatter to aspekter:Læs,Skriv。 Læs: Bruges til at aflæse tælleværdien af den aktuelle timer, rækkefølgen som aflæsningerne skal følges i:Læs ST0 → Læs ST1 → Læs ST2 Skriv: Bruges til at sætte timerens sammenligningsværdi (når timerens tælleværdi = sammenligningsværdi, opstår et interrupt), skal skriverækkefølgen følge:Skriv ST2 → skriv ST1 → skriv ST0 OK, lad os forklare det i kombination med kildekoden: (1) Først defineres en usigneret lang variabel (32-bit) sleepTimer til at modtage den aktuelle tælleværdi for sleeptimeren: UsigneretLangsleepTimer =0;
sleepTimer |= ST0; //Få tælleværdien af den aktuelle dvaletimer
sleepTimer |= (usigneretLang)ST1 <<8; sleepTimer |= (usigneretLang)ST2 <<16;
(2) Tilføj derefter det nødvendige tidsinterval: sleepTimer += ((usigneret)Lang)sec * (usigneretLang)32768); //Plus den nødvendige tidsvarighed
Her er en lille forklaring: Hvorfor repræsenterer 1'ere 32768? Fordi timeren arbejder under 32,768kHz, tager den 1/32768 s for hver 1, der tilføjes timeren; Læg 32768 til, og du skal bruge 1'ere; (3) Endelig bruges værdien af sleepTimer som sammenligningsværdi for timeren: ST2 = (usigneret)Char(sleepTimer >>16); //Indstil sammenligningsværdien af søvntimeren
ST1 = (usigneret)Char(sleepTimer >>8); ST0 = (usigneretChar)sleepTimer;
På denne måde kan du med succes indstille tidsperioden for timeren~ (Bemærk: Hvad angår de andre dele af kildekoden, mener jeg, at kombineret med detaljerede noter kan du nemt forstå det, og jeg vil ikke gentage det her) (4) Eksperimentelle resultaterNår man kører programmet og observerer LED1, er fænomenet:LED1 blinker (dvs. tændt-> slukket én gang), blinker igen efter 1 sekund, blinker igen efter 2 sekunder, forbliver slukket, og trykker derefter på S1, LED1 lyser op. Det eksperimentelle fænomen er fuldstændig i overensstemmelse med forventningen, Over~
3. KonklusionÅh~ Efter at have taget 2 dages fritid, fik jeg endelig denne log. Jeg fandt virkelig ud af, at det at skrive en blog, især et "læservenligt" blogindlæg, faktisk er et fysisk job: stringens, æstetik, logik... Det handler om overvejelse. Hver gang jeg poster koden, synes jeg, den er for lang, men jeg er tilbageholdende med at bruge det foldeværktøj, der følger med bloghaven. Derfor tilføjede forfatteren i dette blogindlæg forsigtigt nogle JQuery-elementer for at opnå en glidende foldning af koden, og der er stadig en lille følelse af tilfredshed, hehe (JQuery-nybegynder, grin ikke af mesteren~). Men jeg ved ikke, om det virkelig forbedrer læsbarheden af artiklen, og læsere og venner er velkomne til at kommentere :) Denne måned besluttede forfatteren sig virkelig for at slå rod i bloghaven, så jeg brugte meget fritid på at skrive blogindlæg. Da jeg skrev en blog for første gang, var der få kommentarer, men de fleste logs havde en klikrate på over 500, hvilket var en lille opmuntring for mig! Det kræver mod at offentliggøre indhold om mikrocontrollere i bloghaven, men jeg vil holde fast i det~ De ni blogindlæg fra begyndelsen til i dag fokuserer på brugen af grundlæggende hardwaremoduler på CC2430-chippen. Indtil videre har vi stort set gennemgået det meste af periferiudstyr på CC2430, men der er stadig ting som Flash-adgang, tilfældighedsgenerator, AES-koprocessor, RF-kommunikation osv., som ikke er blevet berørt. Zigbee-rejsen er dog ikke slut, og forfatteren har til hensigt selektivt at udfylde disse udeladelser i det næste emne (implementering af Z-Stack-protokollen). I det næste blogindlæg planlægger jeg at afslutte Zigbees første rejse med et lidt mere omfattende og udvidet eksperiment – "temperaturovervågningssystem" – og forklare, hvordan man grundigt anvender de tidligere lærte videnspunkter. Faktisk er det ikke kvalificeret til at blive kaldt "ForklaringSom begynder håber forfatteren kun at opmuntre hinanden og gøre fremskridt sammen i processen med at skrive en doktorgrad! </n; i++)
|