STM32 条件中断处理
STM32 Interrupt Handeling if condition
我如何通过以下代码用一个处理程序进行 2 次中断:
SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI0_PB | SYSCFG_EXTICR1_EXTI1_PC;
EXTI->IMR = EXTI_IMR_MR0 | EXTI_IMR_MR1;
EXTI->RTSR = EXTI_RTSR_TR0| EXTI_RTSR_TR1;
/* Configure NVIC for External Interrupt */
/* (6) Enable Interrupt on EXTI0_1 */
/* (7) Set priority for EXTI0_1 */
NVIC_EnableIRQ(EXTI0_1_IRQn); /* (6) */
NVIC_SetPriority(EXTI0_1_IRQn,0); /* (7) */
这是处理程序执行的代码:
void EXTI0_1_IRQHandler(void)
{
if ((EXTI->PR & EXTI_PR_PR1) == EXTI_PR_PR1) /* Check line 1 has triggered the IT */
{
EXTI->PR = EXTI_PR_PR1; /* Clear the pending bit */
GPIOC->ODR |= 1<<0;
}
if ((EXTI->PR & EXTI_PR_PR0) == EXTI_PR_PR0) /* Check line 0 has triggered the IT */
{
EXTI->PR = EXTI_PR_PR0; /* Clear the pending bit */
GPIOC->ODR &= ~(1<<0);
}
}
当我点击连接到 PC1 的按钮时,代码工作正常,LED 亮起,当我点击连接到 PB0 的按钮时,LED 熄灭。
在我的 if 结构中,我检查哪条线处于活动状态,但我也希望 LED 仅通过单击 PC1 而不是单击第 1 行上的另一个引脚打开,第 0 行相同,但我不知道如何更改if 结构的条件。
微控制器是STM32F091。
- 首先:每条 EXTIx 线不能连接超过一个引脚 (A..Fx)(请参阅第 177 页的 RM0091)。所以 EXTI line 0 IRQ 严格对应一个 pin: C0 在你的代码中。
其次:不要对服务按钮使用 IRQ。您必须实施弹跳过滤器,最好的办法是通过计时器检查按钮的引脚状态。人的反应约为200ms,真正按下按钮会产生持续时间为100-200ms的脉冲。因此,您需要 12-24 毫秒的计时器和每个按钮在 RAM 中的两个字节...请参见下面的代码示例:
uint8_t btn_state = (uint8_t)0x0, btn_mask = (uint8_t)0x1;
void some_tim_irq_handler(void)
{
if (GPIOC->IDR & (uint16_t)0x1) { // PC0 up
btn_state |= btn_mask;
} else { // PC0 down
btn_state &= (uint8_t)~btn_mask;
}
btn_mask <<= (uint8_t)0x1; // mask cycle
if (btn_state == (uint8_t)0x0) {
// One state
return;
}
if (btn_state == (uint8_t)0xFF) {
// Second state
}
}
我如何通过以下代码用一个处理程序进行 2 次中断:
SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI0_PB | SYSCFG_EXTICR1_EXTI1_PC;
EXTI->IMR = EXTI_IMR_MR0 | EXTI_IMR_MR1;
EXTI->RTSR = EXTI_RTSR_TR0| EXTI_RTSR_TR1;
/* Configure NVIC for External Interrupt */
/* (6) Enable Interrupt on EXTI0_1 */
/* (7) Set priority for EXTI0_1 */
NVIC_EnableIRQ(EXTI0_1_IRQn); /* (6) */
NVIC_SetPriority(EXTI0_1_IRQn,0); /* (7) */
这是处理程序执行的代码:
void EXTI0_1_IRQHandler(void)
{
if ((EXTI->PR & EXTI_PR_PR1) == EXTI_PR_PR1) /* Check line 1 has triggered the IT */
{
EXTI->PR = EXTI_PR_PR1; /* Clear the pending bit */
GPIOC->ODR |= 1<<0;
}
if ((EXTI->PR & EXTI_PR_PR0) == EXTI_PR_PR0) /* Check line 0 has triggered the IT */
{
EXTI->PR = EXTI_PR_PR0; /* Clear the pending bit */
GPIOC->ODR &= ~(1<<0);
}
}
当我点击连接到 PC1 的按钮时,代码工作正常,LED 亮起,当我点击连接到 PB0 的按钮时,LED 熄灭。 在我的 if 结构中,我检查哪条线处于活动状态,但我也希望 LED 仅通过单击 PC1 而不是单击第 1 行上的另一个引脚打开,第 0 行相同,但我不知道如何更改if 结构的条件。
微控制器是STM32F091。
- 首先:每条 EXTIx 线不能连接超过一个引脚 (A..Fx)(请参阅第 177 页的 RM0091)。所以 EXTI line 0 IRQ 严格对应一个 pin: C0 在你的代码中。
其次:不要对服务按钮使用 IRQ。您必须实施弹跳过滤器,最好的办法是通过计时器检查按钮的引脚状态。人的反应约为200ms,真正按下按钮会产生持续时间为100-200ms的脉冲。因此,您需要 12-24 毫秒的计时器和每个按钮在 RAM 中的两个字节...请参见下面的代码示例:
uint8_t btn_state = (uint8_t)0x0, btn_mask = (uint8_t)0x1; void some_tim_irq_handler(void) { if (GPIOC->IDR & (uint16_t)0x1) { // PC0 up btn_state |= btn_mask; } else { // PC0 down btn_state &= (uint8_t)~btn_mask; } btn_mask <<= (uint8_t)0x1; // mask cycle if (btn_state == (uint8_t)0x0) { // One state return; } if (btn_state == (uint8_t)0xFF) { // Second state } }