6. Stm32f407 key中断方式示例

                          6. Stm32f407 key中断方式示例

 

硬件平台:  stm32f407ve

软件平台:  win10 (OS Name:                   Microsoft Windows 10 Enterprise

                                  OS Version:                10.0.18363 N/A Build 18363)

             Keil5  5.26.2

             HAL库版本: 2.14.0(目前下载的最新的)

时间:   2020-02-12

 

中断:这个概念一般有点难以理解,但是又是一个非常重要的功能,基本所有的单片机(或者说处理器)都有中断。可见中断的重要性。51单片机都有5个中断源,这是我接触到的最简单的中断系统了。

 

打个比方,还是手机的那个例子,上次我说的是查询方式,这次我们的手机有了铃声了。那你需要接听任何一个电话还需要一直盯着屏幕吗?那很明显,不需要了,只要把手机带在身边,你随时可以被铃声暂停手头的事情(可能你在吃饭,睡觉,打豆豆等待各种日常生活),来接听呼入的电话。暂停手头的事情,接听电话就对应着cpu的中断处理过程(实际过程比这个要复杂一些),暂停当前的程序,跳到中断处理程序处理事件,然后返回继续当前的工作(当然接完电话,你也会回来继续干手中的事情)。还有一个比较小的细节就是,当你接电话的时候,实际你会在大脑中记住你刚刚在干嘛,不然等一下你放下电话就不知道要继续干嘛了。这个细节对应cpu也是同样需要处理的,所以就会有中断跳转之前会有现场保护(主要是寄存器值得保存到栈里),一会中断处理完之后(将之前保存到栈里的值重新返回寄存器,这个部分比较底层,涉及到cpu在执行指令时会用到哪些寄存器及cpu怎么执行指令的理论部分,这个地方不了解的话,确实不太好理解)还能回来接着干活。

扫描二维码关注公众号,回复: 9115200 查看本文章

 

但是你要意识到一个问题,程序可以跳转,还能跳转回来,这个需要一些复杂的机制才能处理,绝对不是直接跳来跳去。

 

回到正题,我们处理这个按键中断,stm32f407支持的中断比较多,外部中断只是其中的中断一个小部分。外部中断是指外部引脚电平的变化引起的中断事件。Stm32f407ve有82个引脚,82个引脚都可以设置中断,但是最多只能设置16个中断。这个因为GPIOA1,GPIOB1....GPIOH1共用了一个外部中断,如果GPIOB1设置了中断,那么其他组的1脚就无法设置为中断方式了。

这个地方可以参考中文参考手册的部分,比较详细。

 

按键中断有利于改善cpu的效率,cpu不用一直查询按键的状态,等到有按键按下的时候,直接打断cpu的执行,做中断处理。所以cpu在其他时间就可以完成很多任务了。(所有中断有利于改善cpu对于输入事件的处理效率)。

 

中断优先级(stm32f4的中断一共有81个吧,这么多中断一起的话,不可能都是同一个优先级,某些中断肯定要有些优越感,优先级高,有些中断就会被冷落,不重要就优先级低。这里同样注意一个问题,不一定我们每个中断都要设置优先级,我们只需要设置我们需要使用的中断就可以了。),程序中我们暂不处理这个问题,大家有点印象,就是多个中断同时发生的时候,优先级高的,可以被优先处理,如果优先级相同,就选择最先监测到中断的那个开始执行中断处理。还有一个会涉及到抢占,比如一个优先级的中断正在处理,但是一个比这个优先级更高的中断发生了,那么系统会再次打断正在处理的中断程序,处理更高优先级的事件。当然如果时低优先级的中断发生了,那么是不会被打断的。按键这个地方我们的优先级一般会设置一样,另一个角度来讲,几个按键同时触发中断的可能性极低,其实也不需要把某个按键做更紧急的处理(至少在我的程序中不需要这么处理)。

 

好,说了这么多,还是写程序,改动会比较大。

 

1.Keil的组件要增加外部中断的部分。

 

  1. 增加以下代码
  1. 设置按键中断模式
  2. 设置按键中断处理函数
  3. 主函数中修改按键的初始化函数,修改主循环(这里什么都不做,空转)

#include <stm32f4xx.h>


void led_init(void)
{	
	GPIO_InitTypeDef GPIO_Init;

	//1.时钟使能
	__HAL_RCC_GPIOE_CLK_ENABLE();
	
	
	//2.端口设置
	GPIO_Init.Mode = GPIO_MODE_OUTPUT_OD;  //输出开漏模式
	GPIO_Init.Pin = GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
	GPIO_Init.Pull = GPIO_PULLUP;
	GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
//	GPIO_Init.Alternate = ;  //GPIO的mode设置位复用功能的时候,才会配置复用功能
	HAL_GPIO_Init(GPIOE, &GPIO_Init);
	
	//3.点亮或熄灭灯
}







/*按键初始化*/
void key_init(void)
{	
	GPIO_InitTypeDef GPIO_Init;

	//1.时钟使能,按键使用的时GPIOE
	__HAL_RCC_GPIOE_CLK_ENABLE();
	
	
	//2.端口设置
	GPIO_Init.Mode = GPIO_MODE_INPUT;  //输入模式
	GPIO_Init.Pin = GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;   //设置的引脚
	GPIO_Init.Pull = GPIO_NOPULL;      //上拉电阻可以有也可以没有,电路本身有上拉
//	GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;    //这个是设置输出速度,输入模式可以不管
//	GPIO_Init.Alternate = ;  //GPIO的mode设置位复用功能的时候,才会配置复用功能
	HAL_GPIO_Init(GPIOE, &GPIO_Init);
	
}




/*按键中断方式初始化*/
void key_int_init(void)
{
	GPIO_InitTypeDef GPIO_Init;

	//1.时钟使能,按键使用的时GPIOE
	__HAL_RCC_GPIOE_CLK_ENABLE();
	
	
	//2.端口设置
	GPIO_Init.Mode = GPIO_MODE_IT_FALLING;  //下降沿中断模式
	GPIO_Init.Pin = GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;   //设置的引脚
	GPIO_Init.Pull = GPIO_NOPULL;      //上拉电阻可以有也可以没有,电路本身有上拉

	HAL_GPIO_Init(GPIOE, &GPIO_Init);


	NVIC_SetPriority(EXTI15_10_IRQn,0xA0);  //设置简单的中断优先级
	NVIC_EnableIRQ(EXTI15_10_IRQn);  //外部中断,10-15共用一个外部中断
	
	
}



/*
	按键测试程序,我的例子实现为,(这是最简单的方法)
    第一个按键按下的时候,第一个灯点亮
	第二个按键按下的时候,第二个灯点亮
	第三个按键按下的时候,第三个灯点亮
*/

int main(void)
{
	int i;
	GPIO_PinState pins;
	
	
	HAL_Init();  //必须在第一个语句执行
	
	led_init();
	
	key_int_init();
	
	while(1)
	{
		//什么事都不做,空转

	}
}


void EXTI15_10_IRQHandler(void)
{
	uint32_t ret;
	EXTI_HandleTypeDef hexti;
	int i;
	uint32_t arr[3] = {EXTI_LINE_10,EXTI_LINE_11,EXTI_LINE_12};
	uint32_t ledarr[3] = {GPIO_PIN_13,GPIO_PIN_14,GPIO_PIN_15};
		
	for(i=0;i<3;i++)
	{
		hexti.Line = arr[i];       //哪一个外部中断线触发中断
		ret = HAL_EXTI_GetPending(&hexti, EXTI_TRIGGER_FALLING);
		if(ret)   
		{
			//中断处理比较简单,直接翻转led
			HAL_GPIO_TogglePin(GPIOE, ledarr[i]);
			
			//清中断标志
			HAL_EXTI_ClearPending(&hexti, EXTI_TRIGGER_FALLING); //下降沿
		}
	}
}


void SysTick_Handler(void)
{
	HAL_IncTick();
}

github的工程源码:

https://github.com/zhaozhi0810/stm32f407_hal_keil5

发布了24 篇原创文章 · 获赞 18 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/zhaozhi0810/article/details/104288757