Tämä artikkeli on konekäännöksen peiliartikkeli, klikkaa tästä siirtyäksesi alkuperäiseen artikkeliin.

Näkymä: 9371|Vastaus: 0

Zigbee Journey (9): Useita tärkeitä perus CC2430-kokeita – systemaattinen uni ja keskeytetty valveillaolo

[Kopioi linkki]
Julkaistu 30.10.2014 23.24.30 | | | |
1. Ylä- ja alakerrosten yhdistäminen

Tässä artikkelissa käsittelemme CC2430:n unitoimintoa ja herätysmenetelmää. Todellisessa käytössä CC2430-solmu saa yleensä virtansa paristoista, joten sen virrankulutuksen hallinta on ratkaisevan tärkeää.

Seuraavassa on ote CC2430:n kiinalaisesta käsikirjasta CC2430:n neljän virrankulutustilan esittelyä varten:

Kuten yllä olevasta taulukosta näkyy, CC2430:ssa on yhteensä 4 tehotilaa:PM0(täysin hereillä),PM1(hieman uninen),PM2(puoliksi hereillä ja puoliksi unessa),PM3(Nukkui hyvin syvästi). Mitä kauemmas taaksepäin, sitä useammat toiminnot pois päältä ja virrankulutus vähenee koko ajan. Niiden välinen konversiosuhde on seuraava:

putPM1、PM2HerätäPM0, on kolme tapaa: nollaus, ulkoinen keskeytys, uniajastimen keskeytys; Mutta laitaPM3HerätäPM0, on olemassa vain kaksi tapaa: nollaus, ulkoinen keskeytys (tämä johtuu siitä, että inPM3Kaikki oskillaattorit lakkasivat toimimasta, ja tietysti uniajastin oli pois päältä~)

Käydään läpi pieni koe, jossa esitellään, miten siirrytään lepotilaan ja miten herätäänPM0Osavaltio.

2. Järjestelmälliset uni ja keskeytetyt herätyskokeet(1) Johdanto kokeeseenJärjestelmän alustus,PM0
→ sisäänPM1
→ Herää uniajastimen luona 1 sekunnin jälkeenPM0
→ sisäänPM2
→ heräsi uniajastimella kahden sekunnin jälkeenPM0
→ sisäänPM3
→ Odota, että S1-näppäin painetaan, mikä laukaisee ulkoisen keskeytyksen ja herääPM0
(2) Ohjelman vuokaavio

(Huomautus: Yllä olevassa kuvassa oleva pyöristetty laatikko osoittaa järjestelmän kuntotilan)

(3) Kokeellinen lähdekoodi ja analyysi (Seuraavia ruutuja voi klikata~Otsikkotiedosto ja makromäärittely[url=] [/url]
/*
    Kokeellinen kuvaus: Keskeytetyn herätyksen koe, joka esittelee valveillaolon kolmessa unimoodissa
*/

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

Alatoiminnot[url=] [/url]
/*Järjestelmän kellon alustus
-------------------------------------------------------
*/
voidxtal_init(void)
{
  UNI &= ~0x04;            //Kaikki ovat voimalla toimivia
  kun(! (UNI &0x40));     //Kideoskillaattori on päällä ja vakaa
  CLKCON &= ~0x47;         //Valitse 32MHz:n kideoskillaattori
  UNI |=0x04;
}


/*LED-alustus
-------------------------------------------------------
*/
voidled_init(void)
{
  P1SEL =0x00;         //P1 on tavallinen I/O-portti
  P1DIR |=0x0F;         //P1.0 P1.1 P1.2 P1.3 ulostulo
  
  led1 = LED_OFF;         //Kytke kaikki LEDit pois päältä
  led2 = LED_OFF;
  led3 = LED_OFF;
  led4 = LED_OFF;
}


/*Ulkoisen keskeytyksen alustus
-------------------------------------------------------
*/
voidio_init(void)
{
    P0INP &= ~0X02;   //P0.1:ssä on leuanveto ylös ja alas

    EA =1;           //Täysi keskeytys sallittu
   
    IEN1 |=  0X20;   //P0IE = 1, P0-keskeytykset otetaan käyttöön
   
    KUVA |=  0X09;   //P0.1 sallii keskeytykset, drop edge -laukaisimet
   
    P0IFG &= ~0x02;   //P0.1 Keskeytysmerkki clear0
}


/*Uniaikastimen keskeytyksen alustus
-------------------------------------------------------
*/
voidsleepTimer_init(void)
{
  STIF=0;   //Uniajastimen keskeytysmerkki on selkeä 0
   
  STIE=1;   //Laita päälle uniajastin keskeytetty
   
  EA=1;     //Avaa koko keskeytys
}


/*Aseta aikataulutettu väli uniajastimelle
-------------------------------------------------------
*/
voidsetSleepTimer(allekirjoittamatonintsec)
{
  AllekirjoittamatonpitkäsleepTimer =0;
  
  sleepTimer |= ST0;                     //Hanki nykyisen uniajan lukumääräarvo
  sleepTimer |= (allekirjoittamatonpitkä)ST1 <<8;
  sleepTimer |= (allekirjoittamatonpitkä)ST2 <<16;
  
  sleepTimer += ((allekirjoittamatonpitkä)sec * (allekirjoittamatonpitkä)32768);   //Lisäksi vaadittu ajoitusaika
  
  ST2 = (allekirjoittamatonchar)(sleepTimer >>16);   //Aseta uniajastimen vertailuarvo
  ST1 = (allekirjoittamatonchar)(sleepTimer >>8);
  ST0 = (allekirjoittamatonchar)sleepTimer;
}


/*Valitse virtatila
-------------------------------------------------------
*/
voidPowerMode (allekirjoittamatonchartila)
{
  jos(tila <4)
  {
    UNI &=0xfc;      //Tyhjennä SLEEP.MODE nollaan
    SLEEP |= tila;      //Valitse virtatila
    PCON |=0x01;        //Ota tämä virtatila käyttöön
  }
}


/*Viivefunktio
-------------------------------------------------------
*/
voidViive (allekirjoittamatonintn)
{
  Allekirjoittamatoninti,j;
  for(i=0; i<n; i++)
    for(j=0; j <1000; j++);
}
[url=] [/url]

Päätehtävä[url=] [/url]
/*Päätehtävä
-------------------------------------------------------
*/
voidpää(void)
{
  xtal_init();         
  led_init();         
  
  //PM0-tila, valo päällä ja viive
  led1 = LED_ON;         //Kirkkaus-LED1 osoittaa, että järjestelmä toimii PM0-tilassa
  Viive(10);


  //PM1-tila, valot pois päältä
  setSleepTimer(1);      //Aseta uniajastimen aikaväli 1 sekunniksi
  sleepTimer_init();     //Laita päälle uniajastin keskeytetty
  led1 = LED_OFF;
  PowerMode(1);         //Aseta virtatilaksi PM1
  
  
//1 sekunnin jälkeen PM1 siirtyy PM0:aan, syttyy ja viivästyy.
  led1 = LED_ON;
  Viive(50);
  
  //PM2, valot pois
  setSleepTimer(2);      //Aseta uniajastimen aikaväli 2 sekunniksi
  led1 = LED_OFF;
  PowerMode(2);         //Aseta virtatilaksi PM2


  
//Kahden sekunnin jälkeen PM2 siirtyy PM0:aan, syttyy ja viivästyy.
  led1=0;
  Viive(50);
  
  //PM3, valot pois  
  io_init();            //Aloita ulkoiset keskeytykset
  led1 = LED_OFF;
  PowerMode(3);         //Aseta virtatilaksi PM3
  
  
//Kun ulkoinen keskeytys tapahtuu, PM3 siirtyy PM0:aan ja syttyy
  led1 = LED_ON;

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

Keskeytyspalvelumenettelyt[url=] [/url]
/*Ulkoinen keskeytyspalveluohjelma
-------------------------------------------------------
*/
#pragmavektori = P0INT_VECTOR
__interruptvoidP0_ISR(void)
{
  EA =0;                        //Portti keskeytyy
  
  Viive(50);

  jos((P0IFG &0x02) >0)         //Näppäimet keskeytyvät
  {
    P0IFG &= ~0x02;               //P0.1 Keskeytysmerkki clear0
  }
  P0IF =0;                       //P0 keskeytysmerkki clear0


  EA =1;                        //Avoin keskeytys
}


/*Uniajastin keskeyttää palveluohjelmat
-------------------------------------------------------
*/
#pragmavektori= ST_VECTOR
__interruptvoidsleepTimer_IRQ(void)
{
  EA=0;     //Portti keskeytyy
   
  STIF=0;   //Uniajastimen keskeytysmerkki on selkeä 0
  
  EA=1;     //Avoin keskeytys
}
[url=] [/url]

Miten uniajastinta käytetään järjestelmän herättämiseen, voidaan tiivistää seuraavasti:Avaa uniajastimen keskeytys → aseta lepoajastimen ajoitusväli → säädä virtatila

(Huom: "Aseta lepoajastin väli" -vaihe tulee olla ennen "Aseta virtatila", koska järjestelmä ei jatka ohjelman suorittamista lepotilaan jälkeen)

Seuraavaksi keskitytään alifunktioon, joka asettaa uniajastimen välin:setSleepTimer

Ensinnäkin, lyhyt johdanto uniajastimesta: se toimii32.768kHzof24. sijaAjastin, kun järjestelmä on käynnissäPM3:n lisäksiKaikissa virtatiloissa lepoajastin onKeskeytymätön toiminta

Uniajastimien käyttämät rekisterit ovat:ST0ST1ST2。 Seuraavassa on yksityiskohtainen johdatus sen toimintoihin CC2430:n kiinalaisesta käsikirjasta:

On nähtävissä, että niiden toiminnot sisältävät kaksi osa-aluetta:Luekirjoita

  Lue: Käytetään lukemaan nykyisen ajastimen lukumääräarvon, jossa lukemat tulee noudattaa:Lue ST0 → Lue ST1 → Lue ST2

  kirjoita: Kun ajastimen vertailuarvo asetetaan (kun ajastimen lukumäärä = vertailuarvo, tapahtuu keskeytys), kirjoitusjärjestyksen on noudatettava seuraavaa:Kirjoita ST2 → kirjoita ST1 → kirjoittaa ST0

Selitetäänpä se yhdessä lähdekoodin kanssa:

(1) Määritellään ensin allekirjoittamaton pitkä muuttuja (32-bittinen) sleepTimer, joka vastaanottaa uniajastimen nykyisen lukumäärän:

  AllekirjoittamatonpitkäsleepTimer =0;
  
  sleepTimer |= ST0;                     //Hanki nykyisen uniajan lukumääräarvo
  sleepTimer |= (allekirjoittamatonpitkä)ST1 <<8;
  sleepTimer |= (allekirjoittamatonpitkä)ST2 <<16;

(2) Lisää sitten vaadittu aikaväli:

  sleepTimer += ((allekirjoittamatonpitkä)sec * (allekirjoittamatonpitkä)32768);   //Lisäksi vaadittu ajoitusaika

Tässä pieni selitys:

Miksi ykköset edustavat 32768:aa? Koska ajastin toimii alle 32,768 kHz, se vie 1/32768 s jokaista lisättyä ajastimeen lisättyä 1 sekuntia kohden; Lisää 32768, niin tarvitset 1:t;

(3) Lopuksi sleepTimer-arvoa käytetään ajastimen vertailuarvona:

  ST2 = (allekirjoittamatonchar)(sleepTimer >>16);   //Aseta uniajastimen vertailuarvo
  ST1 = (allekirjoittamatonchar)(sleepTimer >>8);
  ST0 = (allekirjoittamatonchar)sleepTimer;

Näin voit onnistuneesti asettaa ajastimen ajoituksen~

(Huomautus: Mitä tulee muihin lähdekoodin osiin, uskon, että yhdistettynä yksityiskohtaisiin merkintöihin on helppo ymmärtää, enkä aio toistaa sitä tässä)

(4) Kokeelliset tulokset
Ohjelmaa ajaessa, LED1:n havainnoinnissa, ilmiö on:LED1 vilkkuu (eli päälle > pois yhden kerran), vilkkuu uudelleen 1 sekunnin jälkeen, vilkkuu uudelleen kahden sekunnin jälkeen, pysyy pois päältä, ja painaa S1:tä, LED1 syttyy.
Kokeellinen ilmiö on täysin yhdenmukainen odotuksen kanssa, Yli~

3. Johtopäätös

Oi~ Kahden vapaapäivän jälkeen sain vihdoin tämän lokin. Huomasin todella, että blogin kirjoittaminen, erityisesti "lukijaystävällisen" blogikirjoituksen, on todellakin fyysinen tehtävä: tarkkuus, esteettisyys, logiikka... Kyse on harkinnasta.

Joka kerta kun julkaisen koodin, se tuntuu liian pitkältä, mutta epäröin käyttää blogipuutarhan mukana tulevaa taittotyökalua. Siksi tässä blogikirjoituksessa kirjoittaja lisäsi varovaisesti joitakin JQueryn elementtejä koodin sulavan taittelun saavuttamiseksi, ja silti on pieni saavutuksen tunne, hehe (JQuery-aloittelija, älä naura mestarille~). Mutta en tiedä, parantaako tämä artikkelin luettavuutta, ja lukijat sekä ystävät ovat tervetulleita kommentoimaan :)

Tänä kuukautena kirjoittaja päätti todella juurtua blogipuutarhaan, joten käytin paljon vapaa-aikaa blogikirjoitusten kirjoittamiseen. Kun kirjoitin blogia ensimmäistä kertaa, vaikka kommentteja oli vähän, useimmissa lokeissa oli yli 500 klikkausprosentti, mikä oli minulle pieni kannustus! Mikrokontrollereista kertovien sisältöjen julkaiseminen blogipuutarhassa vaatii rohkeutta, mutta pysyn siinä~

Alusta tähän päivään julkaistut yhdeksän blogikirjoitusta keskittyvät peruslaitteistomoduulien käyttöön CC2430-piirissä. Tähän mennessä olemme käytännössä käyneet läpi suurimman osan CC2430:n oheislaitteista, mutta on edelleen asioita kuten Flash-käyttö, satunnaislukugeneraattori, AES-koprosessori, RF-viestintä jne., joita ei ole käsitelty. Zigbeen matka ei kuitenkaan ole ohi, ja kirjoittaja aikoo valikoivasti täydentää nämä puutteet seuraavassa aiheessa (Z-Stack-protokollan toteutus).

Seuraavassa blogikirjoituksessa aion päättää Zigbeen ensimmäisen matkan hieman kattavammalla ja laajemmalla kokeella – "lämpötilan seurantajärjestelmällä" – ja selittää, miten aiemmin opittuja tietopisteitä voi soveltaa kattavasti.

Itse asiassa sitä ei voi kutsua "SelitysAloittelijana kirjoittaja toivoo vain kannustavansa toisiaan ja edistyvänsä yhdessä tohtorintutkinnon kirjoittamisessa!


</n; i++)




Edellinen:Zigbee Journey (8): Useita tärkeitä CC2430-peruskokeita – vahtikoirat
Seuraava:Zigbee Journey (10): Kattava koe – lämpötilan seurantajärjestelmä CC2430:n pohjalta
Vastuuvapauslauseke:
Kaikki Code Farmer Networkin julkaisemat ohjelmistot, ohjelmamateriaalit tai artikkelit ovat tarkoitettu vain oppimis- ja tutkimustarkoituksiin; Yllä mainittua sisältöä ei saa käyttää kaupallisiin tai laittomiin tarkoituksiin, muuten käyttäjät joutuvat kantamaan kaikki seuraukset. Tämän sivuston tiedot ovat peräisin internetistä, eikä tekijänoikeuskiistat liity tähän sivustoon. Sinun tulee poistaa yllä oleva sisältö kokonaan tietokoneeltasi 24 tunnin kuluessa lataamisesta. Jos pidät ohjelmasta, tue aitoa ohjelmistoa, osta rekisteröityminen ja hanki parempia aitoja palveluita. Jos rikkomuksia ilmenee, ota meihin yhteyttä sähköpostitse.

Mail To:help@itsvse.com