Dit artikel is een spiegelartikel van machinevertaling, klik hier om naar het oorspronkelijke artikel te gaan.

Bekijken: 9371|Antwoord: 0

Zigbee Journey (9): Verschillende belangrijke basisexperimenten met CC2430 - systematische slaap en onderbroken wakkerheid

[Link kopiëren]
Geplaatst op 30-10-2014 23:24:30 | | | |
1. Het verbinden van de boven- en benedenverdiepingen

In dit artikel bespreken we de slaapfunctie en de wakkerheidsmethode van CC2430. In het daadwerkelijk gebruik wordt de CC2430-node meestal van stroom voorzien door batterijen, dus de controle over het energieverbruik is cruciaal.

Hieronder volgt een fragment uit de Chinese handleiding van de CC2430 voor de introductie van de 4 energieverbruiksmodi van de CC2430:

Zoals je uit de bovenstaande tabel kunt zien, heeft de CC2430 in totaal 4 energiemodi:PM0(volledig wakker),PM1(een beetje slaperig),PM2(half wakker en half slapend),PM3(Slaapt heel diep). Hoe verder naar achteren, hoe meer functies worden uitgeschakeld en het stroomverbruik wordt steeds lager. De conversierelatie tussen hen is als volgt:

ZetPM1、PM2Wakker wordenPM0, er zijn drie manieren: reset, externe onderbreking, onderbreking van de slaaptimer; Maar zetPM3Wakker wordenPM0, er zijn slechts twee manieren: reset, externe interrupt (dit komt doordat inPM3Alle oscillatoren stopten met werken, en natuurlijk stond de slaaptimer uit~)

Laten we een klein experiment doen om te laten zien hoe je in slaapstand gaat en wakker wordtPM0staat.

2. Systematische slaap en onderbroken wakkerexperimenten(1) Inleiding tot het experimentsysteeminitialisatie, inPM0
→ binnenkomenPM1
→ Word wakker met de slaaptimer na 1 secondePM0
→ binnenkomenPM2
→ werd na 2 seconden wakker gemaakt door de slaaptimerPM0
→ binnenkomenPM3
→ Wacht tot de toets S1 wordt ingedrukt, waardoor een externe interrupt wordt geactiveerd en je wakker wordtPM0
(2) Programmastroomdiagram

(Opmerking: Het afgeronde vakje in de bovenstaande afbeelding geeft de gezondheidsstatus van het systeem aan)

(3) Experimentele broncode en analyse (De volgende vakjes kunnen worden aangeklikt~Headerbestand en macrodefinitie[url=] [/url]
/*
    Experimentele beschrijving: Onderbroken wakkerslaap-experiment, dat wakkerheid in drie slaapmodi introduceert
*/

#include
#define LED_ON 0
#define LED_OFF 1#defineled1 P1_0         
#defineled2 P1_1         
#defineled3 P1_2         
#defineled4 P1_3   [url=] [/url]

Subfuncties[url=] [/url]
/*Systeemklokinitialisatie
-------------------------------------------------------
*/
leegtextal_init(leegte)
{
  SLAAP &= ~0x04;            //Allemaal zijn ze van stroom
  terwijl(! (SLAAP &0x40));     //De kristaloscillator staat aan en is stabiel
  CLKCON &= ~0x47;         //Kies een 32MHz kristaloscillator.
  SLAAP |=0x04;
}


/*LED-initialisatie
-------------------------------------------------------
*/
leegteled_init(leegte)
{
  P1SEL =0x00;         //P1 is de normale I/O-poort
  P1DIR |=0x0F;         //P1.0 P1.1 P1.2 P1.3 uitgang
  
  led1 = LED_OFF;         //Zet alle LED's uit
  led2 = LED_OFF;
  led3 = LED_OFF;
  led4 = LED_OFF;
}


/*Externe interrupt-initialisatie
-------------------------------------------------------
*/
leegteio_init(leegte)
{
    P0INP &= ~0X02;   //P0.1 heeft pull-up en pull-down

    EA =1;           //Volledige onderbreking toegestaan
   
    IEN1 |=  0X20;   //P0IE = 1, P0-interrupts activeren
   
    PICTL |=  0X09;   //P0.1 staat interrupts en drop edge triggers toe
   
    P0IFG &= ~0x02;   //P0.1 Interrupt mark clear0
}


/*Initialisatie van slaaptimerinterrupten
-------------------------------------------------------
*/
leegtesleepTimer_init(leegte)
{
  STIF=0;   //Het onderbrekingsteken voor de slaaptimer is schoon 0
   
  STIE=1;   //Zet de slaaptimer aan onderbroken
   
  EA=1;     //Open de totale onderbreking
}


/*Stel het geplande interval in voor de slaaptimer
-------------------------------------------------------
*/
leegtesetSleepTimer (niet ondertekendintsec)
{
  OnondertekendlangsleepTimer =0;
  
  sleepTimer |= ST0;                     //Krijg de telwaarde van de huidige slaaptimer
  sleepTimer |= (onondertekendlang)ST1 <<8;
  sleepTimer |= (onondertekendlang)ST2 <<16;
  
  sleepTimer += ((ongetekendlang)sec * (ongetekendlang)32768);   //Plus de vereiste tijdsduur
  
  ST2 = (niet ondertekendchar(sleepTimer >>16);   //Stel de vergelijkingswaarde van de slaaptimer in
  ST1 = (niet ondertekendchar(sleepTimer >>8);
  ST0 = (niet ondertekendchar)sleepTimer;
}


/*Selecteer Stroommodus
-------------------------------------------------------
*/
leegtePowerMode (niet ondertekendcharmodus)
{
  als(modus <4)
  {
    SLAAP &=0xfc;      //Maak SLEEP.MODE leeg naar 0
    SLAAP |= modus;      //Selecteer Stroommodus
    PCON |=0x01;        //Schakel deze energiemodus in
  }
}


/*Vertragingsfunctie
-------------------------------------------------------
*/
leegteVertraging(niet getekend)intn)
{
  Onondertekendinti,j;
  voor(i=0; i<n; i++)
    voor(j=0; j <1000; j++);
}
[url=] [/url]

Hoofdfunctie[url=] [/url]
/*Hoofdfunctie
-------------------------------------------------------
*/
leegtehoofd(leegte)
{
  xtal_init();         
  led_init();         
  
  //PM0-status, licht aan en vertraging
  led1 = LED_ON;         //Helderheid LED1 geeft aan dat het systeem in PM0-modus werkt
  Vertraging(10);


  //PM1-toestand, licht uit
  setSleepTimer(1);      //Stel het tijdsinterval van de slaaptimer in op 1 seconden
  sleepTimer_init();     //Zet de slaaptimer aan onderbroken
  led1 = LED_OFF;
  PowerMode(1);         //Zet de energiemodus op PM1
  
  
//Na 1s gaat PM1 PM0 binnen, licht op en vertraagt het
  led1 = LED_ON;
  Vertraging(50);
  
  //PM2, licht uit
  setSleepTimer(2);      //Stel het tijdsinterval voor de slaaptimer in op 2 seconden
  led1 = LED_OFF;
  PowerMode(2);         //Zet de stroommodus op PM2


  
//Na 2 seconden komt PM2 in PM0, licht op en vertraagt
  led1=0;
  Vertraging(50);
  
  //PM3, licht uit  
  io_init();            //Externe interrupts initialiseren
  led1 = LED_OFF;
  PowerMode(3);         //Zet de energiemodus op PM3
  
  
//Wanneer er een externe onderbreking optreedt, gaat PM3 PM0 binnen en licht op
  led1 = LED_ON;

  terwijl(1);
}
[url=] [/url]

Interruptserviceprocedures[url=] [/url]
/*Extern interruptserviceprogramma
-------------------------------------------------------
*/
#pragmavector = P0INT_VECTOR
__interruptleegteP0_ISR(leegte)
{
  EA =0;                        //De poort wordt onderbroken
  
  Vertraging(50);

  als((P0IFG &0x02) >0)         //De sleutels zijn onderbroken
  {
    P0IFG &= ~0x02;               //P0.1 Interrupt mark clear0
  }
  P0IF =0;                       //P0 interrupt mark clear0


  EA =1;                        //Open onderbreking
}


/*Slaaptimer onderbreekt serviceprogramma's
-------------------------------------------------------
*/
#pragmavector= ST_VECTOR
__interruptleegtesleepTimer_IRQ(leegte)
{
  EA=0;     //De poort wordt onderbroken
   
  STIF=0;   //Het onderbrekingsteken voor de slaaptimer is schoon 0
  
  EA=1;     //Open onderbreking
}
[url=] [/url]

Hoe je een slaaptimer gebruikt om het systeem wakker te maken, kan als volgt worden samengevat:Open slaaptimer interrupt → stel het tijdinterval van de slaaptimer in → stel de energiemodus in

(Opmerking: de stap "Set the Sleep Timer Interval" moet vóór "Set Power Mode" plaatsvinden, omdat het systeem het programma niet verder uitvoert na het in slaapstand)

Laten we ons vervolgens richten op de subfunctie die het slaaptimerinterval bepaalt:setSleepTimer

Allereerst een korte introductie tot de slaaptimer: hij draait op32,768kHzvan24e plaatsTimer, wanneer het systeem draaitNaast PM3In alle energiemodi zal de slaaptimer zijnOnonderbroken werking

De registers die door slaaptimers worden gebruikt zijn:ST0ST1ST2。 Hieronder volgt een gedetailleerde introductie van de functies uit de Chinese handleiding CC2430:

Hieruit blijkt dat hun functies twee aspecten omvatten:Leesschrijf

  Lees: Gebruikt om de telwaarde van de huidige timer af te lezen, de volgorde waarin de metingen gevolgd moeten worden:Lees ST0 → lees ST1 → lees ST2

  schrijf: Gebruikt om de vergelijkingswaarde van de timer in te stellen (wanneer de tellwaarde van de timer = vergelijkingswaarde optreedt, vindt er een interrupt plaats), moet de schrijfvolgorde volgen:Schrijf ST2 → schrijf ST1 → schrijf ST0

Oké, laten we het uitleggen in combinatie met de broncode:

(1) Definieer eerst een ongetekende lange variabele (32-bits) sleepTimer om de huidige tellwaarde van de slaaptimer te ontvangen:

  OnondertekendlangsleepTimer =0;
  
  sleepTimer |= ST0;                     //Krijg de telwaarde van de huidige slaaptimer
  sleepTimer |= (onondertekendlang)ST1 <<8;
  sleepTimer |= (onondertekendlang)ST2 <<16;

(2) Voeg dan het vereiste tijdsinterval op:

  sleepTimer += ((ongetekendlang)sec * (ongetekendlang)32768);   //Plus de vereiste tijdsduur

Hier is een kleine uitleg:

Waarom staat 1s voor 32768? Omdat de timer onder 32,768 kHz werkt, duurt het 1/32768 s voor elke 1 die aan de timer wordt toegevoegd; Voeg 32768 toe, en je hebt 1s nodig;

(3) Ten slotte wordt de waarde van sleepTimer gebruikt als vergelijkingswaarde van de timer:

  ST2 = (niet ondertekendchar(sleepTimer >>16);   //Stel de vergelijkingswaarde van de slaaptimer in
  ST1 = (niet ondertekendchar(sleepTimer >>8);
  ST0 = (niet ondertekendchar)sleepTimer;

Op deze manier kun je de timingperiode van de timer succesvol instellen~

(Opmerking: wat betreft de andere delen van de broncode, geloof ik dat je in combinatie met gedetailleerde annotaties het gemakkelijk kunt begrijpen, en ik zal het hier niet herhalen)

(4) Experimentele resultaten
Het programma draait en LED1 waarneemt, het fenomeen is:LED1 knippert (dus 1 keer aan-> uit), knippert opnieuw na 1 seconde, knippert na 2 seconden weer, blijft dan uit, en drukt dan op S1, LED1 licht op.
Het experimentele fenomeen is volledig consistent met de verwachting, Over~

3. Conclusie

Oh~ Na 2 dagen vrije tijd heb ik eindelijk dit logboek gekregen. Ik heb echt gemerkt dat het schrijven van een blog, vooral een "lezersvriendelijke" blogpost, inderdaad een fysieke taak is: strengheid, esthetiek, logica... Het draait allemaal om overweging.

Elke keer dat ik de code plaats, vind ik het te lang, maar ik ben terughoudend om het vouwgereedschap te gebruiken dat bij de blogtuin hoort. Daarom voegde de auteur in deze blogpost voorzichtig enkele JQuery-elementen toe om een soepele vouwing van de code te bereiken, en er is nog steeds een klein gevoel van voldoening, hehe (JQuery rookie, lach niet om de meester~). Maar ik weet niet of dit echt de leesbaarheid van het artikel verbetert, en lezers en vrienden zijn welkom om te reageren :)

Deze maand besloot de auteur echt wortel te schieten in de blogtuin, dus heb ik veel vrije tijd besteed aan het schrijven van blogposts. Toen ik voor het eerst een blog schreef, hoewel er weinig reacties waren, hadden de meeste logs een klikpercentage van meer dan 500, wat voor mij een kleine aanmoediging was! Het vergt wel moed om content over microcontrollers in de blogtuin te publiceren, maar ik blijf eraan~

De negen blogposts van het begin tot nu richten zich op het gebruik van basishardwaremodules op de CC2430-chip. Tot nu toe zijn we eigenlijk door de meeste randapparatuur op de CC2430 gegaan, maar er zijn nog steeds zaken zoals Flash-toegang, willekeurige getallengenerator, AES-coprocessor, RF-communicatie, enzovoort, waar nog niet op ingegaan. De Zigbee-reis is echter nog niet voorbij, en de auteur is van plan deze weglatingen selectief in te vullen in het volgende onderwerp (implementatie van het Z-Stack-protocol).

In de volgende blogpost ben ik van plan Zigbee's eerste reis af te sluiten met een iets uitgebreider en uitgebreider experiment - "temperatuurmonitoringssysteem", en uit te leggen hoe je de eerder geleerde kennispunten volledig toepast.

In feite is het niet gekwalificeerd om "" genoemd te wordenUitlegAls beginner hoopt de auteur elkaar alleen maar aan te moedigen en samen vooruitgang te boeken in het proces van het schrijven van een doctoraat!


</n; i++)




Vorig:Zigbee Journey (8): Verschillende belangrijke CC2430 basisexperimenten - waakhonden
Volgend:Zigbee Journey (10): Uitgebreid experiment - Temperatuurmonitoringsysteem gebaseerd op CC2430
Disclaimer:
Alle software, programmeermaterialen of artikelen die door Code Farmer Network worden gepubliceerd, zijn uitsluitend bedoeld voor leer- en onderzoeksdoeleinden; De bovenstaande inhoud mag niet worden gebruikt voor commerciële of illegale doeleinden, anders dragen gebruikers alle gevolgen. De informatie op deze site komt van het internet, en auteursrechtconflicten hebben niets met deze site te maken. Je moet bovenstaande inhoud volledig van je computer verwijderen binnen 24 uur na het downloaden. Als je het programma leuk vindt, steun dan de echte software, koop registratie en krijg betere echte diensten. Als er sprake is van een inbreuk, neem dan contact met ons op via e-mail.

Mail To:help@itsvse.com