stm32F407外部中断Sample
关于stm32F407芯片所拥有的中断参数,这里就介绍了,官方手册上有,主要是记录中断开发的几个重要地方,如:io配置、中断调用流程、中断函数重写等。 本Sample是通过一个外部按键开关,控制两个LED灯交替切换点亮和熄灭。
一、硬件
输出:
- LED0<-->PF7;
- LED1<-->PF8;
输入:
- KEY<-->PF6(按键上拉电阻,注意配置需要同样设置,如果按键是其他的类型,需要根据实际情况配置
二、配置
- 时钟(RCC)配置:启用外部8M晶振的高速时钟,最高168M频率,STM32CubeMX可以自动设置;
- GPIO配置:
- PF7、PF8:设置为output,输出初始化电平分别设置为high和low,这样方便根据按键点亮和熄灭两个灯;
- PF6:设置为GPIO_EXTI6,gpio mode设置为上沿触发;gpio pull up/pull down设置为上拉电阻;
- NVIC配置:在GPIO栏目的NVIC标签页下,启用外部中断,我这里显示的外部中断编号为EXTI line[9:5],连接不同的GPIO接口,这个显示会不同
- SYS配置:启用串口调试
三、中断调用流程
通过STM32CubeMX配置硬件和软件环境后,自动生成的代码,可以先编译一次,这个各个库文件就会全部生成,可以方便的用F3功能跳转函数,查看函数的调用流程。
调用流程
main.c-->gpio.c-->stm32f4xx_it.c-->stm32f4xx_hal_gpio.c-->main.c
gipo.c
关键代码就是启用NVIC功能,配置IO引脚,代码如下:
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
stm32f4xx_it.c
此文件是在项目的src(源代码目录下) 系统会根据GPIO和NVIC的配置,自动生成一个中断函数void EXTI9_5_IRQHandler(void),此函数配置了GPIO的端口引脚,并调用通用中断函数,代码如下:
void EXTI9_5_IRQHandler(void)
{
/* USER CODE BEGIN EXTI9_5_IRQn 0 */
/* USER CODE END EXTI9_5_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_6);
/* USER CODE BEGIN EXTI9_5_IRQn 1 */
/* USER CODE END EXTI9_5_IRQn 1 */
}
stm32f4xx_hal_gpio.c
此文件是在驱动的库文件目录的driver目录下 中断函数在这里通过调用回调函数(callback),实现中断的功能。 在此文件中有两个函数,一个通用中断处理函数,一个回调函数
通用外部中断处理函数:主要有两个功能:1清除中断标记;2调用回调函数;注意函数里有一个if判断语句,这个是根据NVIC的配置中,我们使用配置了上升沿触发,即!=RESET
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
/* EXTI line interrupt detected */
if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
HAL_GPIO_EXTI_Callback(GPIO_Pin);
}
}
回调函数:__weak表明是一个虚函数,我们要实现的功能,就是覆写这个函数来实现。
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(GPIO_Pin);
/* NOTE: This function Should not be modified, when the callback is needed,
the HAL_GPIO_EXTI_Callback could be implemented in the user file
*/
}
四、代码
覆写回调函数,就是要在这个函数中实现我们的功能,比如判断触发的按键,按键输入触发后,实现的一系列动作。 回调函数的实现是在main.c文件中完成 以下代码是实现通过按键控制两个输出LED灯的切换交替点亮,即通过转换高低电平来实现。
/* USER CODE BEGIN 0 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
if(GPIO_Pin==GPIO_PIN_6) {
HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_7);
HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_8);
}
}
/* USER CODE END 0 */
五、其他
抄写一段内容
上升沿检测由低电平到高电平,下降沿检测由高电平到低电平。
在callback回调函数中,仅判断了端口号,而没有判断端口组,如果有两个都是6的端口号,但是分数不同端口组,如何判断呢!
- 另一个问题就是通过外部中断实现的按键输入,没有通过gpio扫描按键输入方式稳定