【五】零基础上手HAL库之—按键外部中断

【五】零基础上手HAL库之—按键外部中断

按键开始

5.1 前言

我们已经大致的了解了Cubemx软件中GPIO的基本操作了,接下来我们开始进入外部中断的操作,这是一个惊心动魄的时刻,为什么呢?在使用Hal库的同时你会感觉到其优势性,开发效率大大提高带来的快感。

前期准备

  • STM32各类型的板子(本人使用F103Rc和F407ZE)。
  • CubeMx软件,Keil\_IDE。

5.2 Key按键中断

同样的我们先来看看按键模块的原理图部分:

【五】零基础上手HAL库之—按键外部中断_第1张图片

当按键没有按下时,按键部分相当于断路,PC13的电压相当于电容两端电压为3.3V。

当按键按下时,按键部分相当于短路(即一根导线),PC13的电压和GND地相连为0V。

所以按键从未按下到按下相当于是一个高电平到低电平的跳变,简称为下降沿。所以说我们在按键中断时选择的模式就是下降沿触发。

幻灯片1

1、新建工程

image-20210831144827291

搜索或者筛选芯片后,点击Start Project成功创建一个项目。

幻灯片2

2、时钟配置

image-20210831145137213

点击RCC进入时钟配置,配置高速时钟为外部晶振,软件自动配置了两个晶振的引脚如图PD0和PD1

幻灯片3

3、Debug配置为DAP

image-20210901134555619

幻灯片4

4、GPIO配置为中断

【五】零基础上手HAL库之—按键外部中断_第2张图片

  • ① GPIO模块配置模块
  • ② 各引脚配置: PC12/PC13(外部中断模式中断线12和13),共用一个中断向量。PC14/PC15输出模式为LED的两个引脚
  • ③ 引脚功能具体配置:

    • GPIO mode :上升沿/下降沿/上下降沿 中断和事件模式。
    • GPIO Pull-up/Pull-down:因为我的板子硬件上有上拉电阻即平常电平为高电平,所以配置为弱上拉形式。
    • User Lable:这里没有使用到用户标签为了方便在图中右半部分看到引脚所配置的功能。
  • ④ 输出模式配置:PC14/PC15配置为输出模式,控制LED灯亮灭。
  • ⑤ 外部中断线13:PC13为下降沿触发的外部中断模式,KEY1。
  • ⑥ 外部中断线12:PC12为下降沿触发的外部中断模式,KEY2。

幻灯片5

5、项目管理配置以及代码生成配置

这里我们还是一样配置为最高的时钟频率72M,在对应的框中输入72,按下回车即可见到如下两图的变化。按下回车前如图:

image-20210901135110375

按下回车后如图:

image-20210901135127689

幻灯片6

6、项目管理配置以及代码生成配置

同样的我们填写好工程名KEY,选择好文件路径,以及所用的IDE以及版本号即可

image-20210901135251221

代码生成选择好这两个后点击右上角按钮,产生代码:

image-20210901135319234

幻灯片7

7、业务逻辑代码

7.1 API

我们再来看看GPIO模块对应的API函数:

/* 初始化和删除初始化函数,
    HAL_GPIO_Init:cubemx生成代码后自动调用初始化函数
    HAL_GPIO_DeInit:解除初始化,不想使用时可以主动使用*/
void  HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, GPIO_InitTypeDef *GPIO_Init);
void  HAL_GPIO_DeInit(GPIO_TypeDef  *GPIOx, uint32_t GPIO_Pin);

/* 操作GPIO的函数,包括读取,写入,翻转,加锁,中断服务函数以及回调函数
    HAL_GPIO_ReadPin:读取引脚电平    返回值为(GPIO_PIN_RESET/GPIO_PIN_SET) 
    HAL_GPIO_WritePin:写入引脚电平 
    HAL_GPIO_TogglePin:翻转引脚电平
    HAL_GPIO_LockPin:所以引脚当前电平,将无法改变
    HAL_GPIO_EXTI_IRQHandler:引脚的中断服务函数
    HAL_GPIO_EXTI_Callback:引脚的中断回调函数 */
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
7.2 编写回调函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if(GPIO_Pin == GPIO_PIN_12)
    {
        HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_14);
    }
    
    if(GPIO_Pin == GPIO_PIN_13)
    {
        HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_15);
    }
}

我们来看看回调函数是怎么工作的:

①:产生中断进入函数 void HAL\_GPIO\_EXTI\_IRQHandler(uint16\_t GPIO\_Pin);

②:获取产生中断的引脚

③:清除对应引脚的标志位

④:进入回调函数对此行为进行处理,产生相应的动作

⑤:回到函数 void HAL\_GPIO\_EXTI\_IRQHandler(uint16\_t GPIO\_Pin);直至跳出函数。

所以说回调函数相当于用户层的应用函数,也就是只需要在回调函数写入相应引脚产生中断而要做出的反应即可,不需要像标准库那样手动的清除标志位。

所以16个外部中断只需要调用一个函数进行if判断即可,真正的模块化编程!!!!

来看看外部中断还能做什么

​ 比如可以用来:超声波测距,编码器测速,按键中断等等,凡是要测上下降沿的应用均可使用。

最后就是下载代码的兴奋时刻了:

下载代码到板子中,我们按下不同的按键不同的LED对应的进行电平的翻转操作。

好啦,外部中断就是这么简单就结束了,怎么样是不是感觉也很简单呀!

你可能感兴趣的