Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: LPC11xx и обработка прерываний
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
deplen
Код
volatile uint32_t count = 1;
void PIOINT1_IRQHandler(void)
{
    GPIOIntClear( 1, 9 );
    if( count != 7 )
    {
        count++;
    }
    else
    {
        LPC_GPIO0->MASKED_ACCESS[( 1 << 7 )] = ( 0 << 7 );
        count = 1;
    }
}

int main(void) {
    LPC_SYSCON->SYSAHBCLKCTRL |= ( 1 << 6 );
    NVIC_EnableIRQ( EINT1_IRQn );
    LPC_GPIO0->DIR |= ( 1 << 7 );               // настраиваем PIO0.7 на вывод (светодиод LPCXpresso)
    GPIOSetDir( 1, 9, 0 );

    GPIOSetInterrupt( 1, 9, 0, 0, 0 );
    GPIOIntEnable( 1, 9 );
}

Есть вот такой код обработки прерывания. Суть его такая: при запуске горит светодоид, но при 7 разовом нажатии на кнопку светодиод должен погаснуть. Но работает как то странно. То 7 раз нажать на кнопку и гаснет, то 6, то 4, то 3. Вобщем разные цифры.
В чем я ошибся при кодировании прерывания?
Golikov A.
в дребезге контактов?
кнопка - это не четкий фронт, она прерывание может и много раз вызвать...

Black Pahan
А дребезг контактов как устраняете?
_Артём_
Цитата(deplen @ Feb 6 2013, 18:16) *
В чем я ошибся при кодировании прерывания?

Может виноват дребезг кнопки?
Попробуйте выдать сигнал от другого порта lpc11, настроенного на выход.
deplen
Просто задача стоит что бы по последовательности нажатий на кнопку запускать определенную функцию. Тобишь если кнопка такая не стабильная выхода нет?
_Артём_
Цитата(deplen @ Feb 6 2013, 18:51) *
Просто задача стоит что бы по последовательности нажатий на кнопку запускать определенную функцию. Тобишь если кнопка такая не стабильная выхода нет?

Проверяйте состояние входа с каким-нибудь периодом (100-500 раз в секунду). Если уровень на входе не меняется заданное количество раз, то состояние входа можно считать устоявшимся.

Или вешайте на вход какую-нибудь обвязку(RC-цепочку, триггер и тп).
Golikov A.
это просто.

после прерывания считает отсчет и ставите флаг что кнопка нажата, и если оказываетесь в прерывании а флаг стоит просто выходите, сняв прерывание, без отсчета.

а в основном цикле снимаете флаг только после того как кнопка была отжата несколько тактов
так вы будите реагировать на кнопку 1 раз в те несколько тактов если на кнопку быстро нажимать, или через те тактов после ее отпускания если долго. Подберите число тактов или таймер миллисекунд на 50 - 100 и задача решена. Но в целом это очень стандартная схема, могли для тренировки и сами придумать.
DVF
А разве ноги на вход не имеют Schmitt Trigger? Tогда можно попробовать подцепить к входу емкость на 0.22uF к GND, если нет более жестких требований по помехозащищенности.
Alex11
Триггеров Шмитта как правило нет. Но даже если есть конденсатор здесь очень плохо работает. Нужно ждать стабилизации показаний. Хорошие кнопки прекращают дребезжать за 5 мс, плохие - до 50 мс. Если нужно ловить частые нажатия, то нужно опрашивать кнопку примерно раз в 0.5 - 1 мс и если обнаружено 2 одинаковых состояния подряд, то можно считать что дребезг кончился. Это, правда, относится к хорошим кнопкам.
jcxz
0.5мс????
Вы реально способны нажимать на кнопку с частотой 1 кГц??? smile3046.gif
Значит вы - УНИКУМ! rolleyes.gif
А обычным людям вполне достаточно ~50Гц частоты сканирования кнопок.
Alex11
0.5 мс, если Вы внимательно прочитали пост, - это время опроса дребезга. Общее время дребезга все равно будет не менее 5 мс. На два фронта - 10 мс, стало быть максимум скорости, которую можно отжать от кнопки - 100 Гц. И иногда удобно, чтобы кнопка срабатывала быстро и на короткий удар отвечала двумя переходами, а не блокировала его как дребезг.
Сергей Борщ
Опрашиваю кнопки раз в 50 мс. При этом дребезг гасится автоматически если кнопка дребезжит менее 50мс. Если кнопка дребезжит более 50мс ее надо менять.
deplen
а что делает HYSTERESYS в настройках каждого пина, не триггер ли это?

P.S. да и общий вопрос, вешать такой нестабильный фронт как кнопка на прерывание хорошая идея? или проще и надежнее сделать простой опрос пина в цикле?
_Артём_
Цитата(deplen @ Feb 7 2013, 17:54) *
а что делает HYSTERESYS в настройках каждого пина, не триггер ли это?

Хоть бы и триггер, но кнопка всё равно дребезжать будет...

Цитата(deplen @ Feb 7 2013, 17:54) *
P.S. да и общий вопрос, вешать такой нестабильный фронт как кнопка на прерывание хорошая идея?

Чего ж хорошего в такой идее.

Цитата(deplen @ Feb 7 2013, 17:54) *
или проще и надежнее сделать простой опрос пина в цикле?

Лучше опрос, но не в цикле, а периодически.
Golikov A.
зависит от задачи.

Опрос кнопок в цикле частенько приводить к тупящим приложениям. Где надо каждый раз нажимать основательно, и ты каждый раз не уверен нажалось оно или нет...

Если главный цикл короткий, и фактически один опрос кнопок и малая индикация можно и полингом, если реакция на кнопки нужна четкая и быстрая, а главный цикл загружен, то прерывание.

И нет никакой проблемы в прерываниях на кнопки, просто надо в этом прерывании не тупить. Обработал клик, поставил флаг что кнопка была, и вывалился. Весьма корректное решение...

Периодический опрос - потенциально приложения пропускающие клики...

да гистерезис не особо поможет, конденсатор на кнопицу и пауза в опросе, ну и хорошая дорогая кнопочка.
Сергей Борщ
QUOTE (Golikov A. @ Feb 7 2013, 20:48) *
Периодический опрос - потенциально приложения пропускающие клики...
Почему?
Golikov A.
по определению...

быстрые клики попавшие в паузы опроса - не будут замечены. Прерывание чем хорошо, что даже если вы запретили прерывания в момент нажатия, нажатие все равно будет замечено и флаг будет поставлен, и разрешив прерывания вы узнаете что нажатие было.

Главное не понятно откуда такая боязнь прерывания? Любой полинг грузит процессор в разы выше,
jcxz
Цитата(Alex11 @ Feb 7 2013, 20:51) *
0.5 мс, если Вы внимательно прочитали пост, - это время опроса дребезга. Общее время дребезга все равно будет не менее 5 мс. На два фронта - 10 мс, стало быть максимум скорости, которую можно отжать от кнопки - 100 Гц.
Я внимательно прочитал, только всё равно не понял зачем опрашивать дребезг??? Я почему-то всегда считал - его надо гасить...
Если у вас максимальное время дребезга кнопки 5мс, то соответственно частота сканирования кнопок не должна превышать 200Гц иначе будут ложные срабатывания. Вот и всё.

Цитата(Alex11 @ Feb 7 2013, 20:51) *
И иногда удобно, чтобы кнопка срабатывала быстро и на короткий удар отвечала двумя переходами, а не блокировала его как дребезг.
Здесь вроде обсуждается вопрос подавления дребезга, а не генерации его.

Цитата(deplen @ Feb 7 2013, 21:54) *
P.S. да и общий вопрос, вешать такой нестабильный фронт как кнопка на прерывание хорошая идея? или проще и надежнее сделать простой опрос пина в цикле?
И на прерывание и опрос в цикле - обе плохие. Грамотно - делать опрос из периодического прерывания.


Цитата(Golikov A. @ Feb 8 2013, 00:48) *
Периодический опрос - потенциально приложения пропускающие клики...
Обоснуйте.
HHIMERA
Цитата(Golikov A. @ Feb 8 2013, 06:22) *
Главное не понятно откуда такая боязнь прерывания? Любой полинг грузит процессор в разы выше,

Это не боязнь... это осмысленное понимание того, что, и главное как, нужно делать...
Сергей Борщ
QUOTE (Golikov A. @ Feb 8 2013, 05:22) *
по определению...

быстрые клики попавшие в паузы опроса - не будут замечены.
Опрос раз в 50 мс в прерывании таймера. Клик быстрее 50 мс - это не клик, это наводка. Зато никаких ограничений на функции вывода - ему не обязательно иметь возможность генерить прерывания. Он может использоваться для дополнительных функций - например, на нем может висеть еще и индикатор. Он может вообще быть аналоговым и читаться через АЦП. Кнопки могут быть организованы в матрицу или еще каким-то хитрым способом.


QUOTE (Сергей Борщ @ Feb 8 2013, 12:43) *
Опрос раз в 50 мс в прерывании таймера. Клик быстрее 50 мс - это не клик, это наводка. Зато никаких ограничений на функции вывода - ему не обязательно иметь возможность генерить прерывания. Он может использоваться для дополнительных функций - например, на нем может висеть еще и индикатор. Он может вообще быть аналоговым и читаться через АЦП. Кнопки могут быть организованы в матрицу или еще каким-то хитрым способом.


QUOTE (Golikov A. @ Feb 8 2013, 05:22) *
Главное не понятно откуда такая боязнь прерывания? Любой полинг грузит процессор в разы выше,
У меня в ATmega8 только две ноги могут генерить прерывания. Мне отказываться от заказов, в которых более двух кнопок?
Golikov A.
надо разделить сложности проектирования и текущую реализацию.


имеем
кнопка подключена к ножке процессора, которая умеет генерить прерывание на изменение фронта этой ножки. Вешаем на эту ножку кнопку, применяем все меры по устранению дребезга на схемотехническом уровне. Теперь вопрос, почему в данной ситуации не использовать прерывание? Чем оно хуже полинга? Зачем в этой ситуации нужен полинг? Какой выигрыш от периодического опроса?

Когда я пишу потенциально - это значит потенциально, а не всегда. пишешь приложение с главным циклом

опрос кнопок
измерение
вывод на экран

а потом оно начинает обрастать, фильтрацией, обработкой измерения, и так далее и пауза между опросами кнопок становиться все больше больше... И начинает расти минимальная длительность нажатия которую видит прибор. А за ней начинает расти скорость реакции на кнопку после нажатия, то есть время между тем как вы нажали и тем как приложение отозвалось.

И тут мы приходим к светлому решению вынести кнопки в отдельный поток на таймер. Сделать прерывание и опрашивать с периодами, все супер, но только пришли к тому же прерыванию что и от кнопки, но еще в добавок заняли таймер. А что выиграли то?
_Артём_
Цитата(Golikov A. @ Feb 8 2013, 13:39) *
Какой выигрыш от периодического опроса?

Выигрыш в том, что будет работать для любого входа, независимо поддерживает оно прерывания по входу или нет.

Цитата(Golikov A. @ Feb 8 2013, 13:39) *
а потом оно начинает обрастать, фильтрацией, обработкой измерения, и так далее и пауза между опросами кнопок становиться все больше больше... И начинает расти минимальная длительность нажатия которую видит прибор.

Проверяйте состояние входа в функции прерывания таймера.
scifi
Цитата(Golikov A. @ Feb 8 2013, 15:39) *
Какой выигрыш от периодического опроса?

Я думал, это очевидно: поллинг проще. Техническое совершенство - это прекрасно, но в условиях ограниченных ресурсов (чаще всего - времени) часто приходится выбирать решения, которые не совершенны, но с задачей справляются.
Golikov A.
Цитата(_Артём_ @ Feb 8 2013, 16:03) *
Выигрыш в том, что будет работать для любого входа, независимо поддерживает оно прерывания по входу или нет.


Проверяйте состояние входа в функции прерывания таймера.


про таймер написал чуть ниже, тоже прерывание, только еще и таймер заюзали.

Про то что будет работать для любого входа, аргумент, но есть ли смысл? Если есть устройство, в нем есть прерывание и кнопка, зачем писать так чтобы работало и без этого? На будущее?
Мы решаем эти вопросы во время проектирования, если прерывания выделить невозможно, решается так, если есть порты с прерываниями - сяк. Конкретный прибор - конкретная реализация, переносимость кода и его изменяемость решается на более высоком уровне, на том где уже состояние кнопок получено, а как получается состояние кнопок - это уже конкретный прибор == конкретный способ.


_Артём_
Цитата(Golikov A. @ Feb 8 2013, 14:14) *
тоже прерывание, только еще и таймер заюзали.

На то они и таймеры, чтобы их юзать...
К тому же в программе как правило нужен таймер для формирования времени и тп.

Golikov A.
Цитата(scifi @ Feb 8 2013, 16:06) *
Я думал, это очевидно: поллинг проще. Техническое совершенство - это прекрасно, но в условиях ограниченных ресурсов (чаще всего - времени) часто приходится выбирать решения, которые не совершенны, но с задачей справляются.


стараюсь так не работать. Допускаю компромиссы между работает хорошо и очень хорошо, но никогда ни выбираю между работает хорошо, и хоть как то...Хоть как-то - это сырой продукт, такой заказчику не выдаю... потом будет больше проблем чем неприятностей от срыва срока...

scifi
Цитата(Golikov A. @ Feb 8 2013, 16:27) *
Хоть как-то - это сырой продукт

Есть одно НО: периодический опрос кнопок - это не хоть как-то. Попробуйте на досуге - работает замечательно.
Golikov A.
sad.gif мне кажется меня не слышат, наверное вам кажется так же.

у человека есть проц
есть ножка с прерыванием
есть кнопка
есть прерывание

спрашивает так делать хорошо или плохо? ему говорят плохо, потому что в АВР нет прерыванияsm.gif))... ну смешно же!
Мой ответ так делать в конкретно этом случае хорошо!





scifi
Цитата(Golikov A. @ Feb 8 2013, 16:41) *
Мой ответ так делать в конкретно этом случае хорошо!

Скажу больше: и так, и так хорошо. А с учётом времени, потраченного на спор, мой аргумент о недостатке времени в данном случае не применим :-)
Но есть иные аргументы: переносимость кода, например. Хотя в данном случае он тоже может быть не применим - автору вопроса виднее. Со своей стороны замечу, что при прочих равных стараюсь выбирать переносимый вариант, причём на практике это реально приносило плоды при переходе на другой компилятор, МК и т.д.
Tahoe
Цитата(Golikov A. @ Feb 8 2013, 16:14) *
Если есть устройство, в нем есть прерывание и кнопка, зачем писать так чтобы работало и без этого? На будущее?

У меня есть один, но убийственный аргумент. Никогда не доводилось реализовывать функциональность кнопки чуть сложнее, чем просто нажатие? А именно, различать короткие и длинные нажатия? Ну и как тут без таймера? А в варианте с поллингом, это реализовывается на раз. wink.gif
Golikov A.
ну все, убедили.

переписываю все проекты с прерываниямиsad.gif....

даже тот где кнопки различали еще и комбинации разно длительных нажатий и при том не занимали под себя отдельный таймер.... wink.gif

правда спор на пустом месте. Надо делать как удобнее, плохого в варианте прерываний нет, и полинг допустим также
HHIMERA
Цитата(Golikov A. @ Feb 8 2013, 15:41) *
Мой ответ так делать в конкретно этом случае хорошо!

Ещё не факт...
В 95-98% случаев периодический опрос кнопок даёт наилучший результат...
Golikov A.
Окей Окей sm.gif...
adnega
Пример, конечно, надуманный, но все же: что будет, если на ножку кнопки подать сигнал частотой под мегагерц? в случае работы по прерыванию и в случае работы по опросу? wink.gif
По-моему в случае периодического опроса - ничего страшного, а в случае прерываний - ничего хорошего.
Golikov A.
ну я же согласилсяsm.gif

второй надуманный пример,
что будет если пользователь захочет нажимать на кнопку с частотой под мегагерц? в случае работы по прерыванию все корректно отработается, а в случае полинга половину нажатий пропуститеsm.gif....

ну в целом наверное да, прерывание опаснее... хотя у него так же есть мертвая зона реакции, та что дребезг устраняет...
Tahoe
Цитата(Golikov A. @ Feb 8 2013, 22:45) *
что будет если пользователь захочет нажимать на кнопку с частотой под мегагерц? в случае работы по прерыванию все корректно отработается, а в случае полинга половину нажатий пропуститеsm.gif....

Это почему же? Если частоту опроса выбирать не на след. утро после пьянки, а осмысленно, то тоже ничего не пропустится. wink.gif
jcxz
Цитата(Golikov A. @ Feb 9 2013, 00:45) *
второй надуманный пример,
что будет если пользователь захочет нажимать на кнопку с частотой под мегагерц? в случае работы по прерыванию все корректно отработается, а в случае полинга половину нажатий пропуститеsm.gif....
Так-ли? В случае работы по прерыванию (и особенно наличия ОС), проц скорее всего загрузится на 100% и прикладное ПО встанет колом. В случае периодического опроса, работоспособность остального ПО, не зависящего от событий нажатия, скорей всего не нарушится. smile3046.gif

Ещё один минус прерывания от кнопки Вы сами выше упомянули:
Цитата(Golikov A. @ Feb 8 2013, 17:39) *
кнопка подключена к ножке процессора, которая умеет генерить прерывание на изменение фронта этой ножки. Вешаем на эту ножку кнопку, применяем все меры по устранению дребезга на схемотехническом уровне.
А в случае периодического опроса абсолютно не нужно никаких схемотехнических мер. Более того - схемотехника этой ноги более свободна, и например нога может выполнять ещё и другие функции (светодиод к примеру).

Цитата(Golikov A. @ Feb 8 2013, 19:15) *
даже тот где кнопки различали еще и комбинации разно длительных нажатий и при том не занимали под себя отдельный таймер.... wink.gif
И это надеюсь без привязки к частоте CPU? Вот это интересно! а можно примерчик в студию? laughing.gif
Да и кто кстати сказал что периодический опрос должен занимать отдельный таймер? Почему нельзя его сделать на каком-то уже существующем подходящем периодическом прерывании таймера?
Golikov A.
В целом я уже согласился, прерывание плохо, полинг это хорошо. Просто потому что это ничего не меняет, а вам это почему то важноsm.gif

уточню только эти моменты:
если пользователь хочет нажимать с частотой 1 МГц, а вы пропустите половину нажатий - это некорректная работа! sm.gif

мер не нужно, но они уже сделаны, зачем отговаривать человека от использования прерывания в этом случае?sm.gif

если подбирать подходящий таймер, то это делает трудным поддержку проекта. Если есть модуль и он занял таймер, то таймер можно менять как хочешь, если от этого таймера начинают зависит другие модули - это пипец. Это код где каждый шаг как на минном поле, и ты никогда не узнаешь все ли хорошо, если ты что-то поменял...

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

этот сквозной таймер могут использовать все модули, без возможности менять его параметры. Проект легко обслуживается, и поддерживается. Можно делать все что хочешь в основном цикле, хоть пихать паузы while(1), делать длительные обработки, реакция на кнопки будет правильной и корректной.


jcxz
Вот!!! Так и думал! laughing.gif
Т.е. - таймер у вас всё-же есть и кнопка его использует. А теперь просто вместо использования чтения переменной счётчика таймера, делаем в процедуре ISR таймера вызов нашей процедуры сканирования кнопы (с соответствующим делителем). И всё - раньше этот один таймер использовался и теперь так же один таймер используется wink.gif

PS: А ведь могли-бы, из неприязни к таймерам, на ещё одну ногу прицепить RC-цепочку, по нажатию кнопки включать зарядку её и ловить прерывание по достижении порога. Лишние ноги конечно, но зато без таймера! biggrin.gif

Шутка, не обижайтесь sm.gif
Golikov A.
вы не внимательны.
этот таймер не имеет прерывания, он идет без остановок и запусков потому его может использовать любой другой модуль без опаски что кто-то его выключит или сменит интервал.
Прерывание кнопки позволяет точно фиксировать момент, что в отличии от полинга дает неопределенность с точностью до частоты опроса.

если же таймер вызывает прерывание и сканирует кнопку - это таймер занятый на кнопки, и использовать его для чего либо другого не безопасно, опять же он дает неопределенность длительности до частоты опроса.

Естественно это немного идеализированный пример, потому что в большинстве случаев неопределенность до частоты опроса не важна... но если уж мы копаем нюансы - так вот они.

Причем еще один момент, этот таймер может быть и не регистром контроллера, это может быть таймер внешний в ЛПИСе или же спец микросхема с высокой стабилизацией времени, которые могут и не иметь возможности генерить прервания с интервалами или вообще не иметь возможности генерить прерывание...



заряжать конденсатор - это сильно конечно, там и АЦП можно к процессу подключить, но достаточно просто внешнего таймераsm.gif как я и написал...

Кстати! совсем забылsm.gif)))

Кнопка на прерывании легко и безоговорочно побеждает кнопку по полингу если речь идет о режиме энергосбережения и пробуждению по нажатию кнопки... При полинге вы либо не проснетесь вообще, либо регулярными пробуждениями потратите всю энергию!

тадам!!!! прерывание - полинг 1 : 0
Tahoe
Цитата(Golikov A. @ Feb 9 2013, 21:36) *
Кнопка на прерывании легко и безоговорочно побеждает кнопку по полингу если речь идет о режиме энергосбережения и пробуждению по нажатию кнопки...

Вот так и знал, что про это зайдет. Но не надо путать, событие "wake_up" и событие "button_pressed" - абсолютно разные, хотя, как частный случай, могут наступить от одного источника. Для "wake_up" - только прерывания, без вариантов. А дальше... угу, он самый, поллинг кнопок.
deplen
даже не думал, что обработка нажатия на кнопку вызовет такое обсуждение на 3 страницы sm.gif
deplen
Реализовал чтение порта на нажатие кнопки. Каждые 0.05 секунды выполняется чтение нажатия. Никакого дребезга больше нет.

Но хотелось бы как то заставить таймер следить что бы не было слишком длительных ожидания нажатий. Всмысле, например, пользователь нажал 2 раза, а третий не нажал, то в памяти так два раза и останется. А хотелось бы, если было хотя бы одно нажатие, то запускался счетчик на 5 секунд втечении которых пользователь должен успеть нажать еще 2 раза. Может есть идеи как это реализуется в таймере LPC?
Golikov A.
запустить в таймере счетчик?
deplen
Цитата(Golikov A. @ Feb 11 2013, 19:21) *
запустить в таймере счетчик?


Счетчик, который таймер внутри себя считает?
Golikov A.
естественно

первое нажатие задает значение счетчика на 5 секунд.
каждый тик таймера пока счетчик не 0, счетчик уменьшается.

если пока он не достиг нуля будут еще сколько то нажатий то готово, если нет, то в начальное состояние ожидание первого нажатия.

В реализации вам поможет конечный автомат
1. ожидание нажатие по нажатию переходит в
2. ожидание других нажатий отсюда если вышел таймер в 1, если были нажатия в
3. обработка 3 нажатий, по окончанию в 1.
deplen
Все. Всем спасибо. Прерывание реализовано по таймеру с некоторой частота срабатывания прерывания таймера. Требуемая длительность, после первого нажатия, и последующего сброса если не выполнено условие, реализовано.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.