当前位置: 首页 > article >正文

day 6 中断

一、程序的运行方式

1.1轮询系统

在程序运行的过程中,首先对所有的硬件进行初始化,然后在主程序中写入一个死循环,需要运行的程序按照顺序进行执行,轮询系统是一种简单可靠的方式,一般适用与在只需要按照顺序执行的并且没有外部事件的影响的情况下。

程序的运行过程中出现如按键等需要外部检测的事件,轮询系统的实时响应能力变得很差

1.2前后台系统

相比于轮询系统,前后台系统增加中断的概念,如果外部事件发生,则在中断中进行处理,
主程序在轮询系统中运行,中断被称为前台,主程序中的 while(1)就称为后台。中断会终止
后台程序的运行,然后跳转到对应的中断服务函数中去处理,处理完成后,在继续执行后台
的程序。
如果使用前后台系统,会大大的提高程序的实时响应能力,避免造成外部事件的缺失。

1.3多任务系统

相比于前后台系统,多任务系统的外部事件也是在中断中进行响应,但是外部事件的处理是任务中进行处理。任务具有优先级,优先级高的任务先处理,所以程序就会被分割为一个个的任务,任务是一个独立的死循环,并且不能返回,可以由操作系统进行任务的调度,程序段的实时响应能力又得到提升。

二、外部中断的概述

2.1中断的概述

中断指的是 CPU 来处理和响应外部发生的异常,中断也就意味着打断,比如打断正在做的
事,然后去处理一个紧急的事,处理完成后在继续做刚才没做完的事。

2.2中断源分析

中断源指的是中断发生的源头,中断源在内核中已经定义好了,也称为向量表,向量表在STM32F4 中文参考手册参考。Cortex-M4 内核一共支持 256 个中断,其中有 16 个内核中断,240 个外部中断,只不过对于STM32F407 系列来说,只用到了一部分,包含了 10 个内核中断(不可屏蔽中断,无法通过软件进行控制)、82 个外部中断(可屏蔽中断,可以通过软件进行控制)。 共 92 个。

对于 STM32 的中断异常而言,分为两类:内核异常 + 外部异常,都可以参考下图进行分析

******图

2.3NVIC的概述

NVIC 指的是嵌套向量中断控制器,属于内核中的外设,作用是管理所有的中断,比如中断的使能或失能、中断的优先级.....。

不管是 Cortex A 系列还是 Cortex M 系列的内核内部均有 NVIC,通过 NVIC 来管理内核异常和外部异常。

2.3.1中断的使能与失能

NVIC 管理中断通道的打开与关闭,可以把 NVIC 理解为所有中断的开关,想要使用中断发送中断请求,就必须提前打开中断的通道。关于 NVIC 的使用都存储在一个结构体中,这个结构体和 NVIC 的函数接口都定义在 misc.c 和 misc.h 中。

2.3.2中断优先级设置

NVIC 利用 4bit 的优先级来管理所有的中断通道,STM32 中断的优先级分为两种:抢占式优先级(主优先级) + 响应式优先级(次优先级),每种都有 16 个优先级(0~15),数字越小,优先级越高。

抢占优先级(主优先级):抢占优先级高的中断可以打断抢占优先级低的中断的执行。
响应优先级(次优先级):在同时发生多个中断的情况下,响应优先级高的先执行。

抢占优先级和响应优先级的区别

(1)抢占优先级高的中断可以打断抢占优先级低的中断

(2)抢占优先级相同,响应优先级高的不可以打断响应优先级低的中断

(3)抢占优先级相同,同时发生的情况下响应优先级高的先执行

(4)抢占优先级和响应优先级一样高的中断同时发生,则按照向量表中的优先级执行

为了方便用户管理和响应中断,NVIC 提供一个函数接口可以对中断优先级进行分组

函数原型

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)

函数参数

参数一:NVIC_PriorityGroup   打算设置的 NVIC 优先级分组   一般为 NVIC_PriorityGroup_2

返回值 None

注意:设置中断优先级分组应该在主程序运行的开头部分进行,并且不能随意修改分组,否则会出现中断管理混乱,导致程序出现未知问题。  

   int main()

{

        //设置优先级分组

        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

        //对硬件进行初始化.......

}

2.4EXTI的概述

EXTI 指的是外部中断/事件控制器,一共有 23 个,每个都有一个内部的边沿检测器,可以检测上升沿或者下降沿,每根线都可以产生事件或者中断。

上升沿:指的是电平信号由低变高的那一刻
下降沿:指的是电平信号由高变低的那一刻
想要搞清楚 EXTI 的使用流程,必须要看懂 EXTI 的框图

注意:每个 GPIO 引脚都可以配置为外部中断,但是和 GPIO 相关的外部中断线一共有 16 根,
分别为 EXTI0~EXTI15。
思考:STM32F407 系列有 114 个 GPIO 口,那如何和外部中断线进行关联?通过映射的方式

********图

如果想要让外部中断线和 GPIO 口进行映射,需要使用一个函数接口 SYSCFG_EXTILineConfig()

函数原型
void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex)
函数参数
参数一:EXTI_PortSourceGPIOx 想要映射的 GPIO 端口 如 EXTI_PortSourceGPIOA
参数二:EXTI_PinSourcex 想要映射的 GPIO 引脚 如 EXTI_PinSource0

注意:因为建立映射的时候需要使用系统配置控制器(SYSCFG),所以在编写代码的时候必须打开 SYSCFG 外设的时钟,挂载在 APB2 总线下 调用 RCC_APB2PeriphClockCmd()函数

三、外部中断的代码编写

注意:所有端口都具有外部中断功能。要使用外部中断线,必须将端口配置为输入模式想要使用 EXTI 进行外部事件的检测,可以参考 stm32f4xx_exti.c 源文件中的开头注释部分     

1. 应该在工程中添加 stm32f4xx_exti.c 以及 stm43f4xx_syscfg.c 两个源文件 步骤如下

右击文件夹--add(第二个)--找到需要添加的文件--添加后运行程序即可

2. 打开 GPIO 外设时钟 + SYSCFG 外设时钟 GPIO 挂载 AHB1 总线 SYSCFG 挂载在 APB2 总线
3. 定义 GPIO 初始化结构体,结构体配置的时候需要把引脚模式配置为输入模式 + 初始化
4. 调用 SYSCFG_EXTILineConfig()函数来对外部中断线和 GPIO 引脚建立映射关系
5. 定义 EXTI 初始化结构体,需要配置外部中断线(模式、触发方式.....) + 初始化

 EXTI_Line 需要使用的外部中断线 参考 EXTI_Lines(上一张图跳转)

#include "stm32f4xx.h"  

void LED_Init(void)
{
    GPIO_InitTypeDef   GPIO_InitStructure;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
    
    GPIO_InitStructure.GPIO_Mode     = GPIO_Mode_OUT;            //输出模式
    GPIO_InitStructure.GPIO_OType    = GPIO_OType_PP;            //推挽输出
    GPIO_InitStructure.GPIO_Speed    = GPIO_Speed_100MHz;        //输出速率
    GPIO_InitStructure.GPIO_PuPd     = GPIO_PuPd_NOPULL;            //无上下拉
    GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_9;                //引脚编号
    GPIO_Init(GPIOF, &GPIO_InitStructure);
    
    GPIO_SetBits(GPIOF,GPIO_Pin_9); //默认不亮

}

//主要内容从手册里面复制的
void EXTI0_Init(void)
{
    EXTI_InitTypeDef   EXTI_InitStructure;
    GPIO_InitTypeDef   GPIO_InitStructure;
    NVIC_InitTypeDef   NVIC_InitStructure;

    /* Enable GPIOA clock  打开GPIOA外设时钟*/
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    /* Enable SYSCFG clock 打开SYSCFG外设时钟*/
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

    /* Configure PA0 pin as input floating 配置PA0引脚*/
    GPIO_InitStructure.GPIO_Mode     = GPIO_Mode_IN;                //输入模式
    GPIO_InitStructure.GPIO_PuPd     = GPIO_PuPd_NOPULL;            //无上下拉
    GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_0;                //引脚编号
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* Connect EXTI Line0 to PA0 pin GPIO引脚和外部中断线建立映射关系*/
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);

    /* Configure EXTI Line0 配置外部中断线*/
    EXTI_InitStructure.EXTI_Line     = EXTI_Line0;                //外部中断线0
    EXTI_InitStructure.EXTI_Mode     = EXTI_Mode_Interrupt;        //中断模式
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;      //下降沿触发
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;                    //使能外部中断线0
    EXTI_Init(&EXTI_InitStructure);

    /* Enable and set EXTI Line0 Interrupt 配置中断优先级*/
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;            //中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;//抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;        //响应优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                //使能通道
    NVIC_Init(&NVIC_InitStructure);    

}


int main()
{
    //1.硬件初始化
    LED_Init();
    EXTI0_Init();
    
    //2.进入死循环
    while(1)
    {
        
        
    }
}

//中断服务函数  不需要手动调用   尽量精简(尽量不要添加很长的延时)
void EXTI0_IRQHandler(void)
{
    
    //检测中断线的标志
    if( EXTI_GetITStatus(EXTI_Line0) != RESET )
    {
        GPIO_ToggleBits(GPIOF,GPIO_Pin_9); //LED电平翻转
        
        //清除中断标志位
        EXTI_ClearITPendingBit(EXTI_Line0);
    }
}
 


http://www.kler.cn/a/599469.html

相关文章:

  • 求二叉搜索树中的众数的三种方法
  • [Android] NFC卡模拟 9.05 模拟NFC门禁卡 电梯卡等 手机代替卡片
  • <项目> 高并发服务器的HTTP协议支持
  • QML指示控件:ScrollBar与ScrollIndicator
  • 复杂任务需要多agent协同处理,对其进行逻辑编排和参数调用
  • 鸿蒙特效教程10-卡片展开/收起效果
  • 数据结构篇:空间复杂度和时间复杂度
  • netplan是如何操控NetworkManager的? 笔记250324
  • 车载以太网网络测试 -23【TCPUDP通信示例】
  • 蓝桥杯——嵌入式学习日记
  • 借助AI Agent实现数据分析
  • Python虚拟环境:从入门到实战指南
  • 在 ASP.NET Core 中实现限流(Rate Limiting):保护服务免受滥用与攻击
  • ABB机器人更换机器人本体编码器电池的具体步骤
  • 蓝桥杯,冬奥大抽奖
  • 中间件解析漏洞之Tomcat集合
  • 操作系统必知的面试题
  • Maven 构建配置文件
  • 计算机操作系统(四) 操作系统的结构与系统调用
  • 盖泽 寻边器 帮助类