问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

STM32中断机制详解:从轮询到外部中断的实现

创作时间:
作者:
@小白创作中心

STM32中断机制详解:从轮询到外部中断的实现

引用
CSDN
1.
https://blog.csdn.net/hmh520i/article/details/138131974

一、什么是中断?

轮询机制

轮询机制顾名思义,就是每轮都询问一次。比如while循环的每一次,就会执行检查:

  1. 串口是否有数据到来
  2. 引脚状态是否为低电平

本质是while循环每一次都把数据获取的函数或者寄存器执行一次,看看数据是否发生变化。

中断机制

中断也是一种对于数据获取的调度方式。通过中断源来提醒CPU,数据已经更新,可以读取新数据。

从上图可以观察到NVIC有一部分是接到了EXTI的器件,EXTI,中文名称外部中断/事件控制器。这个器件有16根线路连接到了不同的引脚上,比如PA0、PA1等等。我们板子所有的GPIO引脚都连接着各自相应的外部中断控制器。

二、什么是外部中断

凡是要经过EXTI到达NVIC的中断,都叫做“外部中断”。内部中断不经过EXTI。

外部中断与内部中断路线示意如下:

  • 紫色线路为轮询机制
  • 黑色线路部分为内部中断
  • 红色线路部分为外部中断

思考:为什么要EXTI这个结构。引脚线路为什么不直接见到NVIC上去
原因1:因为NVIC处理的是中断信号,不是电平信号。USART、TIM、IIC这些芯片内部器件本身就可以产生中断信号,因此就可以直接与NVIC连接。但是,光秃秃的GPIO本身就是一根电线,肯定不具备产生中断信号的功能。因此连接EXTI,依靠EXTI产生中断信号。
原因2:中断通达数量比较少,EXTI的多路复选的功能扩充了接口。一个EXTI可以接16个GPIO引脚呢。

三、外部中断的使用

3.1 它是什么样子

着重注意:EXTI0的16根引脚接的是GPIO所有组的第0个成员。EXTI1管着所有GPIO组的第1个成员……EXTI16管着所有GPIO组的第16个成员。

因此:我们希望红外传感器(我接在PF13上)对人的感知,采用中断形式上报。过程如下:
红外传感器数据传输到引脚PF13。所以,该引脚硬件连接在EXTI13上。EXTI13发送数据到NVIC上,core内核调用相应中断服务函数。

3.2 外部中断如何使用

3.2.1 任务分配

3.2.2 任务分配 pir 代码检查

void pir_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
    GPIO_Init(GPIOF, &GPIO_InitStructure);
}

void pir_run()
{
    if(PFin(13) == 1)
    {
        printf("有人靠近\n");
    }
    else
    {
        printf("周边没人\n");
    }
}

3.2.3 确认引脚

从代码去人引脚PF13,GPIO的F组的第13个成员。
组号:GPIOF
成员号:GPIO_Pin_13

3.2.4 工程添加文件

点击位置

3.2.5 代码编写流程图

3.2.5.1 连接 PF13 与 EXTI13

函数解释:告诉程序你要用哪一个EXTI,并用哪一根引脚。
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOx, EXTI_PinSourcex)
参数1:EXTI_PortSourceGPIOx,第几组。
参数2:EXTI_PinSourcex,第几根。

3.2.5.2 EXTI 参数配置

函数解释:告诉程序让哪一个EXTI以什么形式工作。
EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
结构体名字.EXTI_Line =到底是哪一个
EXTI.EXTI_Line2/EXTI_Line3;
结构体名字.EXTI_LineCmd =是否开始工作。
结构体名字.EXTI_Mode =检测中断呢还是事件;
结构体名字.EXTI_Trigger =何种电平信号为依据;

3.2.5.3 优先级分组

NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
函数解释:对于四个比特位进行划分为两个数据段。不同的划分行为影响流程图第四步的优先级配置。
参数1:NVIC_PriorityGroup,这里模仿了IP地址子网划分的思想,进行分组。
NVIC_PriorityGroup_0\NVIC_PriorityGroup_1\NVIC_PriorityGroup_2\NVIC_PriorityGroup_3\NVIC_PriorityGroup_4

3.2.5.4 NVIC 参数配置

NVIC_Init(&NVIC_InitStruct);
函数解释:告诉NVIC检测拿一根电线(中断通道),以什么样子的“优先级
别”来处理
参数1:第几根中断通道,以第几组优先级别(抢占优先级),第几成员优先级
别(响应优先级)来处理,

NVIC_InitStruct.NVIC_IRQChannel = 中断通道;
NVIC_InitStruct.NVIC_IRQChannelCmd = 开始工作;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority =抢占优先
级;
NVIC_InitStruct.NVIC_IRQChannelSubPriority =相应优先级

3.2.5.4 中断服务函数

void EXTI15_10_IRQHandler()
{
}
函数解释:中断出发后会调用这个函数。其中内容标准写法如下。

  1. 查看标记位,确认中断。
  2. 执行想要执行的内容。
  3. 清楚标记位,并退出。

3.2.6 代码验证和代码整理

void pir_interrupt_init()
{
    //exti13与F13连接
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOF,EXTI_PinSource13
    );
    //配置EXTI
    EXTI_InitTypeDef EXTI_InitStruct;
    EXTI_InitStruct.EXTI_Line = EXTI_Line13;
    EXTI_InitStruct.EXTI_LineCmd = ENABLE;
    EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
    EXTI_Init(&EXTI_InitStruct);
    //分组模式
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    NVIC_InitTypeDef NVIC_InitStruct;
    NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority =2;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority =2;
    NVIC_Init(&NVIC_InitStruct);
}

中断服务函数展示如下:

static uint32_t i = 0;
void EXTI15_10_IRQHandler()
{
    if(EXTI_GetITStatus(EXTI_Line13) != RESET)//确认中断事件
    {
        i++;
        if(i%2 == 0)
        {
            printf("有人靠近\n");
        }
        else
        {
            printf("有人离开\n");
        }
        EXTI_ClearITPendingBit(EXTI_Line13);//清除挂起中断标志位
    }
}

四、总结原理深化

中断根据中断信号来源不同,分为内部中断和外部中断。
外部中断:中断信号来自“EXTI”,信号经过EXTI的,都是外部中断。否则都是内部中断。
常见的外部中断:KEY开关,触发类的传感器(PIR),警报设备和诱捕设备。
内部中断:不经过EXTI的就是内部中断,常见的内部中断有,定时器TIM,串口USART,主要是通信类的接口。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号