Denne artikkelen er en speilartikkel om maskinoversettelse, vennligst klikk her for å hoppe til originalartikkelen.

Utsikt: 9371|Svare: 0

Zigbee Journey (9): Flere viktige grunnleggende CC2430-eksperimenter – systematisk søvn og avbrutt våkenhet

[Kopier lenke]
Publisert på 30.10.2014 23:24:30 | | | |
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:ST0ST1ST2。 Følgende er en detaljert introduksjon til dens funksjoner fra CC2430 kinesiske manual:

Det kan sees at deres funksjoner inkluderer to aspekter:Lesskriv

  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 resultater
Ved å 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++)




Foregående:Zigbee Journey (8): Flere viktige CC2430 grunnleggende eksperimenter – vaktbikkjer
Neste:Zigbee Journey (10): Omfattende eksperiment - Temperaturovervåkingssystem basert på CC2430
Ansvarsfraskrivelse:
All programvare, programmeringsmateriell eller artikler publisert av Code Farmer Network er kun for lærings- og forskningsformål; Innholdet ovenfor skal ikke brukes til kommersielle eller ulovlige formål, ellers skal brukerne bære alle konsekvenser. Informasjonen på dette nettstedet kommer fra Internett, og opphavsrettstvister har ingenting med dette nettstedet å gjøre. Du må fullstendig slette innholdet ovenfor fra datamaskinen din innen 24 timer etter nedlasting. Hvis du liker programmet, vennligst støtt ekte programvare, kjøp registrering, og få bedre ekte tjenester. Hvis det foreligger noen krenkelse, vennligst kontakt oss på e-post.

Mail To:help@itsvse.com