打印
[应用相关]

STM32 EXTI外部中断

[复制链接]
41|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
一、中断简介
  在主程序运行过程中,出现了特定的中断触发条件(中断源),使得CPU暂停当前正在运行的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续运行。



图1 中断示意图
  STM32有68个可屏蔽中断通道,包含EXTI、TIM、ADC、USART、SPI、I2C、RTC等多个外设。使用NVIC统一管理中断,每个中断通道都拥有16个可编程的优先等级,可对优先级进行分组,进一步设置抢占优先级和响应优先级

二、NVIC简介
  NVIC是嵌套向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。但是各个芯片厂商在设计芯片的时候会对Cortex-M3内核里面的NVIC进行裁剪,把不需要的部分去掉,所以说STM32的NVIC是Cortex-M3的NVIC的一个子集。



图2 NVIC基本结构



图3 NVIC优先级分组
  NVIC的中断优先级由优先级寄存器的4位(0~15)决定,这4位可以进行切分,分为高n位的抢占优先级和低4-n位的响应优先级。
  抢占优先级高的可以中断嵌套,响应优先级高的可以优先排队,抢占优先级和响应优先级均相同的按中断号排队。

三、EXTI简介
  EXTI(External interrupt/event controller)——外部中断/事件控制器,管理了控制器的 20个中断/事件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测。



图4 EXTI基本结构
3.1 AFIO复用I/O口



图5 EXTI中断/事件线



图6 EXTx输入源选择
  在STM32中,AFIO主要完成两个任务:复用功能引脚重映射、中断引脚选择。

3.2 EXTI功能框图



图7 EXTI 功能框图
  EXTI 可分为两大部分功能,一个是产生中断,另一个是产生事件.
  图7中红色虚线是一个产生中断的线路,最终信号流入到NVIC控制器内。

编号1是输入线,EXTI控制器有19个中断/事件输入线,这些输入线可以通过寄存器设置为任意一个 GPIO,也可以是一些外设的事件。
编号 2是一个边沿检测电路,它会根据上升沿触发选择寄存器(EXTI_RTSR)和下降沿触发选择寄存器(EXTI_FTSR)对应位的设置来控制信号触发。如果检测到有边沿跳变就输出有效信号 1给编号 3电路,否则输出无效信号0。
编号 3电路实际就是一个或门电路,它一个输入来自编号 2电路,另外一个输入来自软件中断事件寄存器(EXTI_SWIER)。EXTI_SWIER 允许我们通过程序控制就可以启动中断/事件线,即只要有一个中断请求进入就响应。
编号 4电路是一个与门电路,它一个输入是编号 3电路,另外一个输入来自中断屏蔽寄存器(EXTI_IMR)。只有当中断屏蔽寄存器输出1时,才会响应。
编号5是将EXTI_PR寄存器内容输出到NVIC内,从而实现系统中断事件控制。
  图7中绿色虚线是一个产生事件的线路,最终输出一个脉冲信号。

编号6 电路是一个与门,它一个输入来自编号 3 电路,另外一个输入来自事件屏蔽寄存器(EXTI_EMR)。只有当中断屏蔽寄存器输出1时,才会响应。
编号 7是一个脉冲发生器电路,当它的输入端,即编号 6电路的输出端,是一个有效信号1时就会产生一个脉冲;如果输入端是无效信号就不会输出脉冲。
编号 8是一个脉冲信号,就是产生事件的线路最终的产物,这个脉冲信号可以给其他外设电路使用,比如定时器 TIM、模拟数字转换器 ADC 等等,这样的脉冲信号一般用来触发TIM或者ADC开始转换。
  EXTI是在APB2总线上的。

四、EXTI库函数代码实现
4.1 EXTI初始化结构体
typedef struct {
    uint32_t EXTI_Line;                 // 中断/事件线
    EXTIMode_TypeDef EXTI_Mode;         // EXTI模式
    EXTITrigger_TypeDef EXTI_Trigger;   // 触发类型
    FunctionalState EXTI_LineCmd;       // EXTI使能
} EXTI_InitTypeDef;


4.2 配置
  根据EXIT基本结构框图可知,需要配置RCC、GPIO、AFIO、EXTI、NVIC。

4.2.1 配置RCC
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOx,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);


4.2.2 配置GPIO
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = ;
GPIO_InitStruct.GPIO_Pin = ;
GPIO_InitStruct.GPIO_Speed = ;
GPIO_Init(GPIOA,&GPIO_InitStruct);


4.2.3 配置AFIO
void GPIO_AFIODeInit(void); //清除AFIO外设配置
//配置AFIO事件输出
void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
void GPIO_EventOutputCmd(FunctionalState NewState);
void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);//引脚重映射
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);//配置AFIO的数据选择器,选择中断引脚
void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface); //与以太网相关


GPIO_EXTILineConfig(GPIO_PortSourceGPIOx,GPIO_PinSourcex);
1
4.2.4 配置EXTI
4.2.4.1 EXTI配置相关函数介绍
void EXTI_DeInit(void); //清除EXTI配置
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);//配置EXTI外设
void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);
void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);//软件触发中断
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);//获取状态寄存器标志位
void EXTI_ClearFlag(uint32_t EXTI_Line);//清除状态寄存器标志位
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);//获取状态寄存器中断标志位
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);//清除状态寄存器中断标志位


4.2.4.2 初始化
EXTI_InitTypeDef EXTI_InitStruct;
EXTI_InitStruct.EXTI_Line = EXTI_Linex;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;//EXTI_Mode_Interrupt or EXTI_Mode_Event
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;//EXTI_Trigger_Rising、EXTI_Trigger_Falling、EXTI_Trigger_Rising_Falling
EXTI_Init(&EXTI_InitStruct);


4.2.4 配置NVIC
4.2.4.1 NVIC相关函数介绍
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);//配置中断分组方式,即抢占优先组和响应优先组
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);//NVIC初始化
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);//设置中断向量表
void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);//系统低功耗配置


4.2.4.2 初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd =ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStruct);


4.3 中断函数
void EXTI9_5_IRQHandler(void)  //中断函数名在startup_stm32f10x_md.s文件查看
{
        //中断标志位判断
        if(EXTI_GetFlagStatus(EXTI_Line5) == SET)
        {
                //中断函数功能
               
                //清除标志位
                EXTI_ClearFlag(EXTI_Line5);
        }
};
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/chang020322/article/details/145076759

使用特权

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

本版积分规则

160

主题

4154

帖子

5

粉丝