Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: прерывание на stm32f407
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
BlackOps
Сконфигурировал два прерывания на EXTI2 и EXTI3. Пины PE2 и PE3.

При подаче единицы на пин PE2(EXTI2) прерывание всегда срабатывает как надо, и внутри обработчика включается один таймер.

Прерывание EXTI3 при подаче единицы на PE3не срабатывает нормально, а именно: Код входит в прерывание, проверяыет наличие прерывание на пине EXTI->PR,
затем даже производит нужные действия, включает еще один таймер и пару пинов других. Однако, по непонятным причинам не производится очистка бита 3 в регистре EXTI->PR

в дебаггере регистр EXTI->PR читается как 0хс, т.е. 1100, т.е. видно что якобы два прерывания активно, EXTI2 и EXTI3.

Мне непонятно одно: почему выстоен пин 2? Ведь первое прерывание прошло успешно, и я проверял что пин №2 после первого прерывания был очищен, и никакого сигнала на тот пин больше не подавал!

Каким образом вдруг не с того не с сего выставлен пин №2? И почему не очищается пин №3?


Вот код настройки прерывания EXTI2,3:
CODE

// Enable SYSCFG clock
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;



// External interrupt from pin PE2 (EXT1_IN1)
SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI2_PE; //

EXTI->IMR |= (1 << 2); // Mask PE2
EXTI->RTSR |= (1 << 2); // Rising Edge detection

NVIC_SetPriority(EXTI2_IRQn, 0x1);

NVIC_EnableIRQ(EXTI2_IRQn);



// External interrupt from pin PE3 (EXT1_IN2)
SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI3_PE; //

EXTI->IMR |= (1 << 3); // Mask PE3
EXTI->RTSR |= (1 << 3); // Rising Edge detection

NVIC_SetPriority(EXTI3_IRQn, 0x2);

NVIC_EnableIRQ(EXTI3_IRQn);



а вот код обработчиков EXTI2,3:
CODE

void EXTI2_IRQHandler()
{


// check if interrupt bit set
if ( (EXTI->PR) == (1 << 2) )
{
// clear interrupt bit
EXTI->PR = (1 << 2);

TIM2->CR1 |= TIM_CR1_CEN; // Enable TIM2
}


}



void EXTI3_IRQHandler()
{


// check if interrupt bit set
if ( (EXTI->PR) == (1 << 3) )
{
// clear interrupt bit
EXTI->PR = (1 << 3);

TIM5->CR1 |= TIM_CR1_CEN; // Enable TIM5


GPIOD->ODR |= GPIO_ODR_ODR_0; // EXT3_OUT1, PD0 HIGH

GPIOD->ODR |= GPIO_ODR_ODR_1; // EXT3_OUT2, PD1 HIGH
}


}

adnega
Код
if ( (EXTI->PR) == (1 << 2) )
if ( (EXTI->PR) == (1 << 3) )

Неправильно. Нужно так:
Код
if ( (EXTI->PR) & (1 << 2) )
if ( (EXTI->PR) & (1 << 3) )
}


BlackOps
да точно..спасибо.
demiurg_spb
OFF: заметил что вы используете ODR для махания пинами - это не самый оптимальный способ.
Так будет лучше с нескольких точек зрения:
Код
GPIOX->BSRR = (1UL << (XPIN));  // Atomic bit-set operation
GPIOX->BRR  = (1UL << (XPIN));   // Atomic bit-clr operation

ну или через bitband...
Allregia
Цитата(demiurg_spb @ Jul 18 2013, 14:28) *
OFF: заметил что вы используете ODR для махания пинами - это не самый оптимальный способ.
Так будет лучше с нескольких точек зрения:
Код
GPIOX->BSRR = (1UL << (XPIN));  // Atomic bit-set operation
GPIOX->BRR  = (1UL << (XPIN));   // Atomic bit-clr operation

Может лучше:

Код
GPIOX->BSRRL =  (1UL << (XPIN));}
GPIOX->BSRRH =  (1UL << (XPIN));}


?
demiurg_spb
Цитата(Allregia @ Jul 19 2013, 16:32) *
Да. Я для stm32f10x пример дал, а для f4 немного иначе. Как Вы предложили или так:
Код
GPIOX->BSRR = (1UL << (XPIN));  // Atomic bit-set operation
GPIOX->BSRR = (1UL << 16+(XPIN));   // Atomic bit-clr operation
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.