打印
[STM32F1]

STM32F103ZET6+EXTI中断处理

[复制链接]
747|23
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
STM32F103ZET6+EXTI中断处理
一、 中断的相关概念
计算机在执行程序过程中(这里主要指单片机执行主程序),当出现异常情况(断电等)或特殊请求(数据传输等)时,计算机暂时停现行程序的运行,转向对这些异常情况或特殊请求的处理,调用相应的中断处理程序处理该事件),处理完毕后再返回到现行程序的中断处继续执行原程序,这就是中断

能够打断当前正常执行流程的事件有两种,一种是中断,一般由外部事件触发,一种是异常,由CPU内部事件产生。中断和异常其本质都是对主程序的中断,中断其实是异常的一种形式

使用特权

评论回复
评论
一点点0321 2023-1-18 16:30 回复TA
———————————————— 版权声明:本文为CSDN博主「辰小夏」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_52411606/article/details/122711046 
一点点0321 2023-1-18 16:20 回复TA
———————————————— 版权声明:本文为CSDN博主「辰小夏」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_52411606/article/details/122711046 
沙发
一点点0321|  楼主 | 2023-1-18 16:26 | 只看该作者
中断处理流程
一个完整的中断处理过程分为4个步骤:中断请求、中断响应、中断服务和中断返回

使用特权

评论回复
板凳
一点点0321|  楼主 | 2023-1-18 16:27 | 只看该作者
中断请求
中断请求是中断源向CPU发出的中断请求信号,此时中断控制系统的中断请求寄存器被置位,向CPU请求中断

使用特权

评论回复
地板
一点点0321|  楼主 | 2023-1-18 16:28 | 只看该作者
中断响应
中断响应是指CPU的中断系统判断中断源的中断请求是否符合中断响应条件,若符合条件,则暂时中断当前程序并控制程序跳转到中断服务程序,完成相应的中断服务操作。
CPU响应中断一般需要满足以下条件
(1)中断源发出中断请求
(2)系统允许中断提出中断请求,即中断没有被屏蔽
(3)无同级或更高级的中断正在被处理
CPU根据中断类型号进行中断优先级的判断,若无更高优先级的中断请求,则保护断点和现场,根据中断类型获得中断服务程序入口地址,转入相应的中断服务程序。
保护现场主要是只保护当前程序的断点和保存当前通用寄存器、状态寄存器的内容,即将这些寄存器的内容压入堆栈。这部分底层操作已经有硬件自动实现,不需要开发人员进行处理

使用特权

评论回复
5
一点点0321|  楼主 | 2023-1-18 16:33 | 只看该作者
中断服务
为处理中断而编写的程序称为中断服务程序,中断类型不同,其中断服务也不同。中断服务程序的入口地址称为中断向量,将所有中断的中断服务程序的入口地址汇成一张表,称为中断向量表

使用特权

评论回复
6
一点点0321|  楼主 | 2023-1-18 16:36 | 只看该作者
中断返回
中断返回是指CPU退出中断服务,返回到中断请求响应前中止的位置继续执行主程序。中断服务程序的最后一条指令通常是一条中断返回指令,使其返回到原来程序的断点处,以便继续执行原来的程序。若在中断处理过程中,又产生了一个优先级更高的中断。则CPU会暂停当前的中断服务,将断点和相关的寄存器入栈后,转而去处理优先级更高的中断,在中断服务完成后,需要将中断的现场(即断点)进行恢复,将压入堆栈的寄存器内容送回到原来的寄存器中(即出栈)。这部分操作同样由硬件来实现,不需要开发人员进行处理

使用特权

评论回复
7
一点点0321|  楼主 | 2023-1-18 16:37 | 只看该作者

使用特权

评论回复
8
一点点0321|  楼主 | 2023-1-18 16:49 | 只看该作者
STM32中断优先级
STM32通过Cortex-M3内核集成的NVIC实现中断优先级管理。理论上,除3个固定的高优先级(Reset、NMI、硬件失效)不可编程外,Cortex-M3支持256级中断,其优先级都是可以设置的

NVIC中断配置的相关函数存放在标准外设库misc.c文件和misc.h文件中,共定义了5个相关函数及NVIC初始化结构体

使用特权

评论回复
9
一点点0321|  楼主 | 2023-1-18 22:54 | 只看该作者
中断分组管理函数void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)用于设置中断的优先级分组,此函数只有一个参数NVIC_PriorityGroup,从源代码中可以看到其取值共有5组,每组的抢占优先级和响应优先级所占位数均不同,且取值范围也有不同,故每组可供设置优先级的数值不一样

使用特权

评论回复
10
一点点0321|  楼主 | 2023-1-18 22:57 | 只看该作者
通过函数void NVIC_PriorityGroupConfig()设置中断分组,对于具体的中断,其抢占优先级和响应优先级设置是通过中断初始化函数void NVIC_Init(NVIC_InitTypeDef *NVIC_InitStruct)实现的,其中NVIC_InitTypeDef是结构体,参数NVIC_InitStruct是指向NVIC_InitTypeDef结构体的指针

使用特权

评论回复
11
一点点0321|  楼主 | 2023-1-18 22:59 | 只看该作者

使用特权

评论回复
12
一点点0321|  楼主 | 2023-1-18 23:02 | 只看该作者
(1)NVIC_IRQChannel:用于指定某个具体的IRQ通道,即具体是哪个中断,在标准外设库stm32f10x.h文件中包含了所有中断所对应的名称

(2)NVIC_IRQChannelPreemptionPriority:用于设置NVIC_IRQChannel的抢占优先级

(3)NVIC_IRQChannelSubPriority:用于设置NVIC_IRQChannel的响应优先级

(4)NVIC_IRQChannelCmd:用于IRQ通道使能或失能,取值为ENABLE或者DISABLE

使用特权

评论回复
13
一点点0321|  楼主 | 2023-1-18 23:03 | 只看该作者
以上通过两个函数确定了具体中断的抢占优先级和响应优先级。若系统中存在多个中断,则一般遵循以下原则判断中断优先级。
(1)高抢先优先级的中断可以打断低抢先优先级的中断服务,构成中断嵌套。
(2)中断优先级的数值越小,优先级级别越高。
(3)抢占优先级的优先级总是高于响应优先级。
(4)中断优先级判断:先判断抢占优先级的大小;若抢占优先级相同,则比较响应优先级的大小;若抢占优先级和响应优先级均相同,则根据中断向量表中的顺序来决定。
(5)Reset NMI Hard Fault的优先级为负,且不可修改,高于其他普通的中断优先级。

使用特权

评论回复
14
一点点0321|  楼主 | 2023-1-18 23:08 | 只看该作者
STM32外部中断EXTI
1、 GPIO初始化
GPIO初始化配置的相关代码

使用特权

评论回复
15
一点点0321|  楼主 | 2023-1-18 23:08 | 只看该作者
开启I/O端口的时钟和复用时钟
GPIO不仅可以作为通用的输入/输出引脚,还可以用作片上外设(如USART、ADC等)的输入/输出引脚,称为复用I/O端口,当GPIO用作复用引脚时,必须开启AFIO时钟。这里I/O端口不是作为GPIO来使用的,而是用作EXTI外部中断功能引脚,所以必须开启复用功能,通过调用RCC_APB2PeriphClockCmd()函数打开相应引脚的AFIO时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_AFIO,ENABLE);

使用特权

评论回复
16
一点点0321|  楼主 | 2023-1-18 23:10 | 只看该作者
3、 设置I/O引脚与中断线路的映射关系
当GPIO引脚作为中断功能引脚用来触发外部中断时,需将GPIO引脚与相应的中断线关联在一起,使用库函数GPIO_EXTILineConfig来实现这种映射关系。如将PE3引脚与外部中断EXTI3_IRQn关联在一起

GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);

使用特权

评论回复
17
一点点0321|  楼主 | 2023-1-18 23:12 | 只看该作者
4、 初始化EXTI,配置EXTI相关参数并使能
如选择具体的中断引脚、中断线路、触发模式等,实例代码如下:

使用特权

评论回复
18
一点点0321|  楼主 | 2023-1-18 23:14 | 只看该作者
初始化NVIC,配置NVIC参数并使能
NVIC相关的配置主要包括配置中断优先级的中断分组,确定各具体中断的抢占优先级和响应优先级的大小,选择中断通道,在stm32f10x.h文件中通过IRQn_Type中断通道结构体定义所有的中断通道,不同的引脚对应不同的终端通道,使能相应的中断

使用特权

评论回复
19
一点点0321|  楼主 | 2023-1-18 23:15 | 只看该作者
在之前的LED灯工程上,新建两个文件,一个是exti.h文件,另一个是exti.c文件

exit.h文件的代码如下:
#ifndef __EXTI_KEY_H
#define __EXTI_KEY_H

#include "stm32f10x.h"


void EXTI_init(void);

#endif

使用特权

评论回复
20
一点点0321|  楼主 | 2023-1-18 23:16 | 只看该作者
exit.c文件的代码如下:
#include "exti.h"
#include "misc.h"


void EXTI_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;       
    NVIC_InitTypeDef NVIC_InitStructure;       
       
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_AFIO,ENABLE); //开启PE3的时钟,并开启复用时钟

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;               //选择要使用的I/O引脚,此处选择PE3引脚
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   //设置引脚输入模式为浮空输入模式
    GPIO_Init(GPIOE,&GPIO_InitStructure);                   //调用初始化库函数初始化GPIO端口
      
    //初始化EXTI,外部中断
    EXTI_ClearITPendingBit(EXTI_Line3);                       //清空外部中断3中断挂起,清空中断标志
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);//将PE3用作外部中断线路
   
    EXTI_InitStructure.EXTI_Line = EXTI_Line3;                //设置外部中断线3中断
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;       //设置为中断模式
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;   //设置为下降沿触发
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;                 //使能该外部中断线
    EXTI_Init(&EXTI_InitStructure);
               
    //初始化NVIC,中断优先级
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);          //选择中断优先级分组2
    NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;         //外部中断3中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//设置抢占优先级为0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;       //设置响应优先级为1
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;          //外部中断处理函数
    NVIC_Init(&NVIC_InitStructure);                
}


//外部中断处理函数
void EXTI3_IRQHandler(void)
{
       
    if(EXTI_GetITStatus(EXTI_Line3) != RESET)
    {
        GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)((1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5))));  //PE5的电平状态翻转
        EXTI_ClearITPendingBit(EXTI_Line3);    //清除中断标志位
    }

}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

52

主题

393

帖子

0

粉丝