stm32学习笔记——外部中断的使用

 stm32学习笔记——外部中断的使用

基本概念

  stm32中,每一个GPIO都可以触发一个外部中断,但是,GPIO的中断是以组为一个单位的,同组间的外部中断同一时间只能使用一个。比如说,PA0,PB0,PC0,PD0,PE0,PF0,PG0这些为1组,如果我们使用PA0作为外部中断源,那么别的就不能再使用了。在此情况下,我们只能使用类似于PB1,PC2这种末端序号不同的外部中断源。每一组使用一个中断标志EXTIx。EXTI0-EXTI4这5个外部中断有着自己单独的中断响应函数,EXIT5-EXIT9共用一个中断响应函数,EXIT10-EXIT15共用一个中断响应函数。

  对于中断的控制,stm32有一个专用的管理机构:NVIC。对于NVIC的详细解释,可以参考《ARM Cortex-M3权威指南》,Joseph Yiu著,宋岩译,北京航空航天大学出版社出版,第8章NVIC与中断控制。中断的使能,挂起,优先级,活动等等都是NVIC在管理。

 

基本步骤

  使用外部中断的基本步骤如下:

  1、设置好相应的时钟;

  2、IO口初始化

  3、中断NVIC配置

  4、将GPIO管脚与外部中断线连接

  5、在选择的中断通道的响应函数中写中断服务程序

  这里举个简单的例子,使用按键来触发中断,中断发生时,点亮一个led灯。

  按键连接的GPIO为PA11,led连接的GPIO为PB5;

 

  1、设置好相应的时钟

  首先需要打开GPIOA和GPIOB的时钟,因为要使用中断,还需要打开AFIO时钟。详细代码如下:

1 void RCC_Config(void)
2 {
3     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);//GPIOA,GPIOBʱÖÓ
4     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//外部中断,需要使用AFIO时钟
5     
6 }
View Code

 

  2、IO口初始化

 1 void GPIO_Config(void)
 2 {
 3         GPIO_InitTypeDef GPIO_InitStructure;
 4         //配置PA11为输入模式
 5         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
 6         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
 7         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 8         GPIO_Init(GPIOA, &GPIO_InitStructure);
 9         //配置PB5为输出模式
10         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
11         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
12         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO口速率为50MHz
13         GPIO_Init(GPIOB, &GPIO_InitStructure);//根据设定参数初始化GPIOB5
14     
15 }
View Code

 

  3、中断NVIC配置

  设置相应的中断实际上就是设置NVIC,在stm32的固件库中有一个结构体NVIC_InitTypeDef,里面有相应的标志位设置,然后再用NVIC_Init()函数进行初始化。详细代码如下:

 1 void NVIC_Config(void)
 2 {
 3     NVIC_InitTypeDef NVIC_InitStructure;
 4     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置NVIC中断分组2:2位抢占优先级,2位响应优先级
 5     NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;//选择中断通道11
 6     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级2
 7     NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;//响应优先级2
 8     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能中断
 9     NVIC_Init(&NVIC_InitStructure);//完成初始化
10 }
View Code

 

  4、将GPIO管脚与外部中断线连接

  由于GPIO并不是专用的中断引脚,因此在用GPIO来触发外部中断的时候需要设置将GPIO相应的引脚和中断线连接起来,具体代码如下:

 1 void EXIT_Config(void)
 2 {
 3     EXTI_InitTypeDef EXTI_InitStructure;
 4     //清空中断标志
 5     EXTI_ClearITPendingBit(EXTI_Line11);
 6     //连接中断管脚PA11
 7     GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource11);
 8     
 9     EXTI_InitStructure.EXTI_Line = EXTI_Line11;//选择中断线路11
10     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//设置为中断请求,非事件请求
11     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//设置中断触发方式为下降沿触发
12     EXTI_InitStructure.EXTI_LineCmd = ENABLE;//外部中断使能
13     EXTI_Init(&EXTI_InitStructure);
14 }
View Code

 

  5、在选择的中断通道的响应函数中写中断服务程序

  stm32不像C51单片机那样,可以通过interrupt关键字来定义中断响应函数,stm32的中断响应函数接口存在于中断向量表中,是由启动代码给出的。默认的中断响应函数在stm32f10x_it.c中。但也可以在自己建立的c文件中书写对应的中断响应函数,但要保证,其名称要和stm32f10x_it.c中的一致。我们使用的中断服务函数名称为:

void EXTI15_10_IRQHandler(void);我们的目标是将led灯点亮,所以函数体很简单:

1 void EXTI15_10_IRQHandler(void)
2 {
3         //点亮led灯,低电平有效
4     GPIO_ResetBits(GPIOB,GPIO_Pin_5);    
5     //清空中断标志位,防止持续进入中断
6     EXTI_ClearITPendingBit(EXTI_Line11); 
7 }
View Code

 

  最后写主函数:

1 #include "stm32f10x_lib.h"
2 int main(void)
3 {
4     RCC_Config();
5     GPIO_Config();
6     NVIC_Config();
7     EXIT_Config();
8     while(1);
9 }
View Code

 

### STM32学习资源推荐 对于希望深入学习STM32微控制器的开发者来说,获取高质量的学习资料至关重要。以下是几个方向可以帮助找到适合的学习材料: #### 官方文档 STMicroelectronics 提供了详尽的技术手册和数据表,这些官方文档涵盖了从基础到高级的各种主题[^1]。通过访问 ST 的官方网站,可以下载最新的芯片规格书、应用笔记以及固件库。 #### 社区分享与博客文章 网络上存在大量由经验丰富的工程师撰写的STM32学习笔记,例如提到的“Stm32学习笔记,3万字超详细”的内容就非常有价值。这类笔记通常会结合实际项目经历来解释复杂的概念,并提供实用的操作指南。此外,“【笔记】STM32篇”这样的记录也强调了实践的重要性——鼓励读者亲自尝试编码过程以加深理解[^2]。 #### 开发环境搭建指导 为了顺利开展基于STM32项目的开发工作,熟悉如何配置IDE(如Keil MDK或者STM32CubeIDE),安装必要的驱动程序也是必不可少的一环。许多在线教程都会详细介绍这一流程并附带截图说明以便于新手快速上手。 #### 中断处理函数解析 针对具体功能模块比如外部中断线(EXTI),需要注意不同版本API可能存在的细微差异。虽然有说法指出`EXTI_ClearFlag` 和 `EXTI_ClearITPendingBit` 在某些实现里表现一致但实际上它们各自承担着不同的职责,在特定场景下选用合适的清除方法能够提高系统的稳定性和效率。 ```c // 示例代码展示如何正确使用上述两个宏定义 void EXTI0_IRQHandler(void){ if(__HAL_GPIO_EXTI_GET_FLAG(GPIO_PIN_0)!=RESET){ __HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_0); // 使用此方式清标志位更直观些 /* Add your application code here */ } } ``` #### PDF资源整合建议 如果偏好纸质阅读体验,则可以通过搜索引擎查找关键词组合:“stm32 学习 教程 pdf”,这样往往能找到一些整理成册的手册文件可供离线查看。不过要注意甄别来源可靠性以免误信过期信息。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值