打印
[STM32F0]

STM32入门学习之EXTI外部中断(转)

[复制链接]
1815|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
下面的代码,是把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);  
}  


沙发
mintspring|  楼主 | 2017-5-19 17:26 | 只看该作者
先补充概念1,同GPIO、USART、NVIC等一样,我们再使用EXTI是首先要定义一个EXTI_InitTypeDef

我们可通过EXTI的头文件查看,库是怎么定义EXTI_InitTypeDef

typedef struct  
{  
  uint32_t EXTI_Line;<span style="white-space:pre">           </span>//线                 
  EXTIMode_TypeDef EXTI_Mode;       <span style="white-space:pre">    </span>//模式  
  EXTITrigger_TypeDef EXTI_Trigger; <span style="white-space:pre">    </span>//触发类型  
  FunctionalState EXTI_LineCmd;     <span style="white-space:pre">    </span>//使能  
}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);  


使用特权

评论回复
板凳
mintspring|  楼主 | 2017-5-19 17:27 | 只看该作者
继续看头文件,了解EXTI的MODE
typedef enum  
{  
  EXTI_Mode_Interrupt = 0x00,  
  EXTI_Mode_Event = 0x04  
}EXTIMode_TypeDef;  
一个是Interrupt中断,一个是Event事件。

中断,系统最多只能给其配置个中断向量入口,然后执行相应的软件程序。

而事件,系统中存在硬件电路,可配置其连接至需要触发硬件电路中,如触发AD转换,或者引起DMA操作等。


使用特权

评论回复
地板
mintspring|  楼主 | 2017-5-19 17:28 | 只看该作者
关于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   


使用特权

评论回复
5
mintspring|  楼主 | 2017-5-19 17:29 | 只看该作者
好了,问题来了,居然EXTI0_1_IRQn包含两个中断,那怎么区分呢?
if(EXTI_GetITStatus(EXTI_Line0)!=RESET)

这下应该知道中断函数里为什么加这句的原因了吧。

使用特权

评论回复
6
viseng| | 2017-5-20 11:49 | 只看该作者
谢啦,及时雨,昨天刚问的问题

使用特权

评论回复
7
51xlf| | 2017-5-20 23:02 | 只看该作者
外部中断配置,还需要注意IO的形态。

使用特权

评论回复
8
51xlf| | 2017-5-20 23:05 | 只看该作者
PIO_PuPd这个对于串口配置很重要。

使用特权

评论回复
9
mintspring|  楼主 | 2017-5-25 11:31 | 只看该作者
好多可以参考官方的手册的。

使用特权

评论回复
10
sonicll| | 2017-5-26 14:39 | 只看该作者
请教一下,如果我同时使用PA0和PB0来做中断,EXTI0_1_IRQHandler里怎么区分是PA0还是PB0呢?

使用特权

评论回复
11
Snow7| | 2017-5-30 16:56 | 只看该作者
中断,系统最多只能给其配置个中断向量入口,然后执行相应的软件程序。

使用特权

评论回复
12
cat_li| | 2017-7-17 11:37 | 只看该作者
sonicll 发表于 2017-5-26 14:39
请教一下,如果我同时使用PA0和PB0来做中断,EXTI0_1_IRQHandler里怎么区分是PA0还是PB0呢? ...

不能同时使用PA0和PB0作为中断的

使用特权

评论回复
13
搁浅jl| | 2017-7-18 10:03 | 只看该作者
外部中断用的地方挺多的,按键触发,计算方波的频率和占空比。

使用特权

评论回复
14
mintspring|  楼主 | 2017-7-19 21:02 | 只看该作者
STm32也是非常给力的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

296

主题

4896

帖子

24

粉丝