|
|
  |
Работа с прерываниями, xmega, повторно отрабатывает прерывание |
|
|
|
Oct 28 2009, 13:49
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 23-07-08
Пользователь №: 39 158

|
Есть кнопка, которая при включеном положении замыкает контакт на землю. Соответствующую ногу я назначил входом, подтянул логическую единицу, и назначил прерывание при падении уровня на этой ноге Код PORT_ConfigurePins( &PORTB, PIN2_bm, false, false, PORT_OPC_PULLUP_gc, PORT_ISC_FALLING_gc ); PORT_SetPinsAsInput( &PORTB, PIN2_bm ); PORT_ConfigureInterrupt0( &PORTB, PORT_INT0LVL_MED_gc, PIN2_bm ); добавил функцию обработки прерывания Код ISR(PORTB_INT0_vect){ istimer = true; timer=0; PORTD.OUTCLR = PIN1_bm; sendchar('S'); delay_ms(100); } Но обработчик прерывания отрабатывает два раза. Если убрать задержку в прерывании, то обработка прерывания происходит большее количество раз, что возникает скорее всего из-за дребезга контакта, который в устройстве ничем не отфильтровывается. Собственно вопрос, почему происходит повторная обработка прерывания и как с этим бороться (желательно программно)?
|
|
|
|
|
Oct 29 2009, 08:28
|

Профессионал
    
Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955

|
Цитата(Duhas @ Oct 29 2009, 16:10)  я так понимаю, что во время начала отработки прерывания поступает второй запрос на это же прерывание... т.к. прерывание обрабатывается достаточно быстро для клавиатуры, второе - явно лишнее, следовательно, пожалуй даже при выходе из обработчика, неплохо было бы очистить флаг запроса.. Это малопродуктивно, т.к. 1. Дребезговых импульсов может быть гораздо больше двух 2. Прерывание обрабатывается не просто быстро, а очень быстро, и второй запрос при дребезге скорее всего придет после выхода из прерывания. Так что запретить его лучше... А вот перед повторным разрешением по таймеру - да, запросы надо сбросить!
|
|
|
|
|
Oct 29 2009, 19:52
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 23-07-08
Пользователь №: 39 158

|
Всем спасибо за ответы. Прохожий - полезная ссылка! Попробую организовать подобный алгоритм.
|
|
|
|
|
Nov 2 2009, 16:26
|
Частый гость
 
Группа: Участник
Сообщений: 90
Регистрация: 7-05-06
Пользователь №: 16 862

|
Цитата(V_G @ Oct 29 2009, 01:49)  Смотря какой флаг чистить. Флаг запроса на прерывание очищается автоматически. В Xмеге далеко не все флаги запроса на прерывание очищаются автоматически. Я с этим столкнулся, когда возился обработкой прерываний от DMA. Здесь скорее всего тоже. Даташит упоминает только про сброс путем записи единицы: Цитата The INTnIF flag is set when a pin change according to the pin's input sense configuration occurs, and the pin is set as source for port interrupt n. Writing a one to this flag's bit location will clear the flag. For enabling and executing the interrupt refer to the interrupt level description. Такой подход понять можно - на восемь пинов всего два вектора прерывания. В общем случае может оказаться, что две и более ног хотят вызвать одно и тоже прерывание одновременно. Такую ситуацию все равно надо разруливать вручную, так что и ручной сброс флага не сильно напряжет...
|
|
|
|
|
Nov 3 2009, 05:23
|
Частый гость
 
Группа: Участник
Сообщений: 90
Регистрация: 7-05-06
Пользователь №: 16 862

|
Да, похоже Ваша правда - в соотвествующей аппноте 1313 в прерывании флаги тоже вручную никто не сбрасывает. Меня смутило, что в даташите они не заострили на этом внимания. Как, например, для того же SPI: Цитата The IF is cleared by hardware when executing the corresponding interrupt handling vector. Alternatively, the SPIF bit can be cleared by first reading the STATUS register with IF set, and then access the DATA register. Впрочем, все это не смертельно и легко выясняется эксперементально. Хотя для новичков трудностей добавляет...
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|