Микроконтроллер ATtiny 2313. Прерывания. Можно ли настроить отмену очереди?
Всем привет.
Извиняюсь за простой вопрос, но не могу дошарить никак. По инету написано так запутано, что порой трудно разобраться даже в мелочах.
Пишу простую программку типа Hello World, нечто подобие примитивной сигнализации, логика следующая:
-
Ничего не делаем, до тех пор, пока нет возмещения (нет логической 1 с датчика - не открыта дверь)
Как только есть возмущение - бъем тревогу (на одну ногу порта D подаем лог. 1).
И бъем тревогу эту до тех пор, пока возмущение не пропадет, и еще 5 минут после этого.
Если по истечению 5 минут все спокойно, то переходим в сторожевой режим (ничего не делаем) .
-
На радиокоте посоветовали вместо мной предпологаемого While, чтобы МК не гонял бесконечные проверки для этих целей использовать прерывания.
Я понимаю, что это правильное решение, рациональное. Но для меня это пока дебри.
Почитав и посмотрев видео, увидел главные недостаток - если событие прерывания наступило несколько раз подряд - образуется очередь прерываний, и каждое событие прерывания будет обработано отдельно и по очереди.
Мне так не надо.
Мне нужно, что если событие прерывание наступило, то сколько бы не наступало последующих ОДНОТИПНЫх событий, пока это событие не обработается 5 минут, в очередь никакие другие события не становились. Вот пройдет 5 минут - если после этих 5 минут опять наступило событие прерывания - то тогда опять его обработать.
так и отключайте прерывание, на эти 5 минут, а потом вновь разрешать.. .
наступило событи, в обработчике быстро сделали что надо, слиняли, входим в ваш 5ти минутный цикл и там отключаем прерывание ваше, после истечения времени включить и всё заново...
Я автор вопроса.
Alexandr Ыых,
Вот мой кусок кода, который мне на радиокоте застремачили.
DDRD = 0xff; /* все выводы порта D сконфигурировать как выходы */
/* DDRB = 0x00; все выводы порта B сконфигурировать как входы */
while (1)
{ // Бесконечный цикл
if (PINB != 0x00) //Если первый бит порта Б не равен 0 (есть напряжение на входе)
//(Если кто-то пришел и открыл дверь)
{
while (PINB != 0x00)
{
// И до тех пор, пока н закроют дверь - Включаем режим "тревога"
if (PIND != 0x01) PORTD = 0x01; //и его не выключаем во что бы то ни стало.
}
//Как только цикл закончится - дверь закроют, терпим время и возвращаем все в режим.
_delay_ms(5000); // Ждем 5 сек.
PORTD = 0x00; /* устанавливаем "спокойствие" */
}
} // закрывающая скобка бесконечного цикла
} // закрывающая скобка основной программы
Но мне посоветовали сделать на прерываниях.
Типа нефиг постоянно While гонять бестолку.
[ссылка заблокирована по решению администрации проекта]
без прерываний примерно так
_____________________________________________
#include < avr/io.h>
#include < util/delay.h>
// выход тревоги
#defineTREVOGA1 (1 << PB0)
#defineTREVOGA1_DDR DDRB
#defineTREVOGA1_PRT PORTB
// вход датчика
#define DATCH1(1 << PB1)
#define DATCH1_DDRDDRB
#define DATCH1_PINPINB
int main(void)
{
//port_init (
DDRB= 0;
DDRD= 0;
PORTB= 0;
PORTD= 0;
TREVOGA1_DDR |= TREVOGA1;
uint16_t T_datch1_off= 0;
const uint16_t Ts_datch1_off= 300;// 5 minut
while(1)
{
if(DATCH1_PIN & DATCH1)
{
TREVOGA1_PRT |= TREVOGA1;
T_datch1_off= Ts_datch1_off;
}
else
{
///if(T_datch1_off) { T_datch1_off--; _delay_ms(1000);}
if(T_datch1_off) { T_datch1_off--; _delay_ms(1);}/// для симуляции в AVR studio ускорим
else { TREVOGA1_PRT &=~TREVOGA1;}
}
}
}
_____________________________________________
С прерываниями лучше тем, что можно сделать экономию энергии - спящий режим, важно если от батареек.
В Вашем случае надо использовать внешнее прерывания от событий "переход с нуля на единицу" - включим тревогу
"переход с единицы на нуль" - включим таймер отмены тревоги (таймер тоже по прерываниям таймера)