STM32
直播中

好名字

9年用户 875经验值
擅长:可编程逻辑
私信 关注
[问答]

STM32CubeMX中外部中断怎么使用?

STM32CubeMX中外部中断怎么使用?

回帖(1)

李晔皓

2021-11-23 11:23:27
  前言

  今天我们来学习STM32CubeMX中外部中断的使用,实现按下KEY0 KEY1 KEY2
中断-->IO-->按键映射:
  EXTI2-->PE2-->KEY2
  EXTI3-->PE3-->KEY1
  EXTI4-->PE4-->KEY0
IO-->LED映射:
  PB5-->LED0
  PE5-->LED1
  1、GPIO及RCC配置






  在配置GPIO之前需要先打开HSE,并设置为晶振为时钟源。





  而后就可以设置按键对应的管脚为外部中断模式了。





  点击System Core中的GPIO选项后先选择按键映射的GPIO的GPIO mode                                                         [                            1                            ]                                           ^{[1]}               [1]:其中有六个选项:
External Interupt Mode with Rising edge trigger detection
External Interupt Mode with Falling edge trigger detection
External Interrupt Mode with Rising/Faling edge trigger detection
External Event Mode with Rising edge trigger detection
External Event Mode with Falling edge trigger detection
External Event Mode with Rising/Faling edge trigger detection
  分别对应着外部中断和外部事件的上升沿触发、下降沿触发和上升/下降沿触发。
  如果按键没有外接上拉电阻的话我们需要先选择Pull up                                                         [                            2                            ]                                           ^{[2]}               [2]打开内置上拉电阻即可实现按键按下产生下降沿。
  在User Label                                                         [                            3                            ]                                           ^{[3]}               [3]中我们可以自定义GPIO的名称,这个名称会在Pinout View界面和工程中的main.h文件中做同步更改。





2、NVIC设置






  使用中断,免不了配置NVIC我们可以参照下表来选择Proority Group                                                         [                            1                            ]                                           ^{[1]}               [1],然后选中要配置的EXTI linex interrupt在Preemption Priority                                                         [                            2                            ]                                           ^{[2]}               [2]中选择其抢占优先级和子优先级,然后勾选Enable来使能中断。





  在NVIC边上还有一个Code generation选项卡在其中我们可以选择我们想要排序的中断,然后可以在Rank栏看到排序序号。










3、其他设置

3.1、时钟设置、生成工程

  按照下图选择HSE作为主时钟源来源即可。





  随后按照流程填写工程名,设置Code generation而后生成工程即可。
3.2、中断后的操作

  中断触发后在HAL里调用顺序是这样子的:
EXTI15_10_IRQHandler --> HAL_GPIO_EXTI_IRQHandler --> HAL_GPIO_EXTI_Callback
  而__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)函数是一个弱定义函数。
  函数名称前面加上__weak修饰符,我们一般称这个函数为“弱函数”。
  加上了__weak 修饰符的函数,用户可以在用户文件中重新定义一个同名函数,最终编译器编译的时候,会选择用户定义的函数,如果用户没有重新定义这个函数,那么编译器就会执行__weak声明的函数,并且编译器不会报错。所以我们可以在别的地方定义一个相同名字的函数,而不必也尽量不要修改之前的函数。
  ST官方这么做即做到了响应外部中断又做到了让事件在清楚外部中断标志之后完成,从而避免了一些中断嵌套。
  我们可以在gpio.c文件的最下方定义自己的HAL_GPIO_EXTI_Callback函数来完成在中断中想做的操作:





按键消抖:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
        if(GPIO_Pin==KEY2_Pin)//KEY2
        {       
                HAL_Delay(20);//延时20ms
                if(HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)==GPIO_PIN_RESET)
                {
                        HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
                        HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5);
                }
        }
        else if(GPIO_Pin==KEY1_Pin)//KEY1
        {       
                HAL_Delay(20);//延时20ms
                if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==GPIO_PIN_RESET)
                {
                        HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
                }
        }
        else if(GPIO_Pin==KEY0_Pin)//KEY0
        {       
                HAL_Delay(20);//延时20ms
                if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)==GPIO_PIN_RESET)
                {
                        HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5);
                }
        }
}
4、之于STM32L151C8T6

原理图:





配置调试端口:





选择HSE来源为外部晶振输入:





GPIO设置:





NVIC设置:





时钟树设置:





添加代码:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
        static uint8_t SwitchIndex = 0;
        if(GPIO_Pin==KEY_USER_Pin)//KEY_USER
        {       
                HAL_Delay(20);//延时20ms
                if(HAL_GPIO_ReadPin(KEY_USER_GPIO_Port,KEY_USER_Pin)==GPIO_PIN_RESET)
                {
                        if(SwitchIndex == 0)
                        {
                                HAL_GPIO_WritePin(GPIOA,RED_Pin|GREEN_Pin|BLUE_Pin,GPIO_PIN_SET);
                                HAL_GPIO_WritePin(RED_GPIO_Port,RED_Pin,GPIO_PIN_RESET);
                                SwitchIndex++;
                        }
                        else if(SwitchIndex == 1)
                        {
                                HAL_GPIO_WritePin(GPIOA,RED_Pin|GREEN_Pin|BLUE_Pin,GPIO_PIN_SET);
                                HAL_GPIO_WritePin(GREEN_GPIO_Port,GREEN_Pin,GPIO_PIN_RESET);
                                SwitchIndex++;
                        }
                        else if(SwitchIndex == 2)
                        {
                                HAL_GPIO_WritePin(GPIOA,RED_Pin|GREEN_Pin|BLUE_Pin,GPIO_PIN_SET);
                                HAL_GPIO_WritePin(BLUE_GPIO_Port,BLUE_Pin,GPIO_PIN_RESET);
                                SwitchIndex = 0;
                        }
                }
        }
}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分