|
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:ST0,ST1,ST2。 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:Lue,kirjoita。 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 tuloksetOhjelmaa 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ösOi~ 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++)
|