|
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(Порожнеча)
{ SLEEP &= ~0x04; //Всі вони працюють на електропостачанні
поки(! (SLEEP &0x40)); //Кристалічний осцилятор увімкнений і стабільний
CLKCON &= ~0x47; //Виберіть кристалічний осцилятор на 32 МГц
СОН |=0x04;
}
/*Ініціалізація світлодіодів -------------------------------------------------------*/
Порожнечаled_init(Порожнеча)
{ P1SEL =0x00; //P1 — це звичайний порт введення/виведення
P1DIR |=0x0F; //P1.0 P1.1 P1.2 P1.3 вихід
led1 = LED_OFF; //Вимкніть усі світлодіоди
led2 = LED_OFF; led3 = LED_OFF; led4 = LED_OFF;
}
/*Ініціалізація зовнішнього переривання -------------------------------------------------------*/
Порожнечаio_init(Порожнеча)
{ P0INP &= ~0X02; //P0.1 має підтягування вгору і підтягування вниз
EA =1; //Дозволено повне переривання
IEN1 |= 0X20; //P0IE = 1, P0 переривання вмикаються
PICTL |= 0X09; //P0.1 дозволяє переривання, тригери drop edge
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 = (без знакуchar)(sleepТаймер >>16); //Встановіть порівняльне значення таймера сну
ST1 = (без знакуchar)(sleepТаймер >>8); ST0 = (без знакуchar)sleepTimer;
}
/*Виберіть режим живлення -------------------------------------------------------*/
ПорожнечаPowerMode (без знакуcharрежим)
{
якщо(режим <4) { SLEEP &=0xfc; //Очистити SLEEP.MODE до 0
SLEEP |= режим; //Виберіть режим живлення
PCON |=0x01; //Увімкніть цей режим живлення
}
}
/*Функція затримки -------------------------------------------------------*/
ПорожнечаЗатримка (без знаку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; //Відкрите переривання
}
/*Таймер сну перериває сервісні програми -------------------------------------------------------*/
#pragmaвектор= ST_VECTOR __interruptПорожнечаsleepTimer_IRQ(Порожнеча)
{ EA=0; //Ворота перериваються
STIF=0; //Позначка переривання таймера сну чиста 0
EA=1; //Відкрите переривання
}
[url=] [/url]
Як використати таймер сну для пробудження системи, можна підсумувати так:Відкрити таймер сну переривати → встановити інтервал таймера сну → встановити режим живлення (Примітка: крок «Встановити інтервал таймера сну» має бути перед «Встановити режим живлення», оскільки система не продовжить виконання програми після переходу в сон) Далі зосередьмося на підфункції, яка встановлює інтервал таймера сну:setSleepTimer Перш за все, коротке знайомство з таймером сну: він працює на32,768 кГцз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); //Плюс необхідна тривалість таймінгу
Ось невелике пояснення: Чому 1s означає 32768? Оскільки таймер працює нижче 32,768 кГц, на кожен доданий 1 секунд до таймера витрачається 1/32768 с; Додайте 32768 — і вам знадобляться 1s; (3) Нарешті, значення sleepTimer використовується як порівняльне значення таймера: ST2 = (без знакуchar)(sleepТаймер >>16); //Встановіть порівняльне значення таймера сну
ST1 = (без знакуchar)(sleepТаймер >>8); ST0 = (без знакуchar)sleepTimer;
Таким чином, ви можете успішно встановити таймінг-період таймера~ (Примітка: Щодо інших частин вихідного коду, я вважаю, що в поєднанні з детальними анотаціями ви легко зрозуміли, і я не буду повторювати це тут) (4) Експериментальні результатиЗапускаючи програму, спостерігаючи LED1, явище таке:LED1 блимає (тобто вмикається > вимикається один раз), миготить знову через 1 секунду, знову блимає через 2 секунди, потім залишається вимкненим, а потім натискає S1 — LED1 загоряється. Експериментальне явище повністю відповідає очікуванням, Over~
3. ВисновокОх~ Після двох днів вільного часу я нарешті отримав цей журнал. Я справді зрозуміла, що написання блогу, особливо «дружнього до читача» блогу, — це справді фізична робота: строгість, естетика, логіка... Все залежить від уваги. Кожного разу, коли я публікую код, мені здається, що він занадто довгий, але я неохоче користуюся складним інструментом, який йде в комплекті з блогом garden. Тому в цьому блозі автор обережно додав деякі елементи JQuery, щоб забезпечити плавне складання коду, і все ще відчувається невелике відчуття досягнення, хе-хе (JQuery rookie, не смійтеся над майстром~). Але не знаю, чи це справді покращує читабельність статті, і читачі та друзі можуть залишати коментарі :) Цього місяця автор справді вирішив укорінитися в блог-саді, тож я витратив багато вільного часу на написання блог-постів. Коли я вперше писав блог, хоча коментарів було мало, більшість журналів мали коефіцієнт кліків понад 500, що було для мене невеликим підбадьоренням! Потрібна сміливість, щоб публікувати контент про мікроконтролери в блоговому саду, але я дотримуватимусь цього~ Дев'ять дописів у блозі від початку до сьогодні зосереджені на використанні базових апаратних модулів на чипі CC2430. Поки що ми фактично пройшли більшість периферійних пристроїв CC2430, але все ще є такі речі, як доступ до Flash, генератор випадкових чисел, співпроцесор AES, радіочастотний зв'язок тощо, які не були порушені. Однак шлях Zigbee ще не завершений, і автор має намір вибірково заповнити ці прогалини в наступній темі (реалізація протоколу Z-Stack). У наступному блозі я планую завершити першу поїздку Зігбі трохи більш повним і розширеним експериментом — «система моніторингу температури» та пояснити, як комплексно застосовувати отримані раніше знання. Насправді, він не має права називатися «ПоясненняЯк початківець, автор лише сподівається підтримувати одне одного і разом досягати прогресу у написанні докторської дисертації! </n; i++)
|