PRELOADER

不念过去 不负现在 不畏将来

当前文章 : 《STM32 外部中断实验》

12/4/2018 —— 

STM32 外部中断实验

项目说明

STM32共用68个外部中断,16个内部中断,并且有16级的中断优先级设置。比起51内核单片机,STM32的中断设置要复杂和强大的多。

知识点

  • 1、68个外部中断源包括很多种类,比如iic中断,uart中断,can中断等。
  • 2、两种中断优先级。每一个中断源都要设置中断优先等级,由4位数来控制,所以共有16种。这4位数字中包括两种优先级,分别为 抢占式优先级和响应式优先级。抢占式优先级的优先级高于响应式优先级,同时,抢占式优先级支持嵌套,响应式优先级不支持嵌套。
  • 3、4位数分两种优先级,共有 5种搭配方式,即分别为抢占式优先级和响应式优先级的位数分别为4/0,3/1,2/2,1/3,0/4. 采用库函数编写代码是,分别为NVIC_PriorityGroup_1,NVIC_PriorityGroup_2 … NVIC_PriorityGroup_5 。
  • 4、这里采用的是外部按键中断,其本质还是GPIO口的输入中断,对应中断源为 EXTI中断 。STM32的每一个GPIO口均可以作为中断输入,但是由于EXTI中断的特性,STM32它 一次性同时使用的外部 中断只能有 16 个, 而且同时做外部中断的 IO 口序号也是不能相同的, 比如, 你使用 PA0 做外部中断了,那么就不能同时使用 PB0 做外部中断了。
  • 5、配置GPIO口中断时,使用下降沿触发,那么就选择上拉输入模式,要使用上升沿触发,那么就选择下拉输入模式。

部分代码

  • 1、外部中断函数初始化。这里需要设置GPIO,之后选择外部中断模式,最后进行参数配置。
void exti_init()  //外部中断初始化
{
    GPIO_InitTypeDef GPIO_InitStructure;

    EXTI_InitTypeDef EXTI_InitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;

    /* 开启GPIO时钟 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);

    GPIO_InitStructure.GPIO_Pin=k_left;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOE,&GPIO_InitStructure);

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource2);//选择GPIO管脚用作外部中断线路
    //此处一定要记住给端口管脚加上中断外部线路
    /* 设置外部中断的模式 */
    EXTI_InitStructure.EXTI_Line=EXTI_Line2;
    EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    /* 设置NVIC参数 */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);         
    NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;     //打开EXTI2的全局中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级为0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;          //响应优先级为0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           //使能
    NVIC_Init(&NVIC_InitStructure);         
}

  • 2、STM32的中断和之前写的51不一样。中断后的算法逻辑需要添加到user文件夹下的stm32f10x_it.c文件中。 如下为实现按键控制LED状态,代码为stm32f10x_it.c代码中的部分。
void EXTI2_IRQHandler()       //外部中断2中断函数
{
    if(EXTI_GetITStatus(EXTI_Line2)==SET)
    {
           EXTI_ClearITPendingBit(EXTI_Line0);//清除EXTI线路挂起位
        delay_ms(10);//消抖处理
        if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==Bit_RESET)       //k_left按键按下
        {
            delay_ms(10);//消抖处理
            if(GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_0)==Bit_RESET)
            {
                //LED 熄灭
               GPIO_SetBits(GPIOC,GPIO_Pin_0);
            }
            else
            {
               //LED 发光
                GPIO_ResetBits(GPIOC,GPIO_Pin_0);
            }
        }
        while(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==0);
    }        
}