正点原子HAL库 STM32F4 外部中断(学习自用附源码)

实验目的:

外部中断来控制等亮灭等基础功能

硬件资源:

STM32F4正点原子开发板

F4中断简介:

STM32F4 的每个 IO 都可以作为
外部中断的中断输入口,这点也是 STM32F4 的强大之处。 STM32F407 的中断控制器支持 23
个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。
STM32F407 的 23 个外部中断为:
EXTI 线 0~15:对应外部 IO 口的输入中断。
EXTI 线 16:连接到 PVD 输出。
EXTI 线 17:连接到 RTC 闹钟事件。
EXTI 线 18:连接到 USB OTG FS 唤醒事件。
EXTI 线 19:连接到以太网唤醒事件。
EXTI 线 20:连接到 USB OTG HS(在 FS 中配置)唤醒事件。
EXTI 线 21:连接到 RTC 入侵和时间戳事件。
EXTI 线 22:连接到 RTC 唤醒事件。
从上面可以看出, STM32F4 供 IO 口使用的中断线只有 16 个,但是 STM32F4 的 IO 口却
远远不止 16 个,那么 STM32F4 是怎么把 16 个中断线和 IO 口一一对应起来的呢? 于是 STM32
就这样设计, GPIO 的管脚 GPIOx.0~GPIOx.15(x=A,B,C,D,E, F,G,H,I)分别对应中断线 0~15。这样每个中断线对应了最多 9 个 IO 口,以线 0 为例:它对应了 GPIOA.0、 GPIOB.0、 GPIOC.0、GPIOD.0、 GPIOE.0、 GPIOF.0、 GPIOG.0,GPIOH.0,GPIOI.0。而中断线每次只能连接到 1 个 IO口上,这样就需要通过配置来决定对应的中断线配置到哪个 GPIO 上了。下面我们看看 GPIO
跟中断线的映射关系图:

开启中断的步骤:

①使能IO时钟,初始化IO输入(这里是开发板按键的设置)

②设置IO模式,触发条件

    GPIO_InitTypeDef GPIO_Initure;
    
    __HAL_RCC_GPIOA_CLK_ENABLE();               //开启GPIOA时钟
    __HAL_RCC_GPIOE_CLK_ENABLE();               //开启GPIOE时钟
    
    GPIO_Initure.Pin=GPIO_PIN_0;                //PA0
    GPIO_Initure.Mode=GPIO_MODE_IT_RISING;      //上升沿触发
    GPIO_Initure.Pull=GPIO_PULLDOWN;
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
    
    GPIO_Initure.Pin=GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4; 	//PE2,3,4
    GPIO_Initure.Mode=GPIO_MODE_IT_FALLING;     //下降沿触发
    GPIO_Initure.Pull=GPIO_PULLUP;
    HAL_GPIO_Init(GPIOE,&GPIO_Initure);

③配置中断优先级(NVIC),使能中断

    HAL_NVIC_SetPriority(EXTI0_IRQn,2,0);       //抢占优先级为2,子优先级为0
    HAL_NVIC_EnableIRQ(EXTI0_IRQn);             //使能中断线0
    
    //中断线2-PE2
    HAL_NVIC_SetPriority(EXTI2_IRQn,2,1);       //抢占优先级为2,子优先级为1
    HAL_NVIC_EnableIRQ(EXTI2_IRQn);             //使能中断线2
    
    //中断线3-PE3
    HAL_NVIC_SetPriority(EXTI3_IRQn,2,2);       //抢占优先级为2,子优先级为2
    HAL_NVIC_EnableIRQ(EXTI3_IRQn);             //使能中断线2
    
    //中断线4-PE4
    HAL_NVIC_SetPriority(EXTI4_IRQn,2,3);   	//抢占优先级为2,子优先级为3
    HAL_NVIC_EnableIRQ(EXTI4_IRQn);         	//使能中断线4

④编写中断服务函数(EXTIX_IRQHandle函数HAL库已经写好了,按照如此照搬即可,HAL_GPIO_EXTI_IRQHandle函数会调用HAL_GPIO_EXTI_Callback中断处理函数

void EXTI0_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);		//调用中断处理公用函数
}

void EXTI2_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);		//调用中断处理公用函数
}

void EXTI3_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3);		//调用中断处理公用函数
}

void EXTI4_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);		//调用中断处理公用函数
}

⑤编写中断处理回调函数

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    delay_ms(100);      //消抖
    switch(GPIO_Pin)
    {
        case GPIO_PIN_0:
            if(WK_UP==1) 
            {
				LED1=!LED1;//控制LED0,LED1互斥点亮
				LED0=!LED1;
            }
            break;
        case GPIO_PIN_2:
            if(KEY2==0)  //LED1翻转
            {
                LED1=!LED1;    
            }
            break;
        case GPIO_PIN_3:
            if(KEY1==0)  //同时控制LED0,LED1翻转 
            {
                LED0=!LED0;
				LED1=!LED1;
            }
            break;
        case GPIO_PIN_4:
            if(KEY0==0)  
            {
				LED0=!LED0;//控制LED0翻转
            }
            break;
    }
}

⑥main函数


int main(void)
{
    HAL_Init();                    	//初始化HAL库    
    Stm32_Clock_Init(336,8,2,7);  	//设置时钟,168Mhz
	  delay_init(168);               	//初始化延时函数
	  uart_init(115200);              //初始化USART
	  LED_Init();						//初始化LED	
    KEY_Init();                     //初始化按键
	  EXTI_Init();                    //外部中断初始化
	
	
    while(1)
    {	
		printf("OK\r\n");           //打印OK提示程序运行
        delay_ms(1000);             //每隔1s打印一次 
    }
}

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值