STM32F103外部中断配置

一、外部中断

在上一节我们介绍了STM32f103的嵌套向量中断控制器,其中包括中断的使能、失能、中断优先级分组以及中断优先级配置等内容。

1.1 外部中断/事件控制器

STM32f103支持的60个可屏蔽中断中,有一些比较特殊的中断:

  • 中断编号13 EXTI0EXTI线0中断;

  • 中断编号14 EXTI1EXTI线1中断;

  • 中断编号15 EXTI2EXTI线2中断;

  • 中断编号16 EXTI3EXTI线3中断;

  • 中断编号17 EXTI4EXTI线4中断;

  • 中断编号30 EXTI9_5EXTI线[9:5]中断;

  • 中断编号47 EXTI15_10EXTI线[15:10]中断;

  • 中断编号8 PVD:连到EXTI的电源电压检测(PVD)中断;

  • 中断编号48 RTCAlarm:连到EXTI线16RTC闹钟时间;

  • 中断编号49 USB唤醒:连到EXTI的线17USB待机唤醒事件;

  • 对于STM32F107来说,还有一个连到EXTI线18的以太网唤醒事件;

对于STM32f103来说,有19个能产生事件/中断请求的边沿检测器。每个输入线可以独立地配置输入类型(脉冲或挂起)和对应的触发事件(上升沿或下降沿或者双边沿都触发)。每个输入线都可以独立地被屏蔽。挂起寄存器保持着状态线的中断请求。

1.1.1 EXTI线与IO映射关系4

EXTI线0~15:对应外部IO口的输入中断。STM32F103供给IO口使用的中断线只有16个,但是 STM32F103IO口 却远远不止16 个,所以STM32GPIO管脚GPIOx.0~GPIOx.15(x=A,B,C,D,E,F,G)分别对应中断线0~15

这样子每个中断线对应了最多9个IO口,以线0为例:它对应了GPIOA0GPIOB0GPIOC0GPIOD0GPIOE0GPIOF0GPIOG0。而中断线每次只能连接到1个IO口上, 这样就需要通过配置决定对应的中断线配置到哪个GPIO上了。

GPIO和中断线映射关系是在寄存器AFIO_EXTICR1 ~ AFIO_EXTICR4中配置的。

1.1.2 框图

其中按照控制功能划分,共分为4个部分,有两条主线:

  • 一条是由输入线到NVIC中断控制器;
  • 一条是由输入线到脉冲发生器。

其中:

  • 输入线:是线路的信息输入端,它可以通过配置寄存器设置为任何一个GPIO口,或者是一些外设的事件。输入线一般都是存在电平变化的信号;
  • 边沿检测电路(标号1):上升沿触发选择寄存器和下降沿触发选择寄存器。边沿检测电路以输入线作为信号输入端,如果检测到有边沿跳变就输出有效信号1,就输出有效信号1到标号2部分电路,否则输入无效信号0。边沿跳变的标准在于对两个触发选择寄存器的设置;
  • 或门电路(标号2):它的两个信号输入端分别是软件中断事件寄存器和边沿检测电路的输入信号。或门电路只要输入端有信号1,就会输出1,所以就会输出信号1到标号3电路和标号4电路;
  • 与门电路(标号3):两个信号输入端分别是中断屏蔽寄存器和标号2电路信号;-
    • 如果中断屏蔽寄存器设置为0时,不管从标号2电路输出的信号特性如何,最终标号3电路输出的信号都是0;
    • 如果中断屏蔽寄存器设置为1时,最终标号3电路输出的信号才由标号2电路输出信号决定;
  • 与门电路(标号4):输入端来自标号2电路以及来自于事件屏蔽寄存器。可以简单的控制事件屏蔽寄存器来实现是否产生事件的目的。标号4电路输出有效信号1就会使脉冲发生器电路产生一个脉冲,而无效信号就不会使其产生脉冲信号。脉冲信号产生可以给其他外设电路使用,例如定时器,模拟数字转换器等,这样的脉冲信号一般用来触发TIM或者ADC开始转换。
1.2 功能说明
1.2.1 硬件中断选择

要产生中断,必须先配置好并使能中断线;

  • 根据需要的边沿检测设置2个触发寄存器(EXTI_RTSREXTI_FTSR),同时在中断屏蔽寄存器(EXTI_IMR)的相应位写1允许中断请求;
  • 配置对应到外部中断控制器(EXTI)的NVIC中断通道的使能和屏蔽位,使得20个中断线中的请求可以被正确地响应;
  • 当外部中断线上发生了期待的边沿时,将产生一个中断请求,对应的挂起位(EXTI_PR)也随之被置1;
  • 在挂起寄存器(EXTI_PR)的对应位写1,将清除该中断请求。
1.2.2 硬件事件选择

如果需要产生事件,必须先配置好并使能事件线;

  • 根据需要的边沿检测通过设置2个触发寄存器(EXTI_RTSREXTI_FTSR),同时在事件屏蔽寄存器(EXTI_EMR)的相应位写1允许事件请求;

  • 当事件线上发生了需要的边沿时,将产生一个事件请求脉冲,对应的挂起位(EXTI_PR)不被置1。

1.2.3 软件中断/事件的选择

通过在软件中断/事件寄存器写1,也可以通过软件产生中断/事件请求;

  • 配置20个中断/事件线屏蔽位(EXTI_IMREXTI_EMR);
  • 设置软件中断寄存器的请求位(EXTI_SWIER)。

二、EXTI相关寄存器

在前面的介绍中,所涉及的寄存器共有7个:

  • 上升沿触发选择寄存器(EXTI_RTSR);
  • 下降沿触发选择寄存器(EXTI_FTSR);
  • 挂起寄存器(EXTI_PR);
  • 软件中断事件寄存器(EXTI_SWIER);
  • 中断屏蔽寄存器(EXTI_IMR);
  • 事件屏蔽寄存器(EXTI_EMR);
  • 外部中断配置寄存器 (AFIO_EXTICRx)。
2.1 上升沿触发选择寄存器(EXTI_RTSR)

该寄存器主要用于控制输入线进来的输入信号,上升沿时是否在边沿检测电路被检测出,20位共控制20EXTI线;

2.2 下降沿触发选择寄存器(EXTI_FTSR)

该寄存器主要用于控制输入线进来的输入信号,下升沿时是否在边沿检测电路被检测出,20位共控制20EXTI线;

2.3 挂起寄存器(EXTI_PR)

该寄存器的作用主要有两个:

  • 检测外部中断线上是否发生了选择的边沿事件,如果发生了该位置1,并将信号传递给与门电路,进而进入NVIC中;
  • 在该位手动(软件)写入1,可以清除之前中断信号的1,主要作用是进入中断后,清除中断位,防止多次进入中断。
2.4 软件中断事件寄存器(EXTI_SWIER)
2.5 中断屏蔽寄存器(EXTI_IMR)

该寄存器的主要作用只有一个,就是是否允许来自输入线上的中断信号进入NVIC中断控制器。

2.6 事件屏蔽寄存器(EXTI_EMR)

该寄存器的主要作用只有一个,就是是否允许来自输入线线上的事件进入脉冲发生器。

2.7 外部中断配置寄存器 (AFIO_EXTICRx)

AFIO_EXTICR1寄存器配置EXTI0EXTI3线,包含的外部中断的引脚包括PAxPGxx=03

AFIO_EXTICR2寄存器配置EXTI4EXTI7线;

AFIO_EXTICR3寄存器配置EXTI8EXTI11线;

AFIO_EXTICR4寄存器配置EXTI12EXTI15线;

特别注意:配置AFIO寄存器之前需要使能AFIO的时钟。

2.7.1 AFIO_EXTICR1
2.7.2 AFIO_EXTICR2
2.7.3 AFIO_EXTICR3
2.7.4 AFIO_EXTICR4

三、外部中断源码

3.1 外部中断的初始化步骤

EXTI中断配置流程如下:

(1) GPIO口初始化;

  • 外设时钟配置:通过配置RCC_APB2ENR寄存器使能GPIO时钟;
  • GPIO配置:设置GPIO工作模式为上拉/下拉输入模式、浮空输入模式,即配置GPIOx_CRLGPIOx_CRH寄存器;

(2) EXTI外部中断配置;

  • AFIO时钟配置:通过配置RCC_APB2ENR寄存器使能AFIO时钟;
  • 设置GPIOEXTI映射关系:通过AFIO_EXTICRx寄存器配置IO对应的EXTI输入线;
  • 设置EXTI屏蔽、上升沿、下降沿:即设置EXTI_EMREXTI_RTSREXTI_FTSR寄存器;

(3) 设置NVIC;

  • 参考《STM32F103嵌套向量中断控制器》:设置中断优先级分组、设置响应优先级和抢断优先级、使能相应中断位;

(34) 中断处理函数;

  • 设置中断服务函数(包括清除中断标志)。
3.2 源码实现
3.2.1 GPIO口初始化

首先调用gpio_init函数进行GPIO初始化,具体参考《STM32F103 GPIO和串口配置》。

比如配置GPIOC5为上拉输入:

gpio_init(PC5,GPI_UP,HIGH);	             // PC5接按键KEY0
3.2.2 外部中断配置函数
typedef enum	                    //外部中断触发方式
{FALLING = 0x01,RISING  = 0x02,LEVEL   = 0x03
}TRIGGER_MODE;/********************************************************************************************************* *		   Description:外部中断配置函数*					   决定中断线配置到哪个GPIO口	  *                    AFIO->EXTICR[0~3] 每个寄存器的低16位每4位决定1路中断线  *					   0000:PAx    0001:PBx    0010:PCx0011:PDx    0100:PEx    0101:PFx*         Parameter:portx_pinx形如PA0,PA1................TRIGGER_Mode:  0x01 下降沿触发    0x02 上升沿触发0x03 任意电平触发*			Example   : Ex_NVIC_Congig(PA8,0x01);       PA8下降沿触发	*********************************************************************************************************/void Ex_NVIC_Congig(PORTx_PINx portx_pinx,TRIGGER_MODE  trigger_mode){u8 address;			        //外部中断触发寄存器编号选择u8 offset;                  //外部中断触发寄存器偏移位选择u8 portx=portx_pinx/16;     //端口号u8 pinx=portx_pinx%16;      //引脚号 address = pinx/4;offset  = (pinx%4)*4;RCC->APB2ENR |= 1<<0;                     //使能I/O复用时钟AFIO->EXTICR[address]|=portx<<offset;     //EXTI.BITx映射到GPIOx.BITx
//		EXTI->PR  |= 1<<pinx;                     //清除线x上的中断标志位 EXTI->IMR |= 1<<pinx;                     //开放来自线x上的中断请求EXTI->EMR |= 1<<pinx;                     //开放来自线x上的事件请求if(trigger_mode==0x01)EXTI->FTSR |= 1<<pinx;   			  //设置线x上下降沿触发if(trigger_mode==0x02)EXTI->RTSR |= 1<<pinx;   			  //设置线x上上降沿触发}

比如配置GPIOC5为下降沿触发:

Ex_NVIC_Congig(PC5,FALLING);             // 按键KEY0按下触发 高电平->低电平
3.2.3 NVIC中断优先级初始化

调用STM32_NVIC_Init函数初始化PC5中断优先级,具体参考《STM32F103嵌套向量中断控制器》;

GPIOC5对应的EXTI线[9:5],这里设置EXTI9_5_IRQn中断优先级分组2,抢占优先级为2,响应优先级为2;

STM32_NVIC_Init(2,EXTI9_5_IRQn,2,2);
3.2.4 中断处理函数

这里依然以EXTI9_5_IRQn中断为例,对应的中断处理函数为EXTI9_5_IRQHandler

/*********************************************************************************************************************
* Function Name  : EXTI9_5_IRQHandler
* Description    : This function handles External lines 9 to 5 interrupt request.
* Input          : None
* Output         : None
* Return         : None
*************************************************************************************************************************/
void EXTI9_5_IRQHandler(void)
{if(	EXTI->PR & 1<<5 )               //来自中断线5上的中断{//**********************自定义用户任务****************************////*****************************************************************//EXTI->PR = 1<<5;				   //清中断线5上的中断标志}   if(	EXTI->PR & 1<<6 )               //来自中断线6上的中断{//**********************自定义用户任务****************************////*****************************************************************//EXTI->PR = 1<<6;	                //清中断线6上的中断标志}if(	EXTI->PR & 1<<7 )               //来自中断线7上的中断{//**********************自定义用户任务****************************////*****************************************************************//EXTI->PR = 1<<7;	                        //清中断线7上的中断标志 }if(	EXTI->PR & 1<<8 )                  //来自中断线8上的中断{//**********************自定义用户任务****************************//usart_sendStr(USART_1, "坏人");//*****************************************************************//EXTI->PR = 1<<8;	                  //清中断线8上的中断标志 }if(	EXTI->PR & 1<<9 )                 //来自中断线9上的中断{//**********************自定义用户任务****************************////*****************************************************************//EXTI->PR = 1<<9;	                 //清中断线9上的中断标志 }
}
3.3 实现功能

这里我们就利用手头开发板的独立按键kKEY0来控制LED1灯的亮灭;

其中:

  • KEY0连接STM32f103GPIOC5,按键无上拉电阻,需要在GPIOC5上设为上拉状态,提供一个确定电平;
    • 按键按下时,GPIOC5输出低电平;
    • 当按键未按下时,GPIOC5应为高电平;
  • LED1连接STM32f103GPIOA8引脚,低电平点亮;

我们要实现的功能也很简单:即按下KEY0点亮LED1,源码实现包括以下两个步骤;

  • 配置GPIOA8通用推挽输出,最大速度50MHz
  • 配置GPIOC对应的EXTI线[9:5]外部中断,下降沿触发;
3.3.1 main函数实现
int main()
{ u32 i=0;STM32_Clock_Init(9);         	          //系统时钟初始化                         	while(RTC_Init());                       //RTC初始化 STM32_NVIC_Init(2,USART1_IRQn,0,1);		  //串口中断优先级初始化,其中包括中断使能usart_init(USART_1,115200);				  //串口1初始化,波特率115200 映射到PA9 PA10// LED1初始化gpio_init(PA8,GPO_SpeedMax_50,HIGH);              //PA8接入LED1  // 按键KEY0初始化  gpio_init(PC5,GPI_UP,HIGH);	             //PC5接按键KEY0Ex_NVIC_Congig(PC5,FALLING);                //按键KEY0按下触发 高电平->低电平STM32_NVIC_Init(2,EXTI9_5_IRQn,2,2);	     //EXTI线[9:5]中断优先级初始化,其中包括中断使能while(1){	    delay_ms(100);PAout(8) = 1;   // 熄灭LED1}		 
}
3.3.2 EXTI9_5_IRQHandler函数实现
/*********************************************************************************************************************
* Function Name  : EXTI9_5_IRQHandler
* Description    : This function handles External lines 9 to 5 interrupt request.
* Input          : None
* Output         : None
* Return         : None
*************************************************************************************************************************/
void EXTI9_5_IRQHandler(void)		
{if(	EXTI->PR & 1<<5 )               //来自中断线5上的中断{//**********************自定义用户任务****************************//PAout(8) = 0;   // 点亮LED1//*****************************************************************//EXTI->PR = 1<<5;				   //清中断线5上的中断标志}   if(	EXTI->PR & 1<<6 )               //来自中断线6上的中断{//**********************自定义用户任务****************************////*****************************************************************//EXTI->PR = 1<<6;	                //清中断线6上的中断标志}if(	EXTI->PR & 1<<7 )               //来自中断线7上的中断{//**********************自定义用户任务****************************////*****************************************************************//EXTI->PR = 1<<7;	                        //清中断线7上的中断标志 }if(	EXTI->PR & 1<<8 )                  //来自中断线8上的中断{//**********************自定义用户任务****************************////*****************************************************************//EXTI->PR = 1<<8;	                  //清中断线8上的中断标志 }if(	EXTI->PR & 1<<9 )                 //来自中断线9上的中断{//**********************自定义用户任务****************************////*****************************************************************//EXTI->PR = 1<<9;	                 //清中断线9上的中断标志 }}

四、源码下载

源码下载路径:stm32f103

参考文章

[1] Mini2440裸机开发之中断控制器

[2] STM32--中断使用

[3] 《STM32F10xxx Cortex-M3编程手册》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/478604.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker run m3e 配置网络,自动重启,GPU等 配置渠道要点

启动命令&#xff1a; docker run -d --restart always -p 6008:6008 --gpus all --name m3e --network fastgpt_fastgpt stawky/m3e-large-api 配置渠道m3e base url要像我这样填写才行&#xff0c;不然回出问题 模型要选m3e 密钥填&#xff1a;sk-aaabbbcccdddeeefffggghhhi…

ubuntu24挂载硬盘记录

1、显示硬盘及所属分区情况。在终端窗口中输入如下命令&#xff1a; sudo fdisk -l 找到自己硬盘的分区 我的地址/dev/sda 2、显示硬盘及所属分区情况。在终端窗口中输入如下命令&#xff0c;格式化自己硬盘&#xff1a; sudo mkfs -t ext4 /dev/sda 3、在终端窗口中输入如下…

加菲工具 - 好用免费的在线工具集合

加菲工具 https://orcc.online AI 工具 加菲工具 集合了目前主流的&#xff0c;免费可用的ai工具 文档处理 加菲工具 pdf转word、office与pdf互转等等工具都有链接 图片图标 加菲工具 统计了好用免费的在线工具 编码解码 加菲工具 base64编码解码、url编码解码、md5计算…

网络安全与加密

1.Base64简单说明描述&#xff1a;Base64可以成为密码学的基石&#xff0c;非常重要。特点&#xff1a;可以将任意的二进制数据进行Base64编码结果&#xff1a;所有的数据都能被编码为并只用65个字符就能表示的文本文件。65字符&#xff1a;A~Z a~z 0~9 / 对文件进行base64编码…

Easyexcel(6-单元格合并)

相关文章链接 Easyexcel&#xff08;1-注解使用&#xff09;Easyexcel&#xff08;2-文件读取&#xff09;Easyexcel&#xff08;3-文件导出&#xff09;Easyexcel&#xff08;4-模板文件&#xff09;Easyexcel&#xff08;5-自定义列宽&#xff09;Easyexcel&#xff08;6-单…

三种蓝牙架构实现方案

一、蓝牙架构方案 1、hostcontroller双芯片标准架构 手机里面包含很多SoC或者模块&#xff0c;每颗SoC或者模块都有自己独有的功能&#xff0c;比如手机应用跑在AP芯片上&#xff0c;显示屏&#xff0c;3G/4G通信&#xff0c;WiFi/蓝牙等都有自己专门的SoC或者模块&#xff0…

docker 容器运行Ruoyi-cloud

目录 1&#xff0c;linux系统安装openjdk1.8,mvn,dokcer,node,git 2&#xff0c;拉取代码 1&#xff09;查看gitee仓库地址 2&#xff09;创建/app文件夹&#xff0c;进入app目录 3&#xff09;clone代码 4&#xff09;修改配置文件中nacos地址 3&#xff0c;构建项目 1&…

QT简易项目 数据库可视化界面 数据库编程SQLITE QT5.12.3环境 C++实现

案例需求&#xff1a; 完成数据库插入&#xff0c;删除&#xff0c;修改&#xff0c;查看操作。 分为 插入&#xff0c;删除&#xff0c;修改&#xff0c;查看&#xff0c;查询 几个模块。 代码&#xff1a; widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget…

刷题——字符串中的单词数(力扣)

文章目录 一、读题二、思路问题1&#xff1a;解决思路&#xff1a;分割方法&#xff1a;方法1、方法2、 三、代码实现&#xff1a;方法1、方法2、 一、读题 题目来源&#xff1a;https://leetcode.cn/problems/number-of-segments-in-a-string/description/ 首先看例子&#xf…

【人工智能】PyTorch、TensorFlow 和 Keras 全面解析与对比:深度学习框架的终极指南

文章目录 PyTorch 全面解析2.1 PyTorch 的发展历程2.2 PyTorch 的核心特点2.3 PyTorch 的应用场景 TensorFlow 全面解析3.1 TensorFlow 的发展历程3.2 TensorFlow 的核心特点3.3 TensorFlow 的应用场景 Keras 全面解析4.1 Keras 的发展历程4.2 Keras 的核心特点4.3 Keras 的应用…

什么是 WPF 中的依赖属性?有什么作用?

依赖属性&#xff08;Dependency Property&#xff09;是 WPF 的一个核心概念&#xff0c;它为传统的 .NET 属性提供了增强功能&#xff0c;支持绑定、样式、动画和默认值等功能。通过依赖属性&#xff0c;WPF 提供了一种灵活的数据驱动的方式来处理 UI 属性。 1. 什么是依赖属…

在win10环境部署opengauss数据库(包含各种可能遇到的问题解决)

适用于windows环境下通过docker desktop实现opengauss部署&#xff0c;请审题。 文章目录 前言一、部署适合deskdocker的环境二、安装opengauss数据库1.配置docker镜像源2.拉取镜像源 总结 前言 注意事项&#xff1a;后面docker拉取镜像源最好电脑有科学上网工具如果没有科学上…

2024年11月25日Github流行趋势

项目名称&#xff1a;flux 项目维护者&#xff1a;timudk jenuk apolinario zeke thibautRe项目介绍&#xff1a;FLUX.1模型的官方推理仓库。项目star数&#xff1a;17,381项目fork数&#xff1a;1,229 项目名称&#xff1a;screenshot-to-code 项目维护者&#xff1a;abi cle…

Python 爬虫从入门到(不)入狱学习笔记

爬虫的流程&#xff1a;从入门到入狱 1 获取网页内容1.1 发送 HTTP 请求1.2 Python 的 Requests 库1.2 实战&#xff1a;豆瓣电影 scrape_douban.py 2 解析网页内容2.1 HTML 网页结构2.2 Python 的 Beautiful Soup 库 3 存储或分析数据&#xff08;略&#xff09; 一般爬虫的基…

Linux麦克风录音实战

在 Linux 上使用麦克风进行录音可以通过多种方式实现&#xff0c;包括使用命令行工具、图形界面应用程序以及编程接口。下面我将介绍几种常见的方法&#xff0c;从简单的命令行工具到使用 PortAudio 库进行编程。 一. 使用arecord命令行工具 arecord 是 ALSA&#xff08;Adva…

oracle会话追踪

一 跟踪当前会话 1.1 查看当前会话的SID,SERIAL# #在当前会话里执行 示例&#xff1a; SQL> select distinct userenv(sid) from v$mystat; USERENV(SID) -------------- 1945 SQL> select distinct sid,serial# from v$session where sid1945; SID SERIAL# …

ThingsBoard规则链节点:Azure IoT Hub 节点详解

目录 引言 1. Azure IoT Hub 节点简介 2. 节点配置 2.1 基本配置示例 3. 使用场景 3.1 数据传输 3.2 数据分析 3.3 设备管理 4. 实际项目中的应用 4.1 项目背景 4.2 项目需求 4.3 实现步骤 5. 总结 引言 ThingsBoard 是一个开源的物联网平台&#xff0c;提供了设备…

数据结构(Java版)第二期:包装类和泛型

目录 一、包装类 1.1. 基本类型和对应的包装类 1.2. 装箱和拆箱 1.3. 自动装箱和自动拆箱 二、泛型的概念 三、引出泛型 3.1. 语法规则 3.2. 泛型的优点 四、类型擦除 4.1. 擦除的机制 五、泛型的上界 5.1. 泛型的上界的定义 5.2. 语法规则 六、泛型方法 6.1…

STM32端口模拟编码器输入

文章目录 前言一、正交编码器是什么&#xff1f;二、使用步骤2.1开启时钟2.2配置编码器引脚 TIM3 CH1(PA6) CH2 (PA7)上拉输入2.3.初始化编码器时基2.4 初始化编码器输入2.5 配置编码器接口2.6 开启定时器2.7获取编码器数据 三、参考程序四、测试结果4.1测试方法4.2串口输出结果…

商业物联网:拥抱生产力的未来

在现代商业格局中&#xff0c;数据占据至高无上的地位。物联网&#xff08;IoT&#xff09;站在这场数字革命的前沿&#xff0c;将以往模糊不清的不确定因素转变为可衡量、可付诸行动的深刻见解。物联网技术为日常物品配备传感器与连接功能&#xff0c;使其能够实时收集并传输数…