(1)配置步骤
1.配置RCC 打开外设时钟
2.配置GPIO 选择端口输入模式
3.配置AFIO 选择要用的一路GPIO 连接至EXTI
4.配置EXTI 选择边沿触发方式 上升沿 下降沿 双边沿
选择触发响应方式 中断响应 事件响应
5.配置NVIC 选择一个合适的优先级
其中涉及外设有RCC、GPIO、AFIO、EXTI、NVIC
(2)代码示例
案例1 (设置PB14为外部中断触发的方式)
//使能GPIOB对应的外设时钟以及AFIO对应的外设时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//对于外部中断,要选择浮空、上拉、下拉输入的其一
这个根据STM32F10xxx参考手册(中文)8.1.11 外设的GPIO配置内含所有外设的模式选择
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//配置AFIO为外部中断线14的输入引脚
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);
//配置外部中断线14,使能中断,中断触发方式为下降沿触发
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line14;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStructure);
//配置NVIC中断优先级分组2,抢占式2位,响应式2位。
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//配置NVIC外部中断通道EXTI15_10_IRQn,使能中断通道,设置抢占1位,响应1位。
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
案例2(设置PB1 PB11为外部中断触发的方式)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = 0x0802;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource11);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line=EXTI_Line1|EXTI_Line11;
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_1);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
NVIC_Init(&NVIC_InitStructure);
(3)函数分析
函数1:void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
(stm32f10x_gpio.h)
该函数虽然是GPIO开头但是实则是操作AFIO的寄存器,选择外部中断线。
序号 | 名称 | 参数解释 | 示例 |
参数1 | GPIO_PortSource | 选择GPIO外设作为外部中断源A..G | GPIO_PortSourceGPIOB |
参数2 | GPIO_PinSource | 指定参数的外部中断线0..15 | GPIO_PinSource14 |
函数2:void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)(stm32f10x_exti.h)
用结构体的参数来初始化EXTI外设。
序号 | 名称 | 参数解释 | 示例 |
参数1 | EXTI_InitTypeDef* EXTI_InitStruct | 选择GPIO外设作为外部中断源A..G | &EXTI_InitStructure |
补充:对于EXTI_InitTypeDef结构体中的成员变量分别是
EXTI_InitStructure.EXTI_Line(中断线配置)
EXTI_InitStructure.EXTI_LineCmd (中断线的状态开启)
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt(中断、事件Event模式选择)
EXTI_InitStructure.EXTI_Trigger(指定触发信号的边沿 上升沿 下降沿 上升下降沿)
函数3:void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)(misc.h)
该函数用来配置NVIC分组先占优先级以及抢占优先级,防止中断冲突。
序号 | 名称 | 参数解释 | 示例 |
参数1 | PriorityGroup | 选择NVIC分组 | NVIC_PriorityGroup_2 |
函数4:void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)(misc.h)
函数NVIC_InitTypeDef的成员变量如下根据STM32F10xxx参考手册9.2.5外部中断/事件线路映像
序号 | 名称 | 参数解释 | 示例 |
参数1 | NVIC_IRQChannel | 指定中断通道开启或者关闭 | EXTI0_IRQn EXTI1_IRQn EXTI2_IRQn EXTI3_IRQn EXTI4_IRQn EXTI9_5_IRQn EXTI15_10_IRQn |
参数2 | NVIC_IRQChannelCmd | 指定中断使能或者失能 | ENABLE or DISABLE |
参数3 | NVIC_IRQChannelPreemptionPriority | 指定抢占优先级 | 1(根据分组表) |
参数4 | NVIC_IRQChannelSubPriority | 指定响应优先级 | 1(根据分组表) |
补充上述NVIC分组内容:NVIC的中断优先级由优先级寄存器的4位(0~15)决定,这4位可以进行切分,分为高n位的抢占优先级和低4-n位的响应优先级;
抢占优先级高的可以中断嵌套,响应优先级高的可以优先排队,抢占优先级和响应优先级均相同的按中断号排队
分组方式 | 抢占优先级 | 响应优先级 |
分组0 | 0位、取位为0 | 4位、取位为0-15 |
分组1 | 1位、取位为0-1 | 3位、取位为0-7 |
分组2 | 2位、取位为0-3 | 2位、取位为0-3 |
分组3 | 3位、取位为0-7 | 1位、取位为0-1 |
分组4 | 4位、取位为0-15 | 0位、取位为0 |
函数5:ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)(stm32f10x_exti.h)
该函数是获取指定中断标志位的状态,也就是是1还是0。
序号 | 名称 | 参数解释 | 示例 |
参数1 | EXTI_Line | 指定中断标志位 | EXTI_Line14 |
主要配合void EXTI_ClearITPendingBit(uint32_t EXTI_Line)使用,该函数用来清除标志位,参数用法跟上述函数一致,每次进入中断都要手动清除;如下为示例
//位于启动文件中startup_stm32f10x_md.s 参数名根据中断标志位选择 否则无法进入
void EXTI15_10_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line14) == SET)
{
/*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0)
{
//中断触发事件
}
//清除指定中断标志位
EXTI_ClearITPendingBit(EXTI_Line14);
}
}