Top.Mail.Ru
Ответы
Аватар пользователя
13лет
Изменено

Микроконтроллер ATtiny 2313. Прерывания. Можно ли настроить отмену очереди?

Всем привет.
Извиняюсь за простой вопрос, но не могу дошарить никак. По инету написано так запутано, что порой трудно разобраться даже в мелочах.
Пишу простую программку типа Hello World, нечто подобие примитивной сигнализации, логика следующая:
-
Ничего не делаем, до тех пор, пока нет возмещения (нет логической 1 с датчика - не открыта дверь)
Как только есть возмущение - бъем тревогу (на одну ногу порта D подаем лог. 1).
И бъем тревогу эту до тех пор, пока возмущение не пропадет, и еще 5 минут после этого.
Если по истечению 5 минут все спокойно, то переходим в сторожевой режим (ничего не делаем) .
-
На радиокоте посоветовали вместо мной предпологаемого While, чтобы МК не гонял бесконечные проверки для этих целей использовать прерывания.
Я понимаю, что это правильное решение, рациональное. Но для меня это пока дебри.
Почитав и посмотрев видео, увидел главные недостаток - если событие прерывания наступило несколько раз подряд - образуется очередь прерываний, и каждое событие прерывания будет обработано отдельно и по очереди.
Мне так не надо.
Мне нужно, что если событие прерывание наступило, то сколько бы не наступало последующих ОДНОТИПНЫх событий, пока это событие не обработается 5 минут, в очередь никакие другие события не становились. Вот пройдет 5 минут - если после этих 5 минут опять наступило событие прерывания - то тогда опять его обработать.

По дате
По рейтингу
Аватар пользователя
Новичок
13лет

так и отключайте прерывание, на эти 5 минут, а потом вновь разрешать.. .
наступило событи, в обработчике быстро сделали что надо, слиняли, входим в ваш 5ти минутный цикл и там отключаем прерывание ваше, после истечения времени включить и всё заново...

Аватар пользователя
Профи
13лет

Я автор вопроса.
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 гонять бестолку.
[ссылка заблокирована по решению администрации проекта]

Аватар пользователя
Просветленный
13лет

без прерываний примерно так
_____________________________________________
#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;}
}
}
}
_____________________________________________
С прерываниями лучше тем, что можно сделать экономию энергии - спящий режим, важно если от батареек.
В Вашем случае надо использовать внешнее прерывания от событий "переход с нуля на единицу" - включим тревогу
"переход с единицы на нуль" - включим таймер отмены тревоги (таймер тоже по прерываниям таймера)