08:【stm32】中断二:EXTI(外部中断)

EXTI(外部中断)

1、EXTI简介

外部中断控制器,能够检测外部输入信号的变化边沿并由此产生中断。通过检测上升沿或者下降沿来产生中断源。

2、EXTI的内部结构


边沿检测检测到电平的跳变都会生成一个高脉冲信号,然后脉冲通过边沿选择传递到中断屏蔽,当中断屏蔽遇到脉冲时,打开开关,中断挂起有0->1,然后执行中断函数。【注】中断挂起需要手动置0。

2.1、EXTI通道

EXTI一共有20个通道,分别为EXTI0~EXTI19。而IO0连接着EXTI0通道,IO1连接着EXTI1通道,以此类推。让所有IO具备触发中断的能力

当然,如果GPIOA0使用了EXTI0时,GPIOB0~GPIOG0都不能使用EXTI0了,所以每个通过也就只能使用一个IO口。

2.2、内部寄存器

如图:除了软件触发寄存器外,其他的寄存器都是20位的,分别对应着20个EXTI通道。

  • 当给上升沿寄存器的TR0写入1,给下降沿寄存器TR0写入0时,则EXTI0通道是上升沿产生一个中断源。如果都写入1,则上升沿和下降沿都能产生中断源。
  • 中断屏蔽寄存器是开关,写入1关闭开关,写入0打卡开关
  • 挂起寄存器,我们只需要手动置0,每次中断函数执行完成后,我们都应该给他置0,以便等待下一次中断

3、EXTI的编写程序

3.1、EXTI的编程接口


3.1.1、EXTI_Init

为什么不开启EXTI的时钟?因为啊默认都是打开了的。

4、编写实验

按钮通过外部中断控制LED灯的亮灭。下面是程序编写模型

其中AFIO用于选择IO引脚

c 复制代码
/*按钮通过外部中断控制LED灯的亮灭。*/
#include "stm32f10x.h"
#include "stm32f10x_pal.h"
#include "OLED.h"


int main(void)
{
//	PAL_Init();
//	OLED_Init();
	//1.PA0,PA1,PC13引脚的初始化
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
	GPIO_InitTypeDef GPIOInitStruct;
	GPIOInitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;//按钮
	GPIOInitStruct.GPIO_Mode = GPIO_Mode_IPU;//配置为上拉输入
	GPIO_Init(GPIOA ,&GPIOInitStruct);
	
	GPIOInitStruct.GPIO_Pin = GPIO_Pin_13;//LED
	GPIOInitStruct.GPIO_Speed = GPIO_Speed_2MHz;
	GPIOInitStruct.GPIO_Mode = GPIO_Mode_Out_OD;//配置为开漏输出
	GPIO_Init(GPIOC,&GPIOInitStruct);
	
	//2.AFIO选择通道
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);//选择EXTI0
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource1);//选择EXTI1
	
	//3.对EXTI0,EXTI1通道进行配置
	EXTI_InitTypeDef EXTIInitStruct;
	EXTIInitStruct.EXTI_Line = EXTI_Line0;
	EXTIInitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTIInitStruct.EXTI_Trigger = EXTI_Trigger_Rising;//上升沿产生中断源
	EXTIInitStruct.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTIInitStruct);
	
	EXTIInitStruct.EXTI_Line = EXTI_Line1;
	EXTIInitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTIInitStruct.EXTI_Trigger = EXTI_Trigger_Rising;//上升沿产生中断源
	EXTIInitStruct.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTIInitStruct);
	
	//4.对NVIC进行配置
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVICInitStruct;
	NVICInitStruct.NVIC_IRQChannel = EXTI0_IRQn;
	NVICInitStruct.NVIC_IRQChannelPreemptionPriority = 0;
	NVICInitStruct.NVIC_IRQChannelSubPriority = 0;
	NVICInitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVICInitStruct);
	
	NVICInitStruct.NVIC_IRQChannel = EXTI1_IRQn;
	NVICInitStruct.NVIC_IRQChannelPreemptionPriority = 0;
	NVICInitStruct.NVIC_IRQChannelSubPriority = 0;
	NVICInitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVICInitStruct);
	while(1)
	{
		
	}
}

	//5.中断响应函数
	void EXTI0_IRQHandler(void)
	{	
		EXTI_ClearITPendingBit(EXTI_Line0);//清除中断状态
		GPIO_WriteBit(GPIOC ,GPIO_Pin_13,Bit_RESET);//给ODR写入0,点亮LED
	}
	
	void EXTI1_IRQHandler(void)
	{
		EXTI_ClearITPendingBit(EXTI_Line1);//清除中断状态
		GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET);//熄灭LED
	}
相关推荐
最好有梦想~1 小时前
STM32F405RGT6单片机原理图、PCB免费分享
stm32·单片机·嵌入式硬件
三菱-Liu2 小时前
三菱MR-J4伺服绝对位置检测系统
运维·驱动开发·嵌入式硬件·硬件工程·制造·mr
优信电子3 小时前
GY-56 (VL53L0X) 激光测距
单片机·嵌入式硬件·51单片机·激光测距·vl53l0x
java 乐山3 小时前
GPIO 唤醒深度睡眠的esp32-c3
单片机·嵌入式硬件
编程圈子3 小时前
I.MX6U 裸机开发5.准备C环境并用C语言控制LED
c语言·开发语言·嵌入式硬件
沐欣工作室_lvyiyi4 小时前
基于单片机的直流稳压电源的设计(论文+源码)
stm32·单片机·嵌入式硬件·物联网·毕业设计
zhyjhacker5 小时前
WINDOWS XP ReactOS 4.2 对象类型
windows·单片机·嵌入式硬件
马浩同学5 小时前
【ESP32】ESP-IDF开发 | 低功耗管理+RTC唤醒和按键唤醒例程
c语言·单片机·嵌入式硬件·mcu
KINO326 小时前
基于STM32的hx711称重模块使用
stm32·单片机·嵌入式硬件
追梦少年时7 小时前
STM32—独立看门狗(IWDG)和窗口看门狗(WWDG)
stm32·单片机·嵌入式硬件