EXTI中断程序编写

EXTI中断程序编写总结

- EXTI中断主要涉及到AFIO、EXTI、NVIC以及GPIO这几个寄存器

EXTI中断的具体编写步骤:

  1. 先初始化与EXTI中断相关的GPIO寄存器,即欲将哪个GPIO端口设置为中断响应
  2. 初始化EXTI寄存器,用于中断或者事件的产生。
    1. 先绑定输入线,即控制AFIO寄存器
    2. 初始化EXTI结构体,即配置EXTI寄存器的相关参数
  3. 初始化NVIC,用于处理中断(主要用来设置中断优先级)
  4. 编写中断服务函数(相关函数名称需要对应,可以在启动文件中初始化中断向量表中找到相应函数名)
  5. 编写main中的调用初始化逻辑
  6. 6.

具体程序示例如下:

//按键相关EXTI初始化
void Key_EXTI_config(void)
{
         /*  1- 初始化与EXTI相关的GPIO  */
    GPIO_InitTypeDef key1_gpio_initStruct, key2_gpio_initStruct;
    EXTI_InitTypeDef key1_exti_initStruct, key2_exti_initStruct;
    NVIC_InitTypeDef key1_nvic_initstruct, key2_nvic_initstruct;

    //配置GPIO结构体
    key2_gpio_initStruct.GPIO_Pin = KEY2_GPIO_PIN;               //配置对应的引脚
  key2_gpio_initStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;      //配置输入输出模式

    key1_gpio_initStruct.GPIO_Pin = KEY1_GPIO_PIN;                 //配置对应的引脚
    key1_gpio_initStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;      //配置输入输出模式

    RCC_APB2PeriphClockCmd(KEY2_GPIO_CLK, ENABLE);      //RCC寄存器开APB2GPIOB的时钟!
    GPIO_Init(KEY2_GPIO_PORT, &key2_gpio_initStruct);   //再配置相关的控制寄存器,CRL

    RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK, ENABLE);       //RCC寄存器开APB2GPIOA的时钟!
    GPIO_Init(KEY1_GPIO_PORT, &key1_gpio_initStruct);        //再配置相关的控制寄存器,CRL

     /*2.  初始化EXTI,用于中断/事件的产生 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    GPIO_EXTILineConfig(KEY1_portSource, KEY1_PinSource); //根据GPIO绑定对应的输入线,控制寄存器AFIO
    GPIO_EXTILineConfig(KEY2_portSource, KEY2_PinSource);

    key1_exti_initStruct.EXTI_Line = KEY1_exti_line;      //指定输入线
    key1_exti_initStruct.EXTI_LineCmd = ENABLE;           //相应输入线对应的寄存器位的值
    key1_exti_initStruct.EXTI_Mode = EXTI_Mode_Interrupt; //指定是中断还是事件
    key1_exti_initStruct.EXTI_Trigger = EXTI_Trigger_Rising;  //规定触发信号是上升沿  

    key2_exti_initStruct.EXTI_Line = KEY2_exti_line;
    key2_exti_initStruct.EXTI_LineCmd = ENABLE;
    key2_exti_initStruct.EXTI_Mode = EXTI_Mode_Interrupt;
    key2_exti_initStruct.EXTI_Trigger = EXTI_Trigger_Rising;

    EXTI_Init(&key1_exti_initStruct);
    EXTI_Init(&key2_exti_initStruct);

    /* 3.初始化NVIC,用来确定优先级   */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);                  //主优先级和子优先级分配选择组一

    key1_nvic_initstruct.NVIC_IRQChannel = EXTI0_IRQn;              //NVIC的通道选择
    key1_nvic_initstruct.NVIC_IRQChannelCmd = ENABLE;
    key1_nvic_initstruct.NVIC_IRQChannelPreemptionPriority = 1;    //抢断优先级(主优先级)
    key1_nvic_initstruct.NVIC_IRQChannelSubPriority = 1;           //子优先级

    key2_nvic_initstruct.NVIC_IRQChannel = EXTI15_10_IRQn;         //通道的选择要注意!他并不是顺延排序的!
    key2_nvic_initstruct.NVIC_IRQChannelCmd = ENABLE;
    key2_nvic_initstruct.NVIC_IRQChannelPreemptionPriority = 1;
    key2_nvic_initstruct.NVIC_IRQChannelSubPriority = 1;
    NVIC_Init(&key1_nvic_initstruct);
    NVIC_Init(&key2_nvic_initstruct);
}

/*4.编写中断服务函数*/
void EXTI0_IRQHandler(void)
{
    // 先判断是否接受到中断
    if (EXTI_GetITStatus(KEY1_exti_line))
    {
        LED_R(OFF); 
        LED_G(ON);
    }
    EXTI_ClearITPendingBit(KEY1_exti_line);  //响应中断结束,挂起寄存器
}

void EXTI15_10_IRQHandler(void)
{
    // 先判断是否接受到中断
    if (EXTI_GetITStatus(KEY2_exti_line))
    {
        LED_G(OFF);
        LED_R(ON);  
    }
    EXTI_ClearITPendingBit(KEY2_exti_line);  //响应中断结束,挂起寄存器
}

猜你喜欢

转载自blog.csdn.net/super_marie/article/details/80039186