EXTI外部中断

本文详细介绍了在STM32平台上如何配置和管理外部中断,包括对射式红外传感器和旋转编码器的中断触发机制,以及NVIC的中断优先级设置。通过实例展示了GPIO配置、AFIO、EXTI和NVIC的协同工作过程。
摘要由CSDN通过智能技术生成

外部中断适用场景:突发事件及一旦发生急需处理事件(如红外遥控,不及时处理容易丢失数据)

中断程序执行时间应尽量短:中断程序是打断主程序后执行,如果中断程序执行时间过长会对被打断的代码造成较大影响,因此中断程序执行时间越短越好。

中断程序与主程序应尽量避免使用同一个函数或外设避免造成冲突。

中断管家:

 使用NVIC统一管理中 断,每个中断通道都拥有16个可编程的优 先等级可对优先级进行分组,进一步设 置抢占优先级和响应优先级。

相同的pin不能同时触发中断:GPIOA与GPIOB的相同引脚不能同时触发中断。

事件触发:引脚电平触发时,选择触发事件。用于控制其他外设而不进入中断。

• 在STM32中,AFIO主要完成 两个任务:复用功能引脚重 映射、中断引脚选择。此处完成中断引脚选择。

外部中断配置流程:

• 配置外设时钟。EXTI与NVIC(内核外设)时钟默认打开。

• 配置GPIOx,

•配置AFIO,选择中断引脚。

•配置EXTI,选择中断线路,中断方式(事件,中断),有效触发边沿。

• 配置NVIC,选择分组方式,中断通道,抢占优先级和响应优先级。

对射式红外传感器:感应部件受遮挡及遮挡消失,引脚电平会发生变化。

#include "stm32f10x.h"    // Device header

uint16_t CountSensor_Count;
/**
  * 函    数:对射式红外传感器初始化
  * 参    数:无
  * 返 回 值:无
  */
void CounterSensot_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//打开PIOB时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//打开AFIO时钟
	//EXYI与NVIC(内核外设)时钟默认开启
	
	GPIO_InitTypeDef GPIO_InitStructure;//配置GPIO
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//上拉输入
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_14;//使用14号引脚
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//IO口翻转速度
	GPIO_Init(GPIOB,&GPIO_InitStructure);//读取结构体数值
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);//配置AFIC,选择GPIOB14号引脚作为中断源
	
	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_InitStructure.EXTI_Line=EXTI_Line14;//选择14号中段线路
	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;//指定通道10-15
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//指定抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;//指定响应优先级
	NVIC_Init(&NVIC_InitStructure);//读取结构体
}
/**
  * 函    数:返回传感器计数值
  * 参    数:无
  * 返 回 值:CountSensor_Count
  */
uint16_t Get_CountSensor_Count(void)
{
	return CountSensor_Count;
}
/**
  * 函    数:中断函数,每遮挡一次传感器,计数加1
  * 参    数:无
  * 返 回 值:无
  */
void EXTI15_10_IRQHandler(void)
{
	//触发中断才能进来中断函数,为什么还要进行标志位的判断
	if(EXTI_GetITStatus(EXTI_Line14))//通过标志位判断是否触发中断
	{
		CountSensor_Count++;//计数加1
		EXTI_ClearITPendingBit(EXTI_Line14);//清除标志位
	}
}

由于旋转方向不同,两个开关的导通时间不同,A,B处的电压波形便会产生一定的相位差,通过分析波形可判断旋转方向。

旋转编码器计数:

#include "stm32f10x.h"                  // Device header

uint16_t Encoder_Count;
/**
  * 函    数:旋转编码器初始化
  * 参    数:无
  * 返 回 值:无
  */
void CounterSensot_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//打开时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//打开时钟
	//EXYI与NVIC(内核外设)时钟默认开启
	
	GPIO_InitTypeDef GPIO_InitStructure;//配置GPIO
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0);//配置AFIC
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1);//配置AFIC
	
	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_InitStructure.EXTI_Line=EXTI_Line0|EXTI_Line1;//选择0和1号中断线
	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=EXTI0_IRQn;//指定通道
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//指定抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;//指定响应优先级
	NVIC_Init(&NVIC_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel=EXTI1_IRQn;//指定通道
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//指定抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;//指定响应优先级
	NVIC_Init(&NVIC_InitStructure);
	
}
/**
  * 函    数:获取计数值
  * 参    数:无
  * 返 回 值:编码器计数值
  */
int16_t Get_Encoder_Count(void)
{
	uint16_t Temp;
	Temp=Encoder_Count;
	Encoder_Count=0;
	
	return Temp;
}
/**
  * 函    数:0号中断函数
  * 参    数:无
  * 返 回 值:无
  */
void EXTI0_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line0)==SET)//到达下降沿
	{
		if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0)//旋转到位
		{
			Encoder_Count--;
		}
		EXTI_ClearFlag(EXTI_Line0);//清楚标志位
	}
}
/**
  * 函    数:1号中断函数
  * 参    数:无
  * 返 回 值:无
  */
void EXTI1_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line1)==SET)//下降沿触发
	{
		if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)==0)//旋转到位
		{
			Encoder_Count++;
		}
		EXTI_ClearFlag(EXTI_Line1);//清除标志位
	}
}

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值