EXTI-外部中断/事件控制器

目录

EXTI简介

EXTI功能框图

GPIO中断实验

1-初始化要连接到EXTI的GPIO

2-初始化EXTI用于产生中断/事件

3-初始化NVIC,用于处理中断

4-编写中断服务函数

5-main函数

如果PA0 PB0 PC0 都连接到EXTI0的时候怎么办?


EXTI简介

EXTI(External interrupt/event controller)—外部中断/事件控制器,管理了控制器的 20 个中断/事 件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的 检测。

EXTI功能框图

EXTI 可分为两大部分功能,一个是产生中断,另一个是产生事件,这两个功能从硬件上就有所 不同。 首先我们来看图EXTI功能框图中红色虚线指示的电路流程。它是一个产生中断的线路,最终信 号流入到NVIC控制器内。

编号1是输入线,EXTI控制器有19个中断/事件输入线,这些输入线可以通过寄存器设置为任 意一个GPIO,也可以是一些外设的事件

编号2是一个边沿检测电路,它会根据上升沿触发选择寄存器(EXTI_RTSR)和下降沿触发选择 寄存器(EXTI_FTSR)对应位的设置来控制信号触发。。边沿检测电路以输入线作为信号输入端,如 果检测到有边沿跳变就输出有效信号1给编号3电路,否则输出无效信号0。而EXTI_RTSR和EXTI_FTSR两个寄存器可以控制需要检测哪些类型的电平跳变过程,可以是只有上升沿触发、只 有下降沿触发或者上升沿和下降沿都触发

EXTI_Line:输入线的选择是通过AFIO来选择的,这里的EXTI_Line是为了编程的时候,编程寄存器的哪一个位 

EXTI_Mode :事件EXTI_Mode_Event和中断EXTI_Mode_Interrupt两种模式

EXTI_Trigger:上升沿,下降沿,上升沿和下降沿

GPIO中断实验

1-初始化要连接到EXTI的GPIO

    GPIO_InitTypeDef GPIO_InitStruct;
    RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK, ENABLE);
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStruct.GPIO_Pin=KEY1_INT_GPIO_PIN;
	GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStruct);

2-初始化EXTI用于产生中断/事件

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);//选择输入线
	EXTI_InitStruct.EXTI_Line=EXTI_Line0;
	EXTI_InitStruct.EXTI_LineCmd=ENABLE;
	EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
	EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;
	EXTI_Init(&EXTI_InitStruct);

3-初始化NVIC,用于处理中断

static void nvic_exti_config(void)//加上static说明这个函数只能被bsp_exti.c这个文件调用
{
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	
	NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;//主优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;//子优先级
    NVIC_Init(&NVIC_InitStruct);
}

4-编写中断服务函数

void EXTI0_IRQHandler(void)
{
 if(EXTI_GetITStatus(EXTI_Line0)!=0)//确保是该中断线产生的中断
 {
	LED_G_TOGGLE;
 }
 EXTI_ClearITPendingBit(EXTI_Line0);
}


5-main函数

int main(void)
{
	led_init();
	exti_key_init();
	while(1)
	{
	
	}
	
}

bsp_exti.c代码


#include "bsp_exti.h"
static void nvic_exti_config(void)//加上static说明这个函数只能被bsp_exti.c这个文件调用
{
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	
	NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;//主优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;//子优先级
  NVIC_Init(&NVIC_InitStruct);
}
void exti_key_init(void)
{
	
	GPIO_InitTypeDef GPIO_InitStruct;
	EXTI_InitTypeDef EXTI_InitStruct;
	
	//配置中断优先级
    nvic_exti_config();
	
	//初始化GPIO
	RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK, ENABLE);
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStruct.GPIO_Pin=KEY1_INT_GPIO_PIN;
	GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStruct);
	
	//初始化EXTI
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);//选择输入线
	EXTI_InitStruct.EXTI_Line=EXTI_Line0;
	EXTI_InitStruct.EXTI_LineCmd=ENABLE;
	EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
	EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;
	EXTI_Init(&EXTI_InitStruct);
}

bsp_exti.h代码

#ifndef _BSP_EXTI_H
#define _BSP_EXTI_H
#include "stm32f10x.h"   

#define KEY1_INT_GPIO_PIN     GPIO_Pin_0
#define KEY1_INT_GPIO_PORT    GPIOA
#define KEY1_INT_GPIO_CLK     RCC_APB2Periph_GPIOA

void exti_key_init(void);
#endif

如果PA0 PB0 PC0 都连接到EXTI0的时候怎么办?

可以在中断服务函数中进行判断,比如判断GPIOA->IDR,GPIOB->IDR

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值