|
1. Свързване на горния и долния етаж В тази статия ще обсъдим функцията на съня и метода на събуждане на CC2430. В реалната употреба възелът CC2430 обикновено се захранва от батерии, затова контролът на неговата консумация на енергия е от решаващо значение. Следва откъс от китайското ръководство CC2430 за въвеждане на 4-те режима на консумация на енергия на CC2430:
Както се вижда от горната таблица, CC2430 има общо 4 режима на захранване:PM0(напълно буден),PM1(леко сънлив),PM2(полубуден и наполовина заспал),PM3(Спи много дълбоко). Колкото по-назад, толкова повече функции се изключват, а консумацията на енергия става все по-ниска и по-малка. Конверсионната връзка между тях е следната:
ПоставиPM1、PM2СтавайPM0, има три начина: нулиране, външно прекъсване, прекъсване на таймер за сън; Но да се сложиPM3СтавайPM0, има само два начина: нулиране, външно прекъсване (това е защото вPM3Всички осцилатори спряха да работят, а таймерът за сън беше изключен~) Нека минем през малък експеримент, за да въведем как да влезем в режим на сън и как да се събудимPM0щат. 2. Систематичен сън и експерименти с прекъснато събуждане(1) Въведение в експериментаИнициализация на системата, вPM0
→ влезPM1
→ Събуждайте се по таймера за сън след 1 секундиPM0
→ влезPM2
→ беше събуден от таймера за сън след 2 секундиPM0
→ влезPM3
→ Изчакайте бутона S1 да бъде натиснат, което задейства външно прекъсване и се събудиPM0
(2) Схема на потока на програмата
(Забележка: Заобленото поле на изображението по-горе показва здравословното състояние на системата)
(3) Експериментален изходен код и анализ (Следните полета могат да бъдат кликнати~)Заглавен файл и макро дефиниция[url=]
[/url]
/* Описание на експеримента: Експеримент за прекъснат сън при събуждане, който въвежда будност в три режима на сън
*/
#include #define LED_ON 0 #define LED_OFF 1#defineled1 P1_0
#defineLED2 P1_1
#defineled3 P1_2
#defineLED4 P1_3 [url=] [/url]
Подфункции[url=] [/url]
/*Инициализация на системния часовник -------------------------------------------------------*/
Празнотаxtal_init(Празнота)
{ СЪН &= ~0x04; //Всички са захранвани
докато(! (СЪН &0x40)); //Кристалният осцилатор е включен и стабилен
CLKCON &= ~0x47; //Изберете кристален осцилатор с честота 32MHz
СЪН |=0x04;
}
/*Инициализация на LED -------------------------------------------------------*/
Празнотаled_init(Празнота)
{ P1SEL =0x00; //P1 е нормалният I/O порт
P1DIR |=0x0F; //P1.0 P1.1 P1.2 P1.3 изход
led1 = LED_OFF; //Изключете всички LED светлини
led2 = LED_OFF; led3 = LED_OFF; led4 = LED_OFF;
}
/*Инициализация на външни прекъсвания -------------------------------------------------------*/
Празнотаio_init(Празнота)
{ P0INP &= ~0X02; //P0.1 има набиране нагоре и издърпане надолу
EA =1; //Пълно прекъсване е позволено
IEN1 |= 0X20; //P0IE = 1, P0 прекъсвания активират
ПИКТЛ |= 0X09; //P0.1 позволява прекъсвания, изключване на ръбове
P0IFG &= ~0x02; //P0.1 Прекъсване на марк clear0
}
/*Инициализация на прекъсване на таймер за сън -------------------------------------------------------*/
ПразнотаsleepTimer_init(Празнота)
{ STIF=0; //Знакът за прекъсване на таймера за сън е чист 0
STIE=1; //Включи таймера за сън прекъснат
EA=1; //Отворете тоталното прекъсване
}
/*Задайте планирания интервал за таймера за сън -------------------------------------------------------*/
ПразнотаsetSleepTimer(без знакintsec)
{ без подписДългоsleepTimer =0;
sleepTimer |= ST0; //Вземете бройната стойност на текущия таймер за сън
sleepTimer |= (без знакДълго)ST1 <<8; sleepTimer |= (без знакДълго)ST2 <<16;
sleepTimer += ((без знакДълго)sec * (без знакДълго)32768); //Плюс необходимата продължителност на времето
ST2 = (без знакЧар)(sleepTimer >>16); //Задайте сравнителната стойност на таймера за сън
ST1 = (без знакЧар)(sleepTimer >>8); ST0 = (без знакЧар)sleepTimer;
}
/*Изберете режим на захранване -------------------------------------------------------*/
ПразнотаPowerMode (без знакЧаррежим)
{
ако(режим <4) { СЪН &=0xfc; //Изчистете SLEEP.MODE до 0
SLEEP |= режим; //Изберете режим на захранване
PCON |=0x01; //Активирайте този режим на захранване
}
}
/*Функция на забавяне -------------------------------------------------------*/
ПразнотаDelay(без знак)intn)
{ без подписinti,j;
за(i=0; I<N; i++)
за(j=0; j <1000; j++);
}
[url=] [/url]
Основна функция[url=] [/url]
/*Основна функция -------------------------------------------------------*/
Празнотаосновно(Празнота)
{ xtal_init(); led_init();
//Статус на PM0, светлината включена и забавяне
led1 = LED_ON; //Яркост LED1 показва, че системата работи в PM0 режим
Забавяне(10);
//Състояние PM1, светлините изгасени
setSleepTimer(1); //Задайте времевия интервал на таймера за сън на 1s
sleepTimer_init(); //Включи таймера за сън прекъснат
led1 = LED_OFF; PowerMode(1); //Настрой режима на захранване на PM1
//След 1 секунди PM1 влиза в PM0, светва и забавя
led1 = LED_ON; Забавяне(50);
//PM2, светлините изгасени
setSleepTimer(2); //Настройте времевия интервал за таймера за сън на 2 секунди
led1 = LED_OFF; PowerMode(2); //Настрой режима на захранване на PM2
//След 2 секунди PM2 влиза в PM0, светва и забавя
led1=0; Забавяне(50);
//PM3, светлините изгасват
io_init(); //Инициализиране на външни прекъсвания
led1 = LED_OFF; PowerMode(3); //Настрой режима на захранване на PM3
//Когато възникне външно прекъсване, PM3 влиза в PM0 и се включва
led1 = LED_ON;
докато(1);
}
[url=] [/url]
Процедури за прекъсване на обслужване[url=] [/url]
/*Програма за външна услуга за прекъсване -------------------------------------------------------*/
#pragmaвектор = P0INT_VECTOR __interruptПразнотаP0_ISR(Празнота)
{ EA =0; //Портата е прекъсната
Забавяне(50);
ако((P0IFG &0x02) >0) //Клавишите са прекъснати
{ P0IFG &= ~0x02; //P0.1 Прекъсване на марк clear0
} P0IF =0; //P0 означава прекъсване clear0
EA =1; //Отворено прекъсване
}
/*Таймерът за сън прекъсва сервизните програми -------------------------------------------------------*/
#pragmavector= ST_VECTOR __interruptПразнотаsleepTimer_IRQ(Празнота)
{ EA=0; //Портата е прекъсната
STIF=0; //Знакът за прекъсване на таймера за сън е чист 0
EA=1; //Отворено прекъсване
}
[url=] [/url]
Как да използвате таймер за събуждане на системата може да се обобщи така:Отваряне на таймера за сън → задаване на интервала на таймера за сън → настройка на режим на захранване (Забележка: Стъпката "Задайте интервала на таймера за сън" трябва да е преди "Set Power Mode", защото системата няма да продължи да изпълнява програмата след влизане в режим на заспиване) След това нека се съсредоточим върху подфункцията, която задава интервала на таймера за сън:setSleepTimer Първо, кратко въведение в таймера за сън: той работи на32.768kHzна24-то мястоТаймер, когато системата работиОсвен PM3Във всички режими на захранване таймерът за сън ще бъдеНепрекъсната експлоатация。 Регистрите, използвани от таймерите за сън, са:ST0,ST1,ST2。 Следва подробно въведение в функциите ѝ от китайския наръчник CC2430:
Може да се види, че техните функции включват два аспекта:Прочетете,Пиши。 Прочетете: Използва се за четене на стойността на текущия таймер, реда, в който трябва да се следват показанията:Прочети ST0 → Прочети ST1 → Прочети ST2 Пиши: Използва се за задаване на сравнителната стойност на таймера (когато стойността на таймера = стойност на сравнение, възниква прекъсване), редът на писане трябва да следва:Пишете ST2 → пишете ST1 → пишете ST0 Добре, нека го обясним в комбинация с изходния код: (1) Първо, дефинирайте беззнаков дълъг променлив (32-битов) таймер на сън, който да получи текущата стойност на броя на таймера за сън: без подписДългоsleepTimer =0;
sleepTimer |= ST0; //Вземете бройната стойност на текущия таймер за сън
sleepTimer |= (без знакДълго)ST1 <<8; sleepTimer |= (без знакДълго)ST2 <<16;
(2) След това добавете необходимия времеви интервал: sleepTimer += ((без знакДълго)sec * (без знакДълго)32768); //Плюс необходимата продължителност на времето
Ето малко обяснение: Защо 1 означава 32768? Тъй като таймерът работи под 32.768kHz, отнема 1/32768 с за всяка добавена 1 секунда към таймера; Добави 32768 и ще ти трябват 1s; (3) Накрая, стойността на sleepTimer се използва като сравнителна стойност на таймера: ST2 = (без знакЧар)(sleepTimer >>16); //Задайте сравнителната стойност на таймера за сън
ST1 = (без знакЧар)(sleepTimer >>8); ST0 = (без знакЧар)sleepTimer;
По този начин можете успешно да зададете времевия период на таймера~ (Забележка: Що се отнася до другите части на изходния код, вярвам, че в комбинация с подробни анотации лесно можете да разберете и няма да го повтарям тук) (4) Експериментални резултатиПри изпълнение на програма, наблюдавайки LED1, явлението е:LED1 мига (т.е. включва се > изключва 1 път), мига отново след 1 секунди, след 2 секунди, после остава изключен и след това натиска S1, LED1 светва. Експерименталният феномен е напълно съвместим с очакването, Край~
3. ЗаключениеО~ След като отделих 2 свободни дни, най-накрая получих този дневник. Наистина открих, че писането на блог, особено "приятелски настроен към читателя" блог пост, наистина е физическа работа: строгост, естетика, логика... Всичко е въпрос на обмисляне. Всеки път, когато публикувам кода, мисля, че е твърде дълъг, но се колебая да използвам сгъваемия инструмент, който идва с блог градината. Затова в този блог пост авторът предпазливо добави някои елементи на JQuery, за да постигне плавно сгъване на кода, и все още има малко чувство на постижение, хе-хе (JQuery rookie, не се смейте на майстора~). Но не знам дали това наистина подобрява четивността на статията и читателите и приятелите са добре дошли да коментират :) Този месец авторът наистина реши да пусне корени в блог градината, затова прекарах много свободно време в писане на блог постове. Когато за първи път написах блог, макар че коментарите бяха малко, повечето логове имаха процент кликвания над 500, което беше малко насърчение за мен! Изисква се смелост да публикуваш съдържание за микроконтролери в блог градината, но ще се придържам към него~ Деветте блог публикации от началото до днес се фокусират върху използването на основни хардуерни модули на чипа CC2430. Досега сме преминали през повечето периферни устройства на CC2430, но все още има неща като достъп до Flash, генератор на случайни числа, AES копроцесор, RF комуникация и др., които не са били разгледани. Въпреки това, пътуването на Zigbee не е приключило и авторът възнамерява селективно да запълни тези пропуски в следващата тема (реализацията на протокола Z-Stack). В следващата публикация планирам да завърша първото пътуване на Зигби с малко по-обширен и разширен експеримент – "система за мониторинг на температурата" и да обясня как цялостно да приложим научените по-рано знания. Всъщност, не е квалифицирано да бъде наречено "ОбяснениеКато начинаещ, авторът се надява само да се насърчава взаимно и да напредва заедно в процеса на писане на докторска степен! </n; i++)
|