STM32 外部中断 EXTI的理解心得

一.前言

我个人学习嵌入式很长时间了

一直不得要领,往往一个头两个大

对知识不进脑子的迷茫感

看见专用名词无从下手的恐惧感

CV后,依然不见效果的绝望感

在大量时间的冲刷下终于有一丝感想,希望能够帮助到大家

读懂原理图,读懂数据手册,熟悉协议内容

多实践,多思考,多笔记

纸上得来终觉浅,绝知此事要躬行。

二.相关概念

2.1EXTI 外部中断

EXTI的本质是检测指定的GPIO电平信号,当GPIO的电平信号发生变化,EXTI向NVIC发出中断申请,NVIC经过裁决,中断CPU程序,实行EXTI对应的中断程序

中断响应:电平信号变化后,触发中断,通向CPU,CPU中断当前程序,进入中断服务函数。

事件响应:电平信号变化后,不触发中断,不通向CPU,通向其他外设。

2.2EXTI基本结构

每个GPIO口通过AFIO中断引脚选择,每组只有一个口接入EXTI上

PVD,RTC,USB,ETH"蹭网"

每个EXTI通道输入到NVIC中

NVIC经过裁决,通向CPU

CPU进入对应的中断服务函数

2.2.1AFIO内部结构图

PA0——PG0通过选择器,最终只有一个口,能够连接到EXIT0上(其他以此类推)

2.2.2EXTI内部结构图

输入线就是经过AFIO选择的16根线+4根“蹭网”线

软件配置好 上升沿,下降沿,双边沿 检测,经过边沿检测电路到一路或门

软件配置好是否有软件触发中断,输出到另一路或门

边沿支路与软件支路经过或门,分两路输出

下路为事件响应,与事件屏蔽寄存器经过与门到其他外设,事件屏蔽寄存器相当于开关。

上路为中断响应,触发中断置挂起寄存器,相当于一个标志位,读取这个寄存器,就是到是哪个通道触发的中断,与中断屏蔽寄存器经过与门到达NVIC控制器

最终进行中断优先级的配置

 2.3 NVIC

NVIC实际上是中断管理机制,用来对中断优先级进行分配

多种中断源可供选择,EXTIx,ADC,USART等

n 表示有很多条线

优先级共分为16个等级,数字越小,优先级越高

将各种中断源裁决后,交给CPU,CPU中断当前程序,随后进入中断程序

2.3.1 NVIC的中优先级分组

三.例程

这是对射式红外传感器的代码

#include "stm32f10x.h"                  // Device header

uint16_t CountSensor_Count;

void CountSensor_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);
	
	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_InitStructure.EXTI_Line = EXTI_Line14;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_Init(&EXTI_InitStructure);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
}

uint16_t CountSensor_Get(void)
{
	return CountSensor_Count;
}

void EXTI15_10_IRQHandler(void)
{
	if (EXTI_GetITStatus(EXTI_Line14) == SET)
	{
		
		if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0)
		{
			CountSensor_Count ++;
		}
		EXTI_ClearITPendingBit(EXTI_Line14);
	}
}

下面大概解释一下代码内容,这个模块的中文解释,显示字符很不清晰

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure); 
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);

选择PB14检测波形,上拉输入

GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);

将PB14连接到EXTI14

    EXTI_InitTypeDef EXTI_InitStructure;
    EXTI_InitStructure.EXTI_Line = EXTI_Line14;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_Init(&EXTI_InitStructure);

配置EXTI结构体,设置为EXTI14通道并使能,选择中断响应,下降沿触发

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_Init(&NVIC_InitStructure);

NVIC分组设置为抢占优先级为2,响应优先级为2

选择EXTI15_10通道并且使能,配置抢占优先级为1,响应优先级为1

四.结尾

本篇文章并没有软件触发中断的部分,后面会补上。

希望对大家能有所帮助

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值