这一例我们在前面GPIO的工程基础上修改。复制GPIO的工程,修改文件夹名。点击GPIO.ioc打开STM32cubeMX的工程文件重新配置。PA0管脚重新配置为GPIO_EXIT0模式。
按键已经外部上拉,按下去PA0为高电平。在GPIO配置中配置PA0为上升沿触发。内部既不上拉也不下拉
在NVIC(嵌套向量中断控制器)中,勾选EXIT Line0 interrupt使能PA0中断。右边两个选项设置抢占优先级和响应优先级。此处我们选择修改为抢占优先级1
NVIC(嵌套向量中断控制器)的相关知识可以在下方链接查看,有兴趣的话
在这里我们就配置好stm32CubeMX工程,重新生成报告,以及重新生成代码,编译程序。
在USER CODE BEGIN 2 和 USER CODE END 2中添加HAL_NVIC_SetPriority(SysTick_IRQn,0, 0U);,使得系统延生可以在中断中使用。
打开main.c文件。把main()函数里while循环上一例的代码删掉,while循环里面为空。在main.c文件后面USER CODE BEGIN 4 和 USER CODE END 4 中间添加中断回调函数。
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_4)
{
if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==0)
{
HAL_Delay(10);
if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==0)
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
}
}
}
}
在回调函数中为什么要使用HAL_Delay,是因为要进行按键消抖
重新编译程序,编译通过后下载到STM32F103ZE开发板。如果没有错误,按下一下S4按键LED3的状态改变一次
在stm32f1xx_it.c中断服务函数文件中,我们可以找到EXTI0中断的服务函数。
中断服务函数里面就调用了GPIO外部中断处理函数HAL_GPIO_EXTI_IRQHandler(),参数为GPIO_PIN_0,即EXTI0中断。GPIO外部中断处理函数主要就是清除中断标识位,然后调用中断回调函数HAL_GPIO_EXTI_Callback()。我们只需重构中断回调函数,在函数里面添加我们的应用代码即可(程序中为翻转LED3状态)。
执行完中断服务函数后。内核从堆栈去除压入的寄存器数据恢复现场,取出主程序中断点的地址,转到到主程序中断点的地址继续运行主程序。
OK,到这里就完成一次中断服务。简单的来说,触发中断时,硬件先标识中断标识位,然后NVIC中断控制器判断中断优先级是否可以执行此中断。执行中断时,先保护现在程序的状态,将数据保存进堆栈中,执行完中断服务函数后,再在堆栈中取数据回复现场,跳回主程序继续运行。如果在中断服务函数中有更高优先级的中断触发,则也会将现在的数据保存去执行更高优先级的中断服务函数,即中断嵌套。高优先级的中断执行完后,恢复现场,继续执行低优先级的服务函数。
这一例我们在前面GPIO的工程基础上修改。复制GPIO的工程,修改文件夹名。点击GPIO.ioc打开STM32cubeMX的工程文件重新配置。PA0管脚重新配置为GPIO_EXIT0模式。
按键已经外部上拉,按下去PA0为高电平。在GPIO配置中配置PA0为上升沿触发。内部既不上拉也不下拉
在NVIC(嵌套向量中断控制器)中,勾选EXIT Line0 interrupt使能PA0中断。右边两个选项设置抢占优先级和响应优先级。此处我们选择修改为抢占优先级1
NVIC(嵌套向量中断控制器)的相关知识可以在下方链接查看,有兴趣的话
在这里我们就配置好stm32CubeMX工程,重新生成报告,以及重新生成代码,编译程序。
在USER CODE BEGIN 2 和 USER CODE END 2中添加HAL_NVIC_SetPriority(SysTick_IRQn,0, 0U);,使得系统延生可以在中断中使用。
打开main.c文件。把main()函数里while循环上一例的代码删掉,while循环里面为空。在main.c文件后面USER CODE BEGIN 4 和 USER CODE END 4 中间添加中断回调函数。
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_4)
{
if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==0)
{
HAL_Delay(10);
if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==0)
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
}
}
}
}
在回调函数中为什么要使用HAL_Delay,是因为要进行按键消抖
重新编译程序,编译通过后下载到STM32F103ZE开发板。如果没有错误,按下一下S4按键LED3的状态改变一次
在stm32f1xx_it.c中断服务函数文件中,我们可以找到EXTI0中断的服务函数。
中断服务函数里面就调用了GPIO外部中断处理函数HAL_GPIO_EXTI_IRQHandler(),参数为GPIO_PIN_0,即EXTI0中断。GPIO外部中断处理函数主要就是清除中断标识位,然后调用中断回调函数HAL_GPIO_EXTI_Callback()。我们只需重构中断回调函数,在函数里面添加我们的应用代码即可(程序中为翻转LED3状态)。
执行完中断服务函数后。内核从堆栈去除压入的寄存器数据恢复现场,取出主程序中断点的地址,转到到主程序中断点的地址继续运行主程序。
OK,到这里就完成一次中断服务。简单的来说,触发中断时,硬件先标识中断标识位,然后NVIC中断控制器判断中断优先级是否可以执行此中断。执行中断时,先保护现在程序的状态,将数据保存进堆栈中,执行完中断服务函数后,再在堆栈中取数据回复现场,跳回主程序继续运行。如果在中断服务函数中有更高优先级的中断触发,则也会将现在的数据保存去执行更高优先级的中断服务函数,即中断嵌套。高优先级的中断执行完后,恢复现场,继续执行低优先级的服务函数。
举报