stm32 外部中断

STM32F10x芯片有84个中断通道,包括16个内核中断和68个可屏蔽中断
1
NVIC
NVIC英文全称是Nested Vectored Interrupt Controller,中文意思就是嵌套向量中断控制器,它属于M3内核的一个外设,控制着芯片的中断相关功能。由于ARM给NVIC预留了非常多的功能,但对于使用M3内核设计芯片的公司可能就不需要这么多功能,于是就需要在NVIC上裁剪。ST公司的STM32F103芯片内部中断数量就是NVIC裁剪后的结果

STM32F103芯片支持60个可屏蔽中断通道,每个中断通道都具备自己的中断优先级控制字节(8位,但是STM32F103中只使用4位,高4位有效),用于表达优先级的高4位又被为组成抢占式优先级和响应优先级,通常也把响应优先级称为“亚优先级”或“副优先级”,每个中断源都需要被指定这两种优先级

优先级分组
3
中断配置步骤

1.使能外设中断
2.设置中断优先级分组
3.初始化NVIC外设
4.编写中断处理函数

外部中断/事件控制器(EXTI)
对于互联型产品,外部中断/事件控制器由20个产生事件/中断请求的边沿检测器组成,对于其它产品,则有19个能产生事件/中断请求的边沿检测器。每个输入线可以独立地配置输入类型(脉冲或挂起)和对应的触发事件(上升沿或下降沿或者双边沿都触发)。每个输入线都可以独立地被屏蔽

外部中断/事件线路映像
4

EXTI线16连接到PVD输出
EXTI线17连接到RTC闹钟事件
EXTI线18连接到USB唤醒事件
EXTI线19连接到以太网唤醒事件(只适用于互联型产品)

外部中断配置步骤

1.使能IO口时钟,配置IO口模式为输入
2.开启AFIO时钟,设置IO口与中断线的映射关系
3.初始化NVIC外设,使能中断
4.初始化EXTI,选择触发方式,使能中断线
5.编写中断处理函数

中断处理函数

void EXTI0_IRQHandler(void)                                                          
void EXTI1_IRQHandler(void)                                                           
void EXTI2_IRQHandler(void)                                                          
void EXTI3_IRQHandler(void)                                                         
void EXTI4_IRQHandler(void) 
void EXTI9_5_IRQHandler(void) 
void EXTI15_10_IRQHandler(void)

参考startup_stm32f10x_hd.s

举例

void EXTI0_IRQHandler() //名字固定
{
	if(EXTI_GetITStatus(EXTI_Line0) == 1) //中断标志
	{
		delay_ms(10);

		if(key_up == 1)
		{
			led1 = ~led1;
		}
	}
	EXTI_ClearITPendingBit(EXTI_Line0); //清中断
}

typedef struct
{
	uint8_t NVIC_IRQChannel;  //中断源
	uint8_t NVIC_IRQChannelPreemptionPriority; //抢占优先级
	uint8_t NVIC_IRQChannelSubPriority; //响应优先级
	FunctionalState NVIC_IRQChannelCmd; //中断使能或失能
} NVIC_InitTypeDef;

typedef struct
{
	uint32_t EXTI_Line;  //中断线
	EXTIMode_TypeDef EXTI_Mode; //触发方式
	EXTITrigger_TypeDef EXTI_Trigger;  //触发方式
	FunctionalState EXTI_LineCmd; //中断线使能或失能
}EXTI_InitTypeDef;

void EXTI_init()
{
	NVIC_InitTypeDef nvic = 
	{
		EXTI0_IRQn,
		2,
		2,
		ENABLE
	};

	EXTI_InitTypeDef exti = 
	{
		EXTI_Line0,
		EXTI_Mode_Interrupt,
		EXTI_Trigger_Rising,
		ENABLE
	};

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //使能AFIO时钟

	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); //中断线映射

	NVIC_Init(&nvic); //初始化NVIC

	EXTI_Init(&exti); //初始化EXTI
}

int main(void)
{
	GPIO_InitTypeDef gpio_key = 
	{
		GPIO_Pin_0,
		GPIO_Speed_50MHz,
		GPIO_Mode_IPD //输入
	};

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //常用分组方式
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	GPIO_Init(GPIOA, &gpio_key);
	
	EXTI_init();
}
posted @ 2017-08-09 22:43  thomas_blog  阅读(272)  评论(0编辑  收藏  举报