stm32 外部中断
STM32F10x芯片有84个中断通道,包括16个内核中断和68个可屏蔽中断
NVIC
NVIC英文全称是Nested Vectored Interrupt Controller,中文意思就是嵌套向量中断控制器,它属于M3内核的一个外设,控制着芯片的中断相关功能。由于ARM给NVIC预留了非常多的功能,但对于使用M3内核设计芯片的公司可能就不需要这么多功能,于是就需要在NVIC上裁剪。ST公司的STM32F103芯片内部中断数量就是NVIC裁剪后的结果
STM32F103芯片支持60个可屏蔽中断通道,每个中断通道都具备自己的中断优先级控制字节(8位,但是STM32F103中只使用4位,高4位有效),用于表达优先级的高4位又被为组成抢占式优先级和响应优先级,通常也把响应优先级称为“亚优先级”或“副优先级”,每个中断源都需要被指定这两种优先级
优先级分组
中断配置步骤
1.使能外设中断
2.设置中断优先级分组
3.初始化NVIC外设
4.编写中断处理函数
外部中断/事件控制器(EXTI)
对于互联型产品,外部中断/事件控制器由20个产生事件/中断请求的边沿检测器组成,对于其它产品,则有19个能产生事件/中断请求的边沿检测器。每个输入线可以独立地配置输入类型(脉冲或挂起)和对应的触发事件(上升沿或下降沿或者双边沿都触发)。每个输入线都可以独立地被屏蔽
外部中断/事件线路映像
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();
}