Acest articol este un articol oglindă al traducerii automate, vă rugăm să faceți clic aici pentru a sări la articolul original.

Vedere: 9371|Răspunde: 0

Călătoria Zigbee (9): Câteva experimente importante de bază CC2430 - somnul sistematic și starea de veghe întreruptă

[Copiază linkul]
Postat pe 30.10.2014 23:24:30 | | | |
1. Conectarea nivelurilor superioare și inferioare

În acest articol, vom discuta despre funcția de somn și metoda de trezire a CC2430. În utilizarea reală, nodul CC2430 este în general alimentat de baterii, așa că controlul consumului său de energie este crucial.

Următorul este un fragment din manualul chinezesc CC2430 pentru introducerea celor 4 moduri de consum de energie ale CC2430:

După cum puteți vedea din tabelul de mai sus, CC2430 are în total 4 moduri de alimentare:PM0(complet treaz),PM1(puțin somnoros),PM2(pe jumătate treaz și pe jumătate adormită),PM3(Dormind foarte greu). Cu cât mai în spate, cu atât mai multe funcții sunt dezactivate, iar consumul de energie este din ce în ce mai mic. Relația de conversie dintre ele este următoarea:

punePM1、PM2Trezeşte-tePM0, există trei moduri: resetare, întrerupere externă, întrerupere a temporizatorului de somn; Dar punePM3Trezeşte-tePM0, există doar două moduri: reset, întrerupere externă (acest lucru se datorează faptului că înPM3Toate oscilatoarele s-au oprit din funcționare, iar desigur cronometrul de repaus a fost oprit~)

Hai să trecem printr-un mic experiment pentru a introduce cum să intri în modul de repaus și cum să te trezeștiPM0State.

2. Experimente de somn sistematic și trezire întreruptă(1) Introducere în experimentInițializarea sistemului, înPM0
→ intrăPM1
→ Trezește-te după timerul de somn după 1 secundăPM0
→ intrăPM2
→ fost trezit de timerul de somn după 2 secundePM0
→ intrăPM3
→ Așteaptă apăsarea tastei S1, declanșând o întrerupere externă și trezindu-tePM0
(2) Diagramă de flux a programului

(Notă: Caseta rotunjită din imaginea de mai sus indică starea de sănătate a sistemului)

(3) Cod sursă experimental și analiză (Următoarele casete pot fi apăsate~Definiția fișierului de antet și a macro-urilor[url=] [/url]
/*
    Descriere experimentală: Experimentul somnului trezitor întrerupt, care introduce starea de veghe în trei moduri de somn
*/

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

Subfuncții[url=] [/url]
/*Inițializarea ceasului sistemului
-------------------------------------------------------
*/
Voidxtal_init(Void)
{
  SOMN &= ~0x04;            //Toate sunt alimentate
  în timp ce(! (SOMN &0x40));     //Oscilatorul cu cristal este pornit și stabil
  CLKCON &= ~0x47;         //Alege un oscilator cu cristal de 32MHz
  SLEEP |=0x04;
}


/*Inițializarea LED-urilor
-------------------------------------------------------
*/
Voidled_init(Void)
{
  P1SEL =0x00;         //P1 este portul normal de I/O
  P1DIR |=0x0F;         //Ieșire P1.0 P1.1 P1.2 P1.3
  
  a condus1 = LED_OFF;         //Oprește toate LED-urile
  a condus2 = LED_OFF;
  a condus3 = LED_OFF;
  conduse4 = LED_OFF;
}


/*Inițializarea întreruperii externe
-------------------------------------------------------
*/
Voidio_init(Void)
{
    P0INP &= ~0X02;   //P0.1 are tracțiune în sus și în jos

    EA =1;           //Întrerupere totală permisă
   
    IEN1 |=  0X20;   //P0IE = 1, P0 întreruperi activate
   
    PICTL |=  0X09;   //P0.1 permite întreruperi, declanșatoare de tip drop edge
   
    P0IFG &= ~0x02;   //P0.1 Marcaj de întrerupere curat0
}


/*Inițializarea întreruperii cronometrului de somn
-------------------------------------------------------
*/
VoidsleepTimer_init(Void)
{
  STIF=0;   //Semnul de întrerupere al temporizatorului de somn este clar 0
   
  STIE=1;   //Pornește cronometrul de repaus întrerupt
   
  EA=1;     //Deschide întreruperea totală
}


/*Setează intervalul programat pentru cronometrul de somn
-------------------------------------------------------
*/
VoidsetSleepTimer(nesemnatintsec)
{
  nesemnatlungsleepTimer =0;
  
  sleepTimer |= ST0;                     //Obține valoarea de numărătoare a temporizatorului actual de somn
  sleepTimer |= (nesemnatlung)ST1 <<8;
  sleepTimer |= (nesemnatlung)ST2 <<16;
  
  sleepTimer += ((nesemnatlung)sec * (nesemnatlung)32768);   //Plus durata necesară a timpului
  
  ST2 = (nesemnatChar(sleepTimer >>16);   //Setează valoarea de comparație a temporizatorului de somn
  ST1 = (nesemnatChar(sleepTimer >>8);
  ST0 = (nesemnatChar)sleepTimer;
}


/*Selectează modul de alimentare
-------------------------------------------------------
*/
VoidPowerMode(nesemnatCharmod)
{
  dacă(mod <4)
  {
    SOMN &=0xfc;      //Șterge SLEEP.MODE la 0
    SLEEP |= mod;      //Selectează modul de alimentare
    PCON |=0x01;        //Activează acest mod de putere
  }
}


/*Funcția de întârziere
-------------------------------------------------------
*/
VoidÎntârziere (nesemnatintn)
{
  nesemnatinti,j;
  pentru(i=0; i<n; i++)
    pentru(j=0; j <1000; j++);
}
[url=] [/url]

Funcția principală[url=] [/url]
/*Funcția principală
-------------------------------------------------------
*/
Voidmain(Void)
{
  xtal_init();         
  led_init();         
  
  //Stare PM0, lumină aprinsă și întârziere
  conduse1 = LED_ON;         //LED-ul de luminozitate indică faptul că sistemul funcționează în modul PM0
  Întârziere(10);


  //Starea PM1, luminile stinse
  setSleepTimer(1);      //Setează intervalul de timp al cronometrului de somn la 1 secundă
  sleepTimer_init();     //Pornește cronometrul de repaus întrerupt
  a condus1 = LED_OFF;
  PowerMode(1);         //Setează modul de alimentare pe PM1
  
  
//După 1 secundă, PM1 intră în PM0, se aprinde și întârzie
  conduse1 = LED_ON;
  Întârziere(50);
  
  //PM2, luminile stinse
  setSleepTimer(2);      //Setează intervalul de timp pentru cronometrul de somn la 2 secunde
  a condus1 = LED_OFF;
  PowerMode(2);         //Setează modul de alimentare pe PM2


  
//După 2 secunde, PM2 intră în PM0, se aprinde și întârzie
  a condus1=0;
  Întârziere(50);
  
  //PM3, luminile stinse  
  io_init();            //Inițializarea întreruperilor externe
  a condus1 = LED_OFF;
  PowerMode(3);         //Setează modul de putere pe PM3
  
  
//Când apare o întrerupere externă, PM3 intră în PM0 și se aprinde
  conduse1 = LED_ON;

  în timp ce(1);
}
[url=] [/url]

Proceduri de serviciu de întrerupere[url=] [/url]
/*Program extern de servicii de întrerupere
-------------------------------------------------------
*/
#pragmavector = P0INT_VECTOR
__interruptVoidP0_ISR(Void)
{
  EA =0;                        //Poarta este întreruptă
  
  Întârziere(50);

  dacă((P0IFG &0x02) >0)         //Tastele sunt întrerupte
  {
    P0IFG &= ~0x02;               //P0.1 Marcaj de întrerupere curat0
  }
  P0IF =0;                       //Marcaj de întrerupere P0 clear0


  EA =1;                        //Întrerupere deschisă
}


/*Cronometrul de somn întrerupe programele de serviciu
-------------------------------------------------------
*/
#pragmavector= ST_VECTOR
__interruptVoidsleepTimer_IRQ(Void)
{
  EA=0;     //Poarta este întreruptă
   
  STIF=0;   //Semnul de întrerupere al temporizatorului de somn este clar 0
  
  EA=1;     //Întrerupere deschisă
}
[url=] [/url]

Cum să folosești un cronometru de somn pentru a trezi sistemul poate fi rezumat astfel:Deschide întreruperea temporizatorului de somn → setează intervalul de timp al temporizatorului de somn → setează modul de alimentare

(Notă: Pasul "Setează intervalul timerului de repaus" trebuie să fie înainte de "Setează modul de alimentare", deoarece sistemul nu va continua să execute programul după intrarea în somn)

Apoi, să ne concentrăm pe subfuncția care setează intervalul timer de somn:setSleepTimer

În primul rând, o scurtă introducere a cronometrului de somn: funcționează32,768kHzdeLocul 24Cronometru, când sistemul funcționeazăPe lângă PM3În toate modurile de alimentare, timerul de sleep va fiFuncționare neîntreruptă

Registrele folosite de cronometroarele de somn sunt:ST0ST1ST2。 Următoarea este o introducere detaliată a funcțiilor sale din manualul chinezesc CC2430:

Se poate observa că funcțiile lor includ două aspecte:CiteșteScrie

  Citește: Folosit pentru a citi valoarea de numărare a temporizatorului curent, ordinea în care citirile trebuie urmate:Citește ST0 → Citește ST1 → Citește ST2

  Scrie: Folosită pentru a seta valoarea de comparație a cronometrului (când valoarea de număr a temporizatorului = valoarea de comparație, apare o întrerupere), ordinea de scriere trebuie să urmeze:Scrie ST2 → scrie ST1 → scrie ST0

OK, să explicăm în combinație cu codul sursă:

(1) Mai întâi, definiți un sleepTimer cu variabilă lungă nesemnată (32 de biți) pentru a primi valoarea curentă a numărătoarei de sleep timer:

  nesemnatlungsleepTimer =0;
  
  sleepTimer |= ST0;                     //Obține valoarea de numărătoare a temporizatorului actual de somn
  sleepTimer |= (nesemnatlung)ST1 <<8;
  sleepTimer |= (nesemnatlung)ST2 <<16;

(2) Apoi adaugă intervalul de timp necesar:

  sleepTimer += ((nesemnatlung)sec * (nesemnatlung)32768);   //Plus durata necesară a timpului

Iată o mică explicație:

De ce reprezintă 1s 32768? Pentru că cronometrul funcționează sub 32,768kHz, durează 1/32768 s pentru fiecare 1 adăugat la cronometru; Adaugă 32768 și vei avea nevoie de 1s;

(3) În final, valoarea sleepTimer-ului este folosită ca valoare de comparație a cronometrului:

  ST2 = (nesemnatChar(sleepTimer >>16);   //Setează valoarea de comparație a temporizatorului de somn
  ST1 = (nesemnatChar(sleepTimer >>8);
  ST0 = (nesemnatChar)sleepTimer;

Astfel, poți seta cu succes perioada de timp a cronometrului~

(Notă: În ceea ce privește celelalte părți ale codului sursă, cred că, combinate cu adnotări detaliate, puteți înțelege ușor și nu voi repeta aici)

(4) Rezultate experimentale
Rulând programul, observând LED1, fenomenul este:LED1 clipește (adică pornit-> oprit o dată), clipește din nou după 1 secundă, clipește din nou după 2 secunde, apoi rămâne oprit, apoi apasă S1, LED1 se aprinde.
Fenomenul experimental este complet în concordanță cu așteptarea, Peste~

3. Concluzie

Oh~ După ce mi-am luat 2 zile libere, în sfârșit am primit acest jurnal. Am descoperit cu adevărat că scrierea unui blog, mai ales a unei postări "prietenoase cu cititorii", este într-adevăr o muncă fizică: rigoare, estetică, logică... Totul ține de considerație.

De fiecare dată când postez codul, mi se pare prea lung, dar ezit să folosesc unealta pliabilă care vine odată cu grădina de blog. Prin urmare, în această postare pe blog, autorul a adăugat cu prudență câteva elemente JQuery pentru a realiza o pliere lină a codului, și încă există un mic sentiment de realizare, hehe (JQuery rookie, nu râde de maestru~). Dar nu știu dacă asta chiar îmbunătățește lizibilitatea articolului, iar cititorii și prietenii sunt bineveniți să comenteze :)

Luna aceasta, autoarea a decis cu adevărat să prindă rădăcini în grădina blogului, așa că am petrecut mult timp liber scriind postări pe blog. Când am scris un blog pentru prima dată, deși erau puține comentarii, majoritatea jurnalelor aveau o rată de click-uri de peste 500, ceea ce a fost o mică încurajare pentru mine! Este nevoie de curaj să publici conținut despre microcontrolere în bloggrădină, dar mă voi ține de el~

Cele nouă postări pe blog, de la început până în prezent, se concentrează pe utilizarea modulelor hardware de bază pe cipul CC2430. Până acum, am trecut practic prin majoritatea perifericelor de pe CC2430, dar mai sunt lucruri precum accesul Flash, generatorul de numere aleatoare, coprocesorul AES, comunicarea RF etc., care nu au fost atinsese. Totuși, călătoria Zigbee nu s-a încheiat, iar autorul intenționează să completeze selectiv aceste omisiuni în următorul subiect (implementarea protocolului Z-Stack).

În următoarea postare pe blog, plănuiesc să închei prima călătorie a lui Zigbee cu un experiment puțin mai cuprinzător și extins – "sistemul de monitorizare a temperaturii" – și să explic cum să aplic cuprinzător punctele de cunoaștere învățate anterior.

De fapt, nu este calificat să fie numit "ExplicațieCa începător, autorul speră doar să se încurajeze reciproc și să facă progrese împreună în procesul de scriere a unui doctorat!


</n; i++)




Precedent:Zigbee Journey (8): Câteva experimente importante de bază CC2430 - watchdogs
Următor:Zigbee Journey (10): Experiment cuprinzător - Sistem de monitorizare a temperaturii bazat pe CC2430
Disclaimer:
Tot software-ul, materialele de programare sau articolele publicate de Code Farmer Network sunt destinate exclusiv scopurilor de învățare și cercetare; Conținutul de mai sus nu va fi folosit în scopuri comerciale sau ilegale, altfel utilizatorii vor suporta toate consecințele. Informațiile de pe acest site provin de pe Internet, iar disputele privind drepturile de autor nu au legătură cu acest site. Trebuie să ștergi complet conținutul de mai sus de pe calculatorul tău în termen de 24 de ore de la descărcare. Dacă îți place programul, te rugăm să susții software-ul autentic, să cumperi înregistrarea și să primești servicii autentice mai bune. Dacă există vreo încălcare, vă rugăm să ne contactați prin e-mail.

Mail To:help@itsvse.com