|
1. Sammenkobling av øvre og nedre nivåer I denne artikkelen skal vi diskutere søvnfunksjonen og oppvåkningsmetoden til CC2430. I praksis drives CC2430-noden vanligvis av batterier, så kontroll av strømforbruket er avgjørende. Følgende er et utdrag fra den kinesiske manualen CC2430 for introduksjonen av CC2430s 4 strømforbruksmoduser:
Som du kan se i tabellen over, har CC2430 totalt 4 effektmoduser:PM0(helt våken),PM1(litt søvnig),PM2(halvvåken og halvsovende),PM3(Sover veldig tungt). Jo lenger bak, desto flere funksjoner slås av, og strømforbruket blir lavere og lavere. Konverteringsforholdet mellom dem er som følger:
SettPM1、PM2VåknePM0, det finnes tre måter: tilbakestilling, ekstern avbrytelse, avbrudd i søvntimer; Men legg tilPM3VåknePM0, det finnes bare to måter: tilbakestilling, ekstern avbrudd (dette er fordi iPM3Alle oscillatorer sluttet å fungere, og selvfølgelig var søvntimeren slått av~) La oss gå gjennom et lite eksperiment for å introdusere hvordan man går i dvalemodus og hvordan man våknerPM0stat. 2. Systematisk søvn og avbrutte oppvåkningseksperimenter(1) Introduksjon til eksperimentetsysteminitialisering, iPM0
→ kom innPM1
→ Våkne av søvntimeren etter 1 sekunderPM0
→ kom innPM2
→ ble vekket av søvntimeren etter to sekunderPM0
→ kom innPM3
→ Vent på at tasten S1 skal trykkes, noe som utløser et eksternt avbrudd og våknerPM0
(2) Programflytskjema
(Merk: Den avrundede boksen på bildet over viser systemets helsestatus)
(3) Eksperimentell kildekode og analyse (Følgende bokser kan klikkes på~)Headerfil og makrodefinisjon[url=]
[/url]
/* Eksperimentell beskrivelse: Avbrutt våkensøvn-eksperiment, som introduserer våkenhet i tre søvnmoduser
*/
#include #define LED_ON 0 #define LED_OFF 1#defineled1 P1_0
#defineled2 P1_1
#defineled3 P1_2
#defineled4 P1_3 [url=] [/url]
Underfunksjoner[url=] [/url]
/*Systemklokkeinitialisering -------------------------------------------------------*/
Tomromxtal_init(Tomrom)
{ SOV &= ~0x04; //Alle har strøm
mens(! (SØVN &0x40)); //Krystalloscillatoren er på og stabil
CLKCON &= ~0x47; //Velg en 32 MHz krystalloscillator
SØVN |=0x04;
}
/*LED-initialisering -------------------------------------------------------*/
Tomromled_init(Tomrom)
{ P1SEL =0x00; //P1 er den vanlige I/O-porten
P1DIR |=0x0F; //P1.0 P1.1 P1.2 P1.3-utgang
led1 = LED_OFF; //Slå av alle LED-lys
led2 = LED_OFF; led3 = LED_OFF; led4 = LED_OFF;
}
/*Ekstern avbruddsinitialisering -------------------------------------------------------*/
Tomromio_init(Tomrom)
{ P0INP &= ~0X02; //P0.1 har pull-up og pull-down
EA =1; //Total avbrytelse tillatt
IEN1 |= 0X20; //P0IE = 1, P0-avbrudd aktiveres
PICTL |= 0X09; //P0.1 tillater avbrudd, drop edge-triggere
P0IFG &= ~0x02; //P0.1 Avbruddsmarkering clear0
}
/*Initialisering av avbrudd for søvntimer -------------------------------------------------------*/
TomromsleepTimer_init(Tomrom)
{ STIF=0; //Avbruddsmerket for søvntimeren er klart 0
STIE=1; //Slå på søvntimeren avbrutt
EA=1; //Åpne den totale avbrytelsen
}
/*Sett det planlagte intervallet for søvntimeren -------------------------------------------------------*/
TomromsetSleepTimer(usignert)Intsec)
{ UsignertlangsleepTimer =0;
sleepTimer |= ST0; //Få telleverdien til den nåværende søvntimeren
sleepTimer |= (usignertlang)ST1 <<8; sleepTimer |= (usignertlang)ST2 <<16;
sleepTimer += ((usignert)lang)sec * (usignertlang)32768); //Pluss nødvendig tidsvarighet
ST2 = (usignert)Char(sleepTimer >>16); //Sett sammenligningsverdien til søvntimeren
ST1 = (usignert)Char(sleepTimer >>8); ST0 = (usignert)Char)sleepTimer;
}
/*Velg strømmodus -------------------------------------------------------*/
TomromPowerMode (usignertCharmodus)
{
hvis(modus <4) { SOV &=0xfc; //Fjern SLEEP.MODE til 0
SLEEP |= modus; //Velg strømmodus
PCON |=0x01; //Aktiver denne strømmodusen
}
}
/*Forsinkelsesfunksjon -------------------------------------------------------*/
TomromForsinkelse(usignert)Intn)
{ UsignertInti,j;
for(i=0; i<n; i++)
for(j=0; j <1000; j++);
}
[url=] [/url]
Hovedfunksjon[url=] [/url]
/*Hovedfunksjon -------------------------------------------------------*/
Tomromhoved(Tomrom)
{ xtal_init(); led_init();
//PM0-status, lys på og forsinkelse
led1 = LED_ON; //Lysstyrke LED1 indikerer at systemet fungerer i PM0-modus
Forsinkelse(10);
//PM1-tilstand, lyset av
setSleepTimer(1); //Sett tidsintervallet for søvntimeren til 1 sekunder
sleepTimer_init(); //Slå på søvntimeren avbrutt
led1 = LED_OFF; PowerMode(1); //Sett strømmodusen til PM1
//Etter 1 sekunder går PM1 inn i PM0, lyser opp og forsinker
led1 = LED_ON; Forsinkelse(50);
//PM2, lyset av
setSleepTimer(2); //Sett tidsintervallet for søvntimeren til 2 sekunder
led1 = LED_OFF; PowerMode(2); //Sett strømmodusen til PM2
//Etter 2 sekunder går PM2 inn i PM0, lyser opp og forsinker
led1=0; Forsinkelse(50);
//PM3, slukk lyset
io_init(); //Initialiser eksterne avbrudd
led1 = LED_OFF; PowerMode(3); //Sett strømmodusen til PM3
//Når et eksternt avbrudd oppstår, går PM3 inn i PM0 og lyser opp
led1 = LED_ON;
mens(1);
}
[url=] [/url]
Avbruddstjenesteprosedyrer[url=] [/url]
/*Eksternt avbruddstjenesteprogram -------------------------------------------------------*/
#pragmavektor = P0INT_VECTOR __interruptTomromP0_ISR(Tomrom)
{ EA =0; //Porten er avbrutt
Forsinkelse(50);
hvis((P0IFG &0x02) >0) //Nøklene blir avbrutt
{ P0IFG &= ~0x02; //P0.1 Avbruddsmarkering clear0
} P0IF =0; //P0 avbruddsmarkering clear0
EA =1; //Åpen avbrytelse
}
/*Søvntimer avbryter tjenesteprogrammer -------------------------------------------------------*/
#pragmavektor= ST_VECTOR __interruptTomromsleepTimer_IRQ(Tomrom)
{ EA=0; //Porten er avbrutt
STIF=0; //Avbruddsmerket for søvntimeren er klart 0
EA=1; //Åpen avbrytelse
}
[url=] [/url]
Hvordan bruke en søvntimer for å vekke systemet kan oppsummeres slik:Åpne hviletimer-avbrudd → sett tidsintervallet for søvntimeren → sett strømmodus (Merk: "Sett søvntidsintervallet" må være før "Sett strømmodus", fordi systemet ikke vil fortsette å kjøre programmet etter at det går i dvale) La oss deretter fokusere på delfunksjonen som setter søvntidsintervallet:setSleepTimer Først og fremst, en kort introduksjon til søvntimeren: den går på32,768 kHzav24. plassTimer, når systemet kjørerI tillegg til PM3I alle strømmoduser vil hviletimeren væreUavbrutt drift。 Registrene som brukes av søvntimere er:ST0,ST1,ST2。 Følgende er en detaljert introduksjon til dens funksjoner fra CC2430 kinesiske manual:
Det kan sees at deres funksjoner inkluderer to aspekter:Les,skriv。 Les: Brukes til å lese telleverdien til den nåværende timeren, rekkefølgen målingene må følges i:Les ST0 → Les ST1 → Les ST2 skriv: Brukes til å sette timerens sammenligningsverdi (når timerens telleverdi = sammenligningsverdi, oppstår et avbrudd), må skriverekkefølgen følge:Skriv ST2 → skriv ST1 → skriv ST0 OK, la oss forklare det i kombinasjon med kildekoden: (1) Først, definer en usignert lang variabel (32-bits) sleepTimer for å motta den nåværende tellingsverdien til søvntimeren: UsignertlangsleepTimer =0;
sleepTimer |= ST0; //Få telleverdien til den nåværende søvntimeren
sleepTimer |= (usignertlang)ST1 <<8; sleepTimer |= (usignertlang)ST2 <<16;
(2) Legg deretter til det nødvendige tidsintervallet: sleepTimer += ((usignert)lang)sec * (usignertlang)32768); //Pluss nødvendig tidsvarighet
Her er en liten forklaring: Hvorfor representerer 1-ere 32768? Fordi timeren jobber under 32,768 kHz, tar den 1/32768 s for hver 1 som legges til timeren; Legg til 32768, og du trenger 1-ere; (3) Til slutt brukes verdien av sleepTimer som sammenligningsverdi for timeren: ST2 = (usignert)Char(sleepTimer >>16); //Sett sammenligningsverdien til søvntimeren
ST1 = (usignert)Char(sleepTimer >>8); ST0 = (usignert)Char)sleepTimer;
På denne måten kan du sette tidsperioden på timeren med suksess~ (Merk: Når det gjelder de andre delene av kildekoden, mener jeg at kombinert med detaljerte merknader kan du lett forstå, og jeg vil ikke gjenta det her) (4) Eksperimentelle resultaterVed å kjøre et program, observere LED1, er fenomenet:LED1 blinker (altså på-> av én gang), blinker igjen etter 1 sekunder, blinker igjen etter 2 sekunder, forblir av, og trykker så på S1, LED1 lyser opp. Det eksperimentelle fenomenet er helt i samsvar med forventningen, Over~
3. KonklusjonÅh~ Etter å ha tatt 2 dager med fritid, fikk jeg endelig denne loggen. Jeg har virkelig funnet ut at det å skrive en blogg, spesielt et «leservennlig» blogginnlegg, faktisk er en fysisk oppgave: strenghet, estetikk, logikk... Alt handler om omtanke. Hver gang jeg legger ut koden, synes jeg den er for lang, men jeg er motvillig til å bruke brettverktøyet som følger med blogghagen. Derfor la forfatteren i dette blogginnlegget forsiktig til noen JQuery-elementer for å oppnå jevn folding av koden, og det er fortsatt en liten følelse av mestring, hehe (JQuery-nybegynner, ikke le av mesteren~). Men jeg vet ikke om dette virkelig forbedrer lesbarheten i artikkelen, og lesere og venner er velkomne til å kommentere :) Denne måneden bestemte forfatteren seg virkelig for å slå rot i blogghagen, så jeg brukte mye fritid på å skrive blogginnlegg. Da jeg skrev en blogg for første gang, selv om det var få kommentarer, hadde de fleste loggene en klikkrate på over 500, noe som var en liten oppmuntring for meg! Det krever mot å publisere innhold om mikrokontrollere i blogghagen, men jeg skal holde meg til det~ De ni blogginnleggene fra begynnelsen til i dag fokuserer på bruk av grunnleggende maskinvaremoduler på CC2430-brikken. Så langt har vi i praksis gått gjennom de fleste periferiene på CC2430, men det er fortsatt ting som Flash-tilgang, tilfeldig tallgenerator, AES-koprosessor, RF-kommunikasjon osv., som ikke har blitt berørt. Zigbee-reisen er imidlertid ikke over, og forfatteren har til hensikt å selektivt fylle inn disse utelatelsene i neste tema (implementering av Z-Stack-protokollen). I neste blogginnlegg planlegger jeg å avslutte Zigbees første tur med et litt mer omfattende og utvidet eksperiment – «temperaturovervåkingssystem», og forklare hvordan man kan anvende kunnskapspunktene man lærte tidligere. Faktisk er det ikke kvalifisert til å kalles "ForklaringSom nybegynner håper forfatteren bare å oppmuntre hverandre og gjøre fremskritt sammen i prosessen med å skrive en doktorgrad! </n; i++)
|