STM32CubeMX是官方推荐的配置软件,而HAL库也是取代之前的库函数的通用库,所以STM32CubeMX+HAL库是当前主流的工程创建方式,HAL库的可移植性也高于被取代的库函数。
之前在[程序员小哈]的公众号中写过两篇基于STM32CubeMX软件的文章,今天对其进行了转载。
今天我们利用STM32CubeMX实现按键(外部中断)翻转一个LED,涉及到的新知识点:外部中断。
软硬件环境
- Keil 5.14
- STM32F103RET6核心板【202006每月活动】
- STM32CubeMX 5.3
- 按键(PA12)
- LED(PA11)
STM32CubeMX创建工程
- 打开STM32CubeMX软件,从如下箭头所示两个位置可以新建工程。
- 选择芯片STM32F103RET6,可以在下图左侧位置进行检索,缩小待筛选范围。
- 查看核心板的原理图,知道LED对应GPIO的PA11,按键对应的GPIO为PA12。
- 配置PA12为外部中断模式
- 配置PA11为输出模式
- GPIO配置
注意:因为下面按键中断的回调函数中我们加了延时防抖功能,所以此处必须是下降沿触发,至于为什么?大家可以想想哈,大家可以在留言中交流一下。
- 使能外部中断,注意中断分组
- 配置RCC
- SYS要如下设置,否则下载一次程序以后将无法再次下载!!!
- 配置串口1为异步串口
因为PA12占用了串口1的USART1_RTS引脚,所以串口1配置成禁用硬件流控的异步串口即可。
- 时钟树配置
- 工程配置,工程名称:STM32EXTIDemo。
- 生成代码
usart.c文件中,添加串口printf输出代码
#include "stdio.h"
#ifdef __GNUC__
/* With GCC, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
- 添加按键中断回调函数
/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
switch(GPIO_Pin)
{
case KEY0_Pin:
HAL_Delay(10);
if( HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin)==0) //延时10ms之后再判断是否有按键被按下,防抖
{
printf("KEY0 Press ... \r\n");
HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);
}
break;
default:break;
}
}
/* USER CODE END 4 */
其中:
HAL_GPIO_TogglePin() 函数用于实现翻转 IO 口的电平。
实现同样功能,还可以使用下面代码分别控制LED的亮灭:HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_RESET) // 输出低电平--亮 HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_SET) // 输出高电平--灭
我们为什么添加了上面的函数,然后就能与中断函数绑定到一起呢?
因为这里涉及到一个“弱函数”的知识。
在 HAL库中,很多回调函数前面使用__weak 修饰符。weak 顾名思义是“弱”的意思,所以如果函数名称前面加上__weak 修饰符,我们一般称这个函数为“弱函数”。加上了__weak 修饰符的函数,用户可以在用户文件中重新定义一个同名函数,最终编译器编译的时候,会选择用户定义的函数,如果用户没有重新定义这个函数,那么编译器就会执行__weak 声明的函数,并且编译器不会报错。
我们搜索HAL_GPIO_EXTI_Callback()这个函数,发现的确有__weak修饰的同名函数。
这个函数在stm32f1xx_hal_gpio.c文件中的HAL_GPIO_EXTI_IRQHandler()函数中被调用,该函数对中断标志位进行了清除。
而上面的函数正好在外部中断函数EXTI15_10_IRQHandler()中被调用。
由上可知,当GPIO发生外部中断时,我们只要在回调函数HAL_GPIO_EXTI_Callback()中,添加逻辑代码即可。
- 配置JLINK下载工具
- 下载程序后,复位核心板,按下按键,串口助手窗口可以正常打印预设信息,LED亮灭来回切换,证明满足预期使用外部中断反转一个LED。
结果展示