1.中断概念:
(1)STM32的每个IO口都可以作为外部中断输入;
(2)stm32的中断控制器支持19个外部中断/事件请求
- 线0~15:对应外部IO口的输入中断;
- 线16:连接到PVD输出;
- 线17:连接到RTC闹钟事件;
- 线18:连接到USB唤醒事件;
(3)每个外部中断线可以独立的配置触发方式(上升沿,下降沿或双边沿触发),触发/屏蔽,专用的状态位。
(4)STM32供IO使用的中断线只有16个,但STM32F10x系列的IO口多达上百个,STM32F10ZET6(112),STM32F103RCT6(51)。
中断线与IO口对应关系:
IO口外部中断在中断向量表中只分配了7个中断向量,也就是只能使用7个中断服务函数,外部中断线5~9分配一个中断向量,共用一个服务函数,外部中断线10~15分配一个中断向量,共用一个中断服务函数:
2.中断服务函数列表:
3.外部中断常用库函数:
- void GPIO_EXTILineConfig(uint_8 GPIO_PortSource,uint_8 GPIO_PinSource);//设置IO口与中断线的映射关系;
- void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);//初始化中断线,触发方式等;
- ITStatus EXTI_GetITStatus(uint_32_t EXTI_Line);//判断中断线中断状态,是否发生;
- void EXTI_ClearITPendingBit(uint32_t EXTI_Line);//清除中断线上的中断标志位;
4.EXTI_Init()函数:
5.外部中断的一般配置步骤:
- 初始化IO为输入;GPIO_Init();
- 开启IO口复用时钟;RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
- 设置IO口与中断线的映射关系;void GPIO_EXTILineConfig();
- 初始化线上中断,设置触发条件等;EXTI_Init();
- 配置中断分组(NVIC),并使能中断;
- 编写中断服务函数;EXTIx_IRQHandler();
- 清除中断标志位;EXTI_ClearITPendingBit();
6.库函数实现外部中断:
外部中断方式控制LED(外部中断通过PE的KEY0来控制LED0灯的亮灭):
(1)主函数:
#include "delay.h"
#include "led.h"
#include "usart1.h"
#include "exti.h"
int main(){
u8 i=0;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断分组
delay_init(); //延时初始化
LED_Init(); //LED初始化
EXTIx_Init(); //外部中断初始化
delay_ms(50);
while(1){
i++;
if(i%20==0)
{
LED1=!LED1;
}
delay_ms(10);
}
}
(2)头文件:
#ifndef __EXTI_H
#define __EXTI_H
void EXTIx_Init(void);
#endif
(3)外部中断初始化:
#include "stm32f10x.h"
#include "delay.h"
#include "led.h"
#include "exti.h"
/*
功能:外部中断初始化
变量:无
返回值:无
*/
void EXTIx_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
//1.使能IO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
//2.配置IO
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU; //输入上拉
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4; //PE4
GPIO_Init(GPIOE,&GPIO_InitStruct);
//3.开启IO复用时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//4.设置IO口与中断线映射关系->映射到PE4
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
//5.初始化中断线
EXTI_InitStruct.EXTI_Line=EXTI_Line4; //中断线设置为线4
EXTI_InitStruct.EXTI_LineCmd=ENABLE; //使能
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt; //模式:中断或事件->这里选择的中断
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling; //触发方式选择为下降沿触发
EXTI_Init(&EXTI_InitStruct);
//6.中断服务管理
NVIC_InitStruct.NVIC_IRQChannel=EXTI4_IRQn; //中断通道选择4
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; //使能
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2; //优先级设置
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1; //子优先级设置
NVIC_Init(&NVIC_InitStruct);
}
/*
功能:中断服务函数
*/
void EXTI4_IRQHandler(void)
{
delay_ms(10);
if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)) //判断KEY0是否被按下
{
LED0=!LED0; //LED0闪烁
}
//清除中断标志位;
EXTI_ClearITPendingBit(EXTI_Line4);
}