一、EXTI外部中断/事件功能框图
1、中断线路:①-②-③-④-⑤
①输入线:有19个中断/事件输入线(联网型有20个),通过寄存器将这些输入线设置为任意一个GPIO。
②边沿检测电路:选择上升沿触发、下降沿触发或者上升和下降沿都触发。
③或门:选择软件触发或者GPIO输入触发中断。
④与门:从或门③输出的信号分为两路,上路经过请求挂起寄存器输出与中断屏蔽寄存器一起控制与门的输出,并将与门④的输出保存至挂起寄存器EXTI_PR。
⑤、将EXTI_PR寄存器内容输出至NVIC。
2、事件线路:①-②-③-⑥-⑦-⑧
⑥与门:从或门③输出的信号分为两路,下路经过与门⑥,与事件屏蔽寄存器一起控制是否选择事件。
⑦脉冲发生器电路:与门⑥输出为1时,产生一个脉冲信号。
⑧脉冲信号:控制外设事件。
二、EXTI外部中断通路
打通这条通路即可实现EXTI中断/事件。
GPIOA~GPIOI的所有引脚全部连接至AFIO上,作为输入线,但数字编号相同的引脚只能算作一条输入线。如下图:
从PA0~PH0中,通过AFIO的EXTICR1寄存器选择一天作为EXTI0的输入源。
三、EXTI配置
1、配置时钟:开启GPIOB和AFIO的时钟,EXTI和NVIC(内核外设)的时钟不需要开启
2、设置GPIO输入模式:
①EXTI推荐的模式见下表:可选择浮空、上拉或下拉。
②输入引脚:选择GPIO_Pin_14。
③速度:用于是输入模式,GPIO_Speed任选。
3、配置AFIO:使用GPIO_EXTILineConfig函数,该函数位于GPIO外设源码中。
4、配置EXTI:
①EXTI_Line选择14号。
②EXTI_LineCmd选择ENABLE。
③EXTI_Mode:有EXTI_Mode_Event和EXTI_Mode_Interrupt两种,这里选择EXTI_Mode_Interrupt。
typedef enum
{
EXTI_Mode_Interrupt = 0x00,
EXTI_Mode_Event = 0x04
}EXTIMode_TypeDef;
④EXTI_Trigger:这里有EXTI_Trigger_Rising、EXTI_Trigger_Falling和EXTI_Trigger_Rising_Falling,选择一种即可。
typedef enum
{
EXTI_Trigger_Rising = 0x08,
EXTI_Trigger_Falling = 0x0C,
EXTI_Trigger_Rising_Falling = 0x10
}EXTITrigger_TypeDef;
5、配置NVIC,该外设在misc.c文件中。
①配置优先级分组:抢占优先级(主优先级)和子优先级,这里选择第二组,分组方式整个芯片只能使用一种。
在这里插入代码片/**
@code
The table below gives the allowed values of the pre-emption priority and subpriority according
to the Priority Grouping configuration performed by NVIC_PriorityGroupConfig function
============================================================================================================================
NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description
============================================================================================================================
NVIC_PriorityGroup_0 | 0 | 0-15 | 0 bits for pre-emption priority
| | | 4 bits for subpriority
----------------------------------------------------------------------------------------------------------------------------
NVIC_PriorityGroup_1 | 0-1 | 0-7 | 1 bits for pre-emption priority
| | | 3 bits for subpriority
----------------------------------------------------------------------------------------------------------------------------
NVIC_PriorityGroup_2 | 0-3 | 0-3 | 2 bits for pre-emption priority
| | | 2 bits for subpriority
----------------------------------------------------------------------------------------------------------------------------
NVIC_PriorityGroup_3 | 0-7 | 0-1 | 3 bits for pre-emption priority
| | | 1 bits for subpriority
----------------------------------------------------------------------------------------------------------------------------
NVIC_PriorityGroup_4 | 0-15 | 0 | 4 bits for pre-emption priority
| | | 0 bits for subpriority
============================================================================================================================
@endcode
*/
②配置NVIC_InitStructure结构体用于初始化:
NVIC_IRQChannel选择EXTI15_10_IRQn,STM32的EXTI15~EXTI10放置在一个中断里;
NVIC_IRQChannelCmd=ENABLE;NVIC_IRQChannelPreemptionPriority=1;NVIC_IRQChannelSubPriority=1;
③调用NVIC_Init()初始化。
四、加入中断事件处理函数
在stratup_stm32f10x_md.s中查看中断向量表,中断向量表中定义的就是中断函数的名字。
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
DCD WWDG_IRQHandler ; Window Watchdog
DCD PVD_IRQHandler ; PVD through EXTI Line detect
DCD TAMPER_IRQHandler ; Tamper
DCD RTC_IRQHandler ; RTC
DCD FLASH_IRQHandler ; Flash
DCD RCC_IRQHandler ; RCC
DCD EXTI0_IRQHandler ; EXTI Line 0
DCD EXTI1_IRQHandler ; EXTI Line 1
DCD EXTI2_IRQHandler ; EXTI Line 2
DCD EXTI3_IRQHandler ; EXTI Line 3
DCD EXTI4_IRQHandler ; EXTI Line 4
DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
DCD ADC1_2_IRQHandler ; ADC1_2
DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
DCD CAN1_RX1_IRQHandler ; CAN1 RX1
DCD CAN1_SCE_IRQHandler ; CAN1 SCE
DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
DCD TIM1_BRK_IRQHandler ; TIM1 Break
DCD TIM1_UP_IRQHandler ; TIM1 Update
DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
DCD TIM2_IRQHandler ; TIM2
DCD TIM3_IRQHandler ; TIM3
DCD TIM4_IRQHandler ; TIM4
DCD I2C1_EV_IRQHandler ; I2C1 Event
DCD I2C1_ER_IRQHandler ; I2C1 Error
DCD I2C2_EV_IRQHandler ; I2C2 Event
DCD I2C2_ER_IRQHandler ; I2C2 Error
DCD SPI1_IRQHandler ; SPI1
DCD SPI2_IRQHandler ; SPI2
DCD USART1_IRQHandler ; USART1
DCD USART2_IRQHandler ; USART2
DCD USART3_IRQHandler ; USART3
DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
DCD RTCAlarm_IRQHandler ; RTC Alarm through EXTI Line
DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
__Vectors_End
五、函数代码
#include "stm32f10x.h" // Device header
uint16_t CountSensor_Count=0;
void CountSensor_Init(void){
//第一步:配置时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//第二步:配置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
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);
//第四步:配置EXTI
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_Rising;
EXTI_Init(&EXTI_InitStructure);
//第五步:配置NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//分组方式整个芯片只能使用一种
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);
}
uint16_t CountSensor_Get(void){
return CountSensor_Count;
}
void EXTI15_10_IRQHandler(){
if(EXTI_GetITStatus(EXTI_Line14)==SET){
CountSensor_Count++;
EXTI_ClearITPendingBit(EXTI_Line14);
}
}