Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: пауза в ISR
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
0x56
как сделать паузу в обработчике внешнего прерывания?
есть какие-то ограничения или связь с таймерами пика?
при наличии в ней delay_ms() заметил глюки но не понял что это
MrYuran
Забудьте про паузы в прерываниях.
Учитесь пользоваться таймерами.
NOP-овыми паузами имеет смысл отмерять только микросекунды.
0x56
а подскажите алгоритм
устанавливать флаг потом его проверять в обработчике прерывания таймера и доделывать то, что не доделал в обработчике внешнего прерывания?
MrYuran
Цитата(0x56 @ Jul 11 2009, 20:38) *
а подскажите алгоритм
устанавливать флаг потом его проверять в обработчике прерывания таймера и доделывать то, что не доделал в обработчике внешнего прерывания?

Прерывания должны быть как можно короче.
То есть делаете неотложные дела (непосредственно связанные с прерыванием), и быстро выходите.
Иначе, если вложенные прерывания запрещены, вы не сможете их вовремя обработать и пропустите нужное событие (например, потеряете пришедший в UART байт)
А если разрешены вложенные прерывания, то в зависимости от приоритета, может и не пропустите событие, но в процессе может сильно разбухнуть стек.

Я обычно делаю быстрый цикл main(), который опрашивает флаги. А флаги выставляются по событиям, в том числе и в прерываниях.
По флагам запускаются нужные обработчики.
Для отсчёта длинных пауз (миллисекунды) обычно заводится переменная, которая по таймеру считает системные "тики".
А в нужных местах просто стоят проверки, "дотикала" она или ещё нет.

Опишите хотя бы на пальцах, что хотите сделать и для чего нужно ждать в прерывании.
0x56
а нужно просто дребезг котактов(gsm сигнализация) исключить, 50 мс
я вот думаю теперь как определить в таймере сколько прошло времени после вызова INT_EXT
быстрый цикл майн мне не подойдет имхо
MrYuran
Цитата(0x56 @ Jul 11 2009, 21:10) *
а нужно просто дребезг котактов(gsm сигнализация) исключить, 50 мс

Понятно.
Я уже в одной теме выкладывал, на второй раз терпежу не хватит...
Вкратце алгоритм такой.
В прерывании от контакта выставляете флаг изменения состояния кнопки и засекаете время данного события. А ещё лучше время плюс задержку.
Далее, в основном цикле, делаете проверку, прошло это время или нет.
Например:
if(TimeCtr>KeyTime) // кнопка таки нажата (или отпущена)
{
Опрашиваем состояние кнопки
Сбрасываем флаг
Выполняем нужные действия
}
0x56
Цитата(MrYuran @ Jul 11 2009, 20:23) *
и засекаете время данного события. А ещё лучше время плюс задержку.


не умею пока что такого делать smile.gif
сделал так, вроде работает, по моему этого достаточно для данного случая?

Код
#INT_TIMER1
void TIMER1_ISR()
{
    if(IsTest)
    {
        if(Test50 < 50) Test50++;
        else
        {
            if(input(PIN_B1))  output_bit(PIN_A1, 1);

            IsTest = 0;
            Test50 = 0;
        }
    }

   return;
}


#INT_EXT1
void EXT1_ISR()
{
    IsTest=1;

    return;
}


у меня еще вопросик
Код
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
при 10 Мгц резонатора внешнего будет раз в 1мс вызывать ISR таймера?
где-то видел как считать не могу найти
0x56
Цитата(MrYuran @ Jul 11 2009, 20:23) *
и засекаете время данного события. А ещё лучше время плюс задержку.


не умею пока что такого делать smile.gif
сделал так, вроде работает, по моему этого достаточно для данного случая?

Код
#INT_TIMER1
void TIMER1_ISR()
{
    if(IsTest)
    {
        if(Test50 < 50) Test50++;
        else
        {
            if(input(PIN_B1))  output_bit(PIN_A1, 1);

            IsTest = 0;
            Test50 = 0;
        }
    }

   return;
}


#INT_EXT1
void EXT1_ISR()
{
    IsTest=1;

    return;
}
mempfis_
А я для защиты от дребезга делаю так - ввожу массив переменных key[3] который хранит состояния сканируемых кнопочек.
По прерыванию от таймера например раз в 5 мс выставляю флаг сканирования клавиатуры.
В самой ПП сканирования клавиатуры делаю такие действия:
Код
key[2] = key[1];
key[1] = key[0];
key[0] = current_key_state;
key_status = key[0] & key[1] &key [2]; //для кнопочек с активным уровнем "1"

А далее
if(key_status&(1<<key0))
{
   .............................. //действия по нажатию кнопки 0
}

if(key_status&(1<<key1))
{
   .............................. //действия по нажатию кнопки 1
}


Это упрощённый вариант но вполне рабочий.
А вообще я ещё учитываю для каждой кнопки период неактивности после очередного нажатия
(период срабатывания при повторных нажатиях и удержаниях).
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.