图6 GPIOx_EXTICR1
// Clear EXTI2 and assign value, the corresponding value of PB is 0001.
SYSCFG->EXTICR1 = ( ( SYSCFG->EXTICR1 & ~(0xf << 8u) ) | (0x1 << 8u) );
配置触发类型在按键初始化中配置按键未按下时处于高电平,因此,对上升沿触发选择寄存器(EXTI_RTSR)与下降沿触发选择寄存器(EXTI_FTSR)赋值时配置触发类型为下降沿触发。// Clear the corresponding bit of EXTI2 triggered by rising edge.
EXTI->RTSR &= ~ (1u << 2u);
// Configure falling edge trigger.
EXTI->FTSR |= (1u << 2u);
使能中断配置EXTI_IMR寄存器的EXTI2对应位,使能中断。// Enable EXTI interrupt.
EXTI->IMR |= (1u << 2u);
配置NVICEXTI控制中断,NVIC处理中断,使用Cortex-M0 core_cm0.h头文件中的NVIC_EnableIRQ使能中断线,EXTI2对应中断为EXTI2_3_IRQn。// Setup NVIC.
NVIC_EnableIRQ (EXTI2_3_IRQn);
编写中断服务程序中断使能中使用EXTI2_3_IRQn,中断处理函数要与其匹配,因此使用EXTI2_3_IRQHandler,设置变量app_exti_event_on作为中断状态标志,该变量初始时为false,中断请求产生时中断状态标志转换为true,将EXRI_PR寄存器的对应位写入1来清除中断。void EXTI2_3_IRQHandler(void)
{
uint32_t flags = EXTI->PR;
if ( 0u != ( flags & (1u << 2u) ) )
{
app_exti_event_on = true;
}
EXTI->PR |= (1u << 2u); // Clear interrupt.
}
main()函数主程序中初始化变量app_exti_event_times为0,设置该变量从0开始计数,
当中断状态标志app_exti_event_on为true,即产生中断请求时,计数值加1,由于LED2初始化后显示为亮,计算计数值取余2,若余数不等于0则LED2灭,若余数为0则LED2亮。实验效果如图7所示。int main(void)
{
// Enable SYSCFG and GPIOB clock.
RCC->APB2ENR |= (1u << 0u);
RCC->AHB1ENR |= (1u << 18u);
// Setup K2.
GPIOB->CRL &= ~(0xf << 8u);
GPIOB->CRL |= (0x8 << 8u);
GPIOB->BSRR |= (1u << 2u);
// Setup LED2.
GPIOB->CRL &= ~(0xf << 12u);
GPIOB->CRL |= (0x1 << 12u);
// Setup SYSCFG EXTI2.
SYSCFG->EXTICR1 = ( ( SYSCFG->EXTICR1 & ~(0xf << 8u) ) | (0x1 << 8u) );
// Setup EXTI.
EXTI->RTSR &= ~ (1u << 2u);
EXTI->FTSR |= (1u << 2u);
// Enable EXTI interrupt.
EXTI->IMR |= (1u << 2u);
// Setup NVIC.
NVIC_EnableIRQ (EXTI2_3_IRQn);
while (1)
{
while ( !app_exti_event_on )
{
}
app_exti_event_on = false;
app_exti_event_times++;
if ( (app_exti_event_times % 2u) != 0u )
{
GPIOB->BSRR = (1u << 3u);// LED2(PB3 pin) off.
}
else
{
GPIOB->BRR = (1u << 3u);// LED2(PB3 pin) on.
}
}
}