下面的代码,是把PA0当做一个按键口,芯片内部上拉,按键闭合时,IO口被拉低,触发中断。
#include "stm32_lib/inc/stm32f0xx_rcc.h"
#include "stm32_lib/inc/stm32f0xx_exti.h"
#include "stm32_lib/inc/stm32f0xx_gpio.h"
#include "stm32_lib/inc/stm32f0xx_syscfg.h"
#include "stm32_lib/inc/stm32f0xx_misc.h"
int main(void)
{
//时钟使能
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
//外部按键GPIO初始华,PA0
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
//将EXTI0指向PA0
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource0);
//EXTI0中断线配置
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line=EXTI_Line0;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStructure);
//EXTI0中断向量配置
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=EXTI0_1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority=0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
while(1){
}
}
void EXTI0_1_IRQHandler(void){
if(EXTI_GetITStatus(EXTI_Line0)!=RESET)
{
//中断处理
}
//退出中断时注意清除标志位
EXTI_ClearFlag(EXTI_Line0);
}
先补充概念1,同GPIO、USART、NVIC等一样,我们再使用EXTI是首先要定义一个EXTI_InitTypeDef
我们可通过EXTI的头文件查看,库是怎么定义EXTI_InitTypeDef
typedef struct
{
uint32_t EXTI_Line; //线
EXTIMode_TypeDef EXTI_Mode; //模式
EXTITrigger_TypeDef EXTI_Trigger; //触发类型
FunctionalState EXTI_LineCmd; //使能
}EXTI_InitTypeDef;
关于EXTI_Line,继续看头文件
#define EXTI_Line0 ((uint32_t)0x00000001) /*!< External interrupt line 0 */
#define EXTI_Line1 ((uint32_t)0x00000002) /*!< External interrupt line 1 */
#define EXTI_Line2 ((uint32_t)0x00000004) /*!< External interrupt line 2 */
#define EXTI_Line3 ((uint32_t)0x00000008) /*!< External interrupt line 3 */
#define EXTI_Line4 ((uint32_t)0x00000010) /*!< External interrupt line 4 */
#define EXTI_Line5 ((uint32_t)0x00000020) /*!< External interrupt line 5 */
#define EXTI_Line6 ((uint32_t)0x00000040) /*!< External interrupt line 6 */
#define EXTI_Line7 ((uint32_t)0x00000080) /*!< External interrupt line 7 */
#define EXTI_Line8 ((uint32_t)0x00000100) /*!< External interrupt line 8 */
#define EXTI_Line9 ((uint32_t)0x00000200) /*!< External interrupt line 9 */
#define EXTI_Line10 ((uint32_t)0x00000400) /*!< External interrupt line 10 */
#define EXTI_Line11 ((uint32_t)0x00000800) /*!< External interrupt line 11 */
#define EXTI_Line12 ((uint32_t)0x00001000) /*!< External interrupt line 12 */
#define EXTI_Line13 ((uint32_t)0x00002000) /*!< External interrupt line 13 */
#define EXTI_Line14 ((uint32_t)0x00004000) /*!< External interrupt line 14 */
#define EXTI_Line15 ((uint32_t)0x00008000) /*!< External interrupt line 15 */
#define EXTI_Line16 ((uint32_t)0x00010000) /*!< External interrupt line 16
Connected to the PVD Output */
#define EXTI_Line17 ((uint32_t)0x00020000) /*!< Internal interrupt line 17
Connected to the RTC Alarm
event */
#define EXTI_Line19 ((uint32_t)0x00080000) /*!< Internal interrupt line 19
Connected to the RTC Tamper
and Time Stamp events */
#define EXTI_Line21 ((uint32_t)0x00200000) /*!< Internal interrupt line 21
Connected to the Comparator 1
event */
#define EXTI_Line22 ((uint32_t)0x00400000) /*!< Internal interrupt line 22
Connected to the Comparator 2
event */
#define EXTI_Line23 ((uint32_t)0x00800000) /*!< Internal interrupt line 23
Connected to the I2C1 wakeup
event */
#define EXTI_Line25 ((uint32_t)0x02000000) /*!< Internal interrupt line 25
Connected to the USART1 wakeup
event */
#define EXTI_Line27 ((uint32_t)0x08000000) /*!< Internal interrupt line 27
Connected to the CEC wakeup
event */
这里定义了N多EXTI_Line,其中Line0-Line15表示GPIOX_Pin_N的中断。如何区分GPIOX呢?这也就是概念2要补充的了。这里通过SYSCFG_EXTILineConfig函数来配置。
//将EXTI0指向PA0
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource0);
继续看头文件,了解EXTI的MODE
typedef enum
{
EXTI_Mode_Interrupt = 0x00,
EXTI_Mode_Event = 0x04
}EXTIMode_TypeDef;
一个是Interrupt中断,一个是Event事件。
中断,系统最多只能给其配置个中断向量入口,然后执行相应的软件程序。
而事件,系统中存在硬件电路,可配置其连接至需要触发硬件电路中,如触发AD转换,或者引起DMA操作等。
关于EXTITrigger_TypeDef,经常使用示波器的朋友们想必已经很清楚了,上升沿触发、下降沿触发、上升下降兼触发。
typedef enum { EXTI_Trigger_Rising = 0x08, EXTI_Trigger_Falling = 0x0C, EXTI_Trigger_Rising_Falling = 0x10 }EXTITrigger_TypeDef; NVIC中的IRQChannel为什么是EXTI0_1_IRQN呢? 这个可以再stm32f0xx.h头文件找到 EXTI0_1_IRQn对应线0和1的中断 EXTI2_3_IRQn对应线2和3的中断 EXTI4_15_IRQn对应线4-15的中断 #if defined (STM32F0XX_MD) || defined (STM32F030X8) /****** STM32F0XX_MD and STM32F030X8 specific Interrupt Numbers *************************************/ WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */ PVD_IRQn = 1, /*!< PVD through EXTI Line detect Interrupt */ RTC_IRQn = 2, /*!< RTC through EXTI Line Interrupt */ FLASH_IRQn = 3, /*!< FLASH Interrupt */ RCC_IRQn = 4, /*!< RCC Interrupt */ EXTI0_1_IRQn = 5, /*!< EXTI Line 0 and 1 Interrupts */ EXTI2_3_IRQn = 6, /*!< EXTI Line 2 and 3 Interrupts */ EXTI4_15_IRQn = 7, /*!< EXTI Line 4 to 15 Interrupts 好了,问题来了,居然EXTI0_1_IRQn包含两个中断,那怎么区分呢? if(EXTI_GetITStatus(EXTI_Line0)!=RESET) 这下应该知道中断函数里为什么加这句的原因了吧。
上一篇:STM32入门学习之GPIO(STM32F030F4P6基于CooCox IDE)(一)
下一篇:stm32f030-GPIO配置
推荐阅读最新更新时间:2024-03-16 16:08