历史上的今天
返回首页

历史上的今天

今天是:2024年10月11日(星期五)

正在发生

2021年10月11日 | STM32外部中断(基于STM32F103库函数版本)

2021-10-11 来源:eefocus

说明:本文旨在详细解析STM32的外部中断,以实现按键触发外部中断。其中包含“编程流程”、“程序代码”、“代码解析”、“原理分析”、“小结”五部分。


一、编程流程

要实现STM32外部中断,按照基本流程来讲,初步的想法重点应该是端口配置、中断服务函数,具体可分为四部分:

①初始化GPIO;

②初始化EXTI;

③初始化NVIC;

④配置中断服务函数。


二、程序代码

/** 

  * @brief  GPIO Init structure definition(库已包含)  

  */

typedef struct

{

  uint16_t GPIO_Pin;             /*!< Specifies the GPIO pins to be configured.

                                      This parameter can be any value of @ref GPIO_pins_define */

  GPIOSpeed_TypeDef GPIO_Speed;  /*!< Specifies the speed for the selected pins.

                                      This parameter can be a value of @ref GPIOSpeed_TypeDef */

  GPIOMode_TypeDef GPIO_Mode;    /*!< Specifies the operating mode for the selected pins.

                                      This parameter can be a value of @ref GPIOMode_TypeDef */

}GPIO_InitTypeDef;


/** 

  * @brief  EXTI Init Structure definition (库已包含) 

  */


typedef struct

{

  uint32_t EXTI_Line;               /*!< Specifies the EXTI lines to be enabled or disabled.

                                         This parameter can be any combination of @ref EXTI_Lines */

  EXTIMode_TypeDef EXTI_Mode;       /*!< Specifies the mode for the EXTI lines.

                                         This parameter can be a value of @ref EXTIMode_TypeDef */

  EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines.

                                         This parameter can be a value of @ref EXTIMode_TypeDef */

  FunctionalState EXTI_LineCmd;     /*!< Specifies the new state of the selected EXTI lines.

                                         This parameter can be set either to ENABLE or DISABLE */ 

}EXTI_InitTypeDef;


/**

  *@brief   NVIC_Configuration实现NVIC配置

  *

  */

static void NVIC_Configuration()

{

    NVIC_InitTypeDef NVIC_InitStructure;


    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);           //配置NVIC优先级分组为1


    NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;        //中断源:[9:5],位于“stm32f10x.h”中

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级:1

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;        //子优先级:1

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           //使能中断通道

    NVIC_Init(&NVIC_InitStructure);

}

/** 

  * @brief  KEY_Configuration按键配置 

  */

void KEY_Configuration()

{

    GPIO_InitTypeDef GPIO_InitStructure;                      //定义GPIO_InitTypeDef结构体


    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB |

                            RCC_APB2Periph_AFIO, ENABLE);     //开启GPIOB和复用功能时钟                   

    GPIO_DeInit(GPIOB);                                       //将外设GPIOB寄存器重设为缺省值(强制或释放APB2外设复位)

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;                 //选择GPIO_Pin_8

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;             //选择上拉输入模式

    GPIO_Init(GPIOB, &GPIO_InitStructure);                    //初始化以上参数

}

/** 

  * @brief  EXTI_Configuration配置EXTI

  */

void EXTI_Configuration()

{

    KEY_Configuration();


    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource8); //选择EXTI信号源


    EXTI_InitTypeDef EXTI_InitStructure;                                                                                            

    EXTI_InitStructure.EXTI_Line = EXTI_Line8;               //中断线选择

    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;      //EXTI为中断模式

    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  //下降沿触发

    EXTI_InitStructure.EXTI_LineCmd = ENABLE;                //使能中断

    EXTI_Init(&EXTI_InitStructure); 


    NVIC_Configuration();                                     //配置NVIC中断                                                                                    

}

/** 

  * @brief  中断服务函数

  */

void EXTI9_5_IRQHandler(void)                       //EXTI_Line:9...5

{

  if(EXTI_GetITStatus(EXTI_Line8)!= RESET)  

  {  

    EXTI_ClearITPendingBit(EXTI_Line8);

    if(ledstate == 0)

    {

        ledstate = 1;   //标志位

        LEDON;          //LED开启

    }

    else if(ledstate == 1)

    {

        ledstate = 0;  //标志位

        LEDOFF;        //LED关闭

    }

  }   

}


备注:届时只需要在主函数中调用EXTI_Configuration();函数即可。


三、代码解析

1、初始化GPIO:

①开启GPIOX时钟和复用时钟:


RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);


②初始化GPIO模式和对应管脚:


GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;                 //选择GPIO_Pin_8

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;             //选择上拉输入模式

GPIO_Init(GPIOB, &GPIO_InitStructure);                    //初始化以上参数


2、初始化EXTI:

①选择EXTI信号源:


GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource8);


②确定中断线、中断模式、触发方式并使能:


EXTI_InitTypeDef EXTI_InitStructure;                                                                                            

EXTI_InitStructure.EXTI_Line = EXTI_Line8;               //中断线选择

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;      //EXTI为中断模式

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  //下降沿触发

EXTI_InitStructure.EXTI_LineCmd = ENABLE;                //使能中断

EXTI_Init(&EXTI_InitStructure); 


3、初始化NVIC:

①配置NVIC优先级分组:


NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);


②确定中断源、优先级(抢占优先级和子优先级),使能:


NVIC_InitTypeDef NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;        //中断源:[9:5],位于

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级:1

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;        //子优先级:1

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           //使能中断通道

NVIC_Init(&NVIC_InitStructure);


4、配置中断服务函数:

①判断是否进入中断:


 if(EXTI_GetITStatus(EXTI_Line8)!= RESET)

 {


 }


②中断行为处理:


if(ledstate == 0)

{

    ledstate = 1;   //标志位

    LEDON;          //LED开启

}

else if(ledstate == 1)

{

    ledstate = 0;  //标志位

    LEDOFF;        //LED关闭

}


③清位:


EXTI_ClearITPendingBit(EXTI_Line8);


四、原理分析

1、RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);函数:(从代码库和固件库手册两方面来看)


首先,库里面是这样定义的:


/**

  * @brief  Enables or disables the High Speed APB (APB2) peripheral clock.

  * @param  RCC_APB2Periph: specifies the APB2 peripheral to gates its clock.

  *   This parameter can be any combination of the following values:

  *     @arg RCC_APB2Periph_AFIO, RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB,

  *          RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE,

  *          RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG, RCC_APB2Periph_ADC1,

  *          RCC_APB2Periph_ADC2, RCC_APB2Periph_TIM1, RCC_APB2Periph_SPI1,

  *          RCC_APB2Periph_TIM8, RCC_APB2Periph_USART1, RCC_APB2Periph_ADC3,

  *          RCC_APB2Periph_TIM15, RCC_APB2Periph_TIM16, RCC_APB2Periph_TIM17,

推荐阅读

史海拾趣

ELPIDA公司的发展小趣事

ELPIDA公司成立于1999年,是日本在DRAM(动态随机存取存储器)领域的重要企业。它的成立是对当时日本半导体产业的一次重要整合,由NEC、日立、三菱电机等公司的DRAM业务合并而成。这一举措旨在振兴日本在DRAM领域的竞争力,并保护国内DRAM产业。

DB Unlimited公司的发展小趣事

在音频市场日益竞争激烈的环境下,DB Unlimited意识到定制化服务的重要性。因此,公司开始提供定制设计服务,以满足客户对特定音频需求的个性化要求。通过与客户的紧密合作和深入沟通,DB Unlimited成功为客户解决了许多复杂的声学设计问题,赢得了客户的信任和赞誉。

Fortiming Corporation公司的发展小趣事

背景:随着电子技术的快速发展,客户对频率控制产品的要求越来越高。

发展:Fortiming不断投入研发资源,进行技术创新和产品升级。公司成功开发出了一系列高精度、高稳定性的晶振产品,满足了市场对高品质频率控制产品的需求。同时,Fortiming还积极探索新的应用领域,如通信、汽车电子、物联网等,不断拓展市场边界。

Achronix Semiconductor Corporation公司的发展小趣事

背景:随着电子技术的快速发展,客户对频率控制产品的要求越来越高。

发展:Fortiming不断投入研发资源,进行技术创新和产品升级。公司成功开发出了一系列高精度、高稳定性的晶振产品,满足了市场对高品质频率控制产品的需求。同时,Fortiming还积极探索新的应用领域,如通信、汽车电子、物联网等,不断拓展市场边界。

ENPIRION公司的发展小趣事

ENPIRION公司的成立源于其创始人对于电源管理技术的深刻理解和独到见解。在2001年,该创始人凭借在贝尔实验室的器件及工艺发明,决定在美国创办ENPIRION公司,致力于开发创新的电源管理解决方案。这一决定标志着ENPIRION公司的诞生,也为其后续的快速发展奠定了坚实的基础。

EDO Corp公司的发展小趣事

进入1950年代,Eclipse Magnetics迎来了一次重要的创新。公司决定将磁铁涂上红色,这一独特的红色磁铁迅速在市场上获得了认可。同时,公司还设计了与红色磁铁相配的马蹄形标志,这一标志后来成为Eclipse Magnetics的国际通用标记。随着品牌的国际化,Eclipse Magnetics的产品开始进入全球市场。

问答坊 | AI 解惑

初学PIC单片机

想知道学PIC单片机需要什么软件? 在网上查的是需要: 1、MPLABV8.43(从microchip网站下的) 2、PICC编译器(C语言编译器) 3、PIC单片机单片机烧写器(具体软件暂时没查到)    有精通PIC单片机的高手请给予一下指点,其中第二,第 ...…

查看全部问答>

gogogo

[url=http://www.artgoin.com][/url]爱艺购,艺术的天堂,艺术的宝库,爱好艺术的人都该去看看,获取能找到一件稀世珍宝欧…

查看全部问答>

关于加速计和陀螺仪的测试

各位高手有没有测试过加速计和陀螺仪这两颗的功能阿,三轴加速计有X,Y,Z三个电压输出,都是经过其内部的AD转换后输出的,不知道这三个方向上的电压是怎么变化的,是有加速度的时候变化呢,还是位置改变了变化啊? 陀螺仪有X,Y两个电压输出,也是 ...…

查看全部问答>

关于MTD驱动的问题

很多MTD驱动都有调用simple_map_init()函数来初始化read,write等函数,不知道这个函数的用法,请大虾帮忙讲一讲啊,如果我需要改变这些read,write函数,该怎么办啦?…

查看全部问答>

求职: 请问有没有人需要高级WINCE工程师--限深圳地区!

求职: 请问有没有人需要高级WINCE驱动工程师--限深圳地区! 如有,请如下EMAIL联系 lumit_hu@126.com…

查看全部问答>

英蓓特STM32ARM开发板的初级改造(有图)

上周在研讨会上买了英蓓特的开发板,试了下,感觉有几个地方不爽,所以就自己动手DIY了:1)USB供电问题,必须插2条USB线,可怜我的本本一共才3个,鼠标用了一个,被他全占了,其它USB-232就没法用了;2)板子附带的1602没有接背光,而实际这 ...…

查看全部问答>

關於LMF232H5QD的UART問題

各位高手大家好,小妹我用此板子的UART出了一點問題,大家可以幫幫我嗎? 感激不盡 問題是這樣的,我開啟了八個UART,為了使輸入資料可以做辨識,個別在UART4跟UART5的地方 加了三個#字號跟一個通道編號 例如:UART4是  ###Edata 這樣 ...…

查看全部问答>

今年会出功率放大类的吗?

本帖最后由 paulhyde 于 2014-9-15 03:16 编辑 今年会出功率放大类的吗    …

查看全部问答>

这几天学习SimpliciTI协议栈的小总结合小纠结

SimpliciTI简介: SimpliciTI是TI开发的专门针对其CCxxxx系列无线通信芯片的网络协议。 它支持两种网络拓扑结构:严格的点对点通信和基于星型的网络拓扑结构,在星型连接中Hub点在SimplciTI被称为Access Point,简称AP.(AP就是常说的网关,数据中 ...…

查看全部问答>

TM4C 1294XL

老师给了一块tm4c 1294的launchpad,说让我们自己玩,但之前没接触过arm这些东西,接触过单片机;所以完全不知道怎么开始??这块板子能干嘛我都不知道,该怎么学习??完全处于迷茫状态??望大神相助,指点一二,让我有个方向!!非常感谢! …

查看全部问答>