IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32F103 HAL库外部中断(三) -> 正文阅读

[嵌入式]STM32F103 HAL库外部中断(三)

HAL库基本使用系列的 全部博客是我重新学习HAL库的学习记录,仅作为学习记录。其中使用了正点原子Mini开发板和正点原子HAL库Demo,详细的资料请观看正点原子官网

??本来计划写一下串口的使用,但是前面的博客里面已经介绍到了串口的文件夹以及串口的初始化以及基本使用,最多就是在加一个中断处理函数,对接收到的数据进行处理,关于串口不同中断的区别,后期单独介绍。

??STM32F1 的每个 IO 都可以作为外部中断的中断输入口,中断控制器支持 19个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。
STM32F103 的 19 个外部中断为:

EXTI 线 0~15:对应外部 IO 口的输入中断。
EXTI 线 16:连接到 PVD 输出。
EXTI 线 17:连接到 RTC 闹钟事件。
EXTI 线 18:连接到 USB 唤醒事件。
EXTI 线 19:连接到以太网唤醒事件。

STM32通过映射关系,把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。而中断线每次只能连接到 1 个 IO 口上,这样就需要通过配置来决定对应的中断线配置到哪个 GPIO 上了。

IO 口外部中断的一般步骤:

1)使能 IO 口时钟。
2)调用函数 HAL_GPIO_Init 设置 IO 口模式,触发条件,使能 SYSCFG 时钟以及设置 IO
口与中断线的映射关系。
3)配置中断优先级(NVIC),并使能中断。
4)在中断服务函数中调用外部中断共用入口函数 HAL_GPIO_EXTI_IRQHandler。
5)编写外部中断回调函数 HAL_GPIO_EXTI_Callback。

1、外部中断配置

1.1、初始化中断I/O,设置触发条件

I/O作为中断,那么端口输入模式为输入模式。

GPIO_InitTypeDef GPIO_Initure;
    
    __HAL_RCC_GPIOA_CLK_ENABLE();               //开启GPIOA时钟
    __HAL_RCC_GPIOC_CLK_ENABLE();               //开启GPIOC时钟
    
    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_15; 				//PA15
    GPIO_Initure.Mode=GPIO_MODE_IT_FALLING;     //下降沿触发
    GPIO_Initure.Pull=GPIO_PULLUP;
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
	
	GPIO_Initure.Pin=GPIO_PIN_5; 				//PC5
    HAL_GPIO_Init(GPIOC,&GPIO_Initure);

通过定位查找,可以看到中断模式的设置有如下几种:

GPIO_MODE_IT_RISING(外部中断上升沿触发),
GPIO_MODE_IT_FALLING (外部中断下降沿触发)
GPIO_MODE_IT_RISING_FALLING(外部中断双边沿触发)

在这里插入图片描述
该函数内部会通过判断Mode 的值来开启 SYSCFG 时钟,并且设置 IO 口和中断线的映射关系。
初始化了PA0,如果PB0在初始化中断,那么PA0的中断映射将会被清除。

1.2、配置中断优先级(NVIC),并使能中断。

设置好了中断的触发模式等初始化参数。既然是外部中断,涉及到中断我们当然还要设置 NVIC 中断优先级。

 //中断线0-PA0
    HAL_NVIC_SetPriority(EXTI0_IRQn,2,2);       //抢占优先级为2,子优先级为2
    HAL_NVIC_EnableIRQ(EXTI0_IRQn);             //使能中断线0
    
	//中断线5-PC5
    HAL_NVIC_SetPriority(EXTI9_5_IRQn,2,1);   	//抢占优先级为2,子优先级为1
    HAL_NVIC_EnableIRQ(EXTI9_5_IRQn); 
	
    //中断线15-PA15
    HAL_NVIC_SetPriority(EXTI15_10_IRQn,2,0); 	//抢占优先级为2,子优先级为0
    HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);        	//使能中断线15

外部中断的5-9,10-15各自共用了一个通道EXTI15_10_IRQn以及EXTI9_5_IRQn,如图所示:
在这里插入图片描述

1.3、编写中断服务函数。

中断服务函数的名字是在 HAL 库中事先有定义的。STM32F1 的 IO 口外部中断函数只有 7 个,分别为:

void EXTI0_IRQHandler();
void EXTI1_IRQHandler();
void EXTI2_IRQHandler();
void EXTI3_IRQHandler();
void EXTI4_IRQHandler();
void EXTI9_5_IRQHandler();
void EXTI15_10_IRQHandler();

? 通过上面的图中我们也可以知道中断线 0-4 每个中断线对应一个中断函数,中断线 5-9 共用中断函数 EXTI9_5_IRQHandler,中断线 10-15 共用中断函数EXTI15_10_IRQHandler。

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

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

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

1.4、编写中断处理回调函数 HAL_GPIO_EXTI_Callback

通过查找可以看到HAL_GPIO_EXTI_Callback函数是HAL库定义的弱函数,我们可以重新定义新的回调函数,并且编写中断函数控制逻辑。
在这里插入图片描述
提 供 了一个中断通用入口 函 数HAL_GPIO_EXTI_IRQHandler,在该函数内部直接调用回调函数 HAL_GPIO_EXTI_Callback。

void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
 if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
 {
 __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
 HAL_GPIO_EXTI_Callback(GPIO_Pin);
 }
}

该函数实现的作用非常简单,就是清除中断标志位,然后调用回调函数
HAL_GPIO_EXTI_Callback()实现控制逻辑。

//中断服务程序中需要做的事情
//在HAL库中所有的外部中断服务函数都会调用此函数
//GPIO_Pin:中断引脚号
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_5:
            if(KEY0==0)  	//控制LED0翻转 
            {
                LED0=!LED0;
            }
            break;
        case GPIO_PIN_15:
            if(KEY1==0)  
            {
				LED1=!LED1;	//控制LED0翻转
            }
            break;
    }
}

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-12 16:46:05  更:2021-08-12 16:46:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/12 8:39:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码