1.介绍:STM32的每个IO 都可以作为外部中断的中断输入口,STM32F103的中断控制器支持19个外部中断/事件请求:
线0~15:对应外部IO 口的输入中断。
线16:连接到PVD输出。
线17:连接到RTC闹钟事件。
线18:连接到USB唤醒事件。
线16:连接到PVD输出。
线17:连接到RTC闹钟事件。
线18:连接到USB唤醒事件。
因此留给IO口的外部中断线只有16个,stm32的通用IO是GPIOA~GPIOG,并且每个端口配有16个引脚,因此不同IO的相同端口序号被分在一组,共分为16组,连接到16根外部中断线,所以在同一时间一根中短线智能分配一个IO口。
2.配置
a.挂载IO口的时钟, 先挂载GPIOx的时钟,然后挂载APB2中的辅助功能时钟AFIOEN,形成复用。
b.初始化IO口为输入,按照设计的外部中断触发脉冲的设置上拉和下拉电阻,若果要尽量防止中断的干扰,应该在外部加上拉获下拉电阻。
c.使用EXTI_InitTypeDef的结构体初始化外部中断。
typedef struct
{
uint32_t EXTI_Line; /*!< Specifies the EXTI lines to be enabled or disabled.
This parameter can be any combination of @ref EXTI_Lines */
EXTIMode_TypeDef EXTI_Mode; /*!< Specifies the mode for the EXTI lines.
This parameter can be a value of @ref EXTIMode_TypeDef */
EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines.
This parameter can be a value of @ref EXTIMode_TypeDef */
FunctionalState EXTI_LineCmd; /*!< Specifies the new state of the selected EXTI lines.
This parameter can be set either to ENABLE or DISABLE */
}EXTI_InitTypeDef;
通过参数判断可以找到这几个参数的取值范围,第一个是中断线;第二个是中断的模式,包括中断模式还是时间模式两种;第三个参数是中断的触发模式,包括上升沿触发、下降沿触发、上升下降都触发;最后一个是使能/禁止位。
d.设置外部中断的NVIC,也包括分组设置,然后用NVIC_InitTypeDef结构体配置4个参数,注意上面的中短线名与下面NVIC中的中断通道名字,它们并不是同一个。
下面以配置PE4为外部中断,上升沿触发为例子,代码如下:
void exInt_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef exti;
NVIC_InitTypeDef NVIC_exti;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE); //挂载IO口德时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //挂载复用IO的辅助功能时钟
//GPIO配置上拉输入
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉与上升沿对应
GPIO_Init(GPIOE,&GPIO_InitStructure);
//GPIO引脚与中断线的映射关系
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
//exti配置
exti.EXTI_Line = EXTI_Line4;
exti.EXTI_Mode = EXTI_Mode_Interrupt; //模式有中断模式和事件模式
exti.EXTI_Trigger = EXTI_Trigger_Rising;
exti.EXTI_LineCmd = ENABLE;
EXTI_Init(&exti);
//NVIC中断控制配置
NVIC_exti.NVIC_IRQChannel = EXTI4_IRQn;
NVIC_exti.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级是2
NVIC_exti.NVIC_IRQChannelSubPriority = 0x02; //子优先级是2
NVIC_exti.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_exti);
}
3.中断服务函数在中端服务函数记得清除外部中断的标志位(在挂起寄存器(EXTI_PR)中),是中断的挂起标志,写1清除。
中断函数的名字还是要与启动文件中中断向量表中的设置一样,否则会连接不到。
清楚标志位的位置放在服务函数的第一句还是最后一句在中断函数不长的情况下应该都行。