STM32学习笔记(九) 外部中断,待机模式和事件唤醒

摘要:
学会知识只需要不段的积累和提高,但是如何将知识系统的讲解出来就需要深入的认知和系统的了解。外部中断和事件学习难度并不高,不过涉及到STM32的电源控制部分,还是值得认真了解的,在本文中我将以实际代码为例详细讲解这些内容,希望对每一个阅读者有帮助。根据工作原理图:KEY1~PC4;  KEY2~PB10;KEY3~PC13; KEY4~PA0;其中KEY1,2,3作为外部中断引脚,KEY4作为唤醒引脚,后续会讲解。

学会知识只需要不段的积累和提高,但是如何将知识系统的讲解出来就需要深入的认知和系统的了解。外部中断和事件学习难度并不高,不过涉及到STM32的电源控制部分,还是值得认真了解的,在本文中我将以实际代码为例详细讲解这些内容,希望对每一个阅读者有帮助。

1.外部中断

如果已经学习了SysTick系统时钟滴答实验,掌握了Cortex-M3中断的相关知识,那么外部中断也是比较好理解的,和SysTick中断一样,外部中断也是当有信号触发时,如果中断屏蔽寄存器允许触发,就会产生中断,这时CPU查找中断向量表,找到入口函数,就会正确的执行相关代码,因为外部中断本身就是依托于普通GPIO口的上升沿或者下降沿信号的,所以本例中以按键作为测试外部中断的硬件电路。

根据工作原理图:KEY1 ~PC4;  KEY2 ~PB10;

KEY3 ~PC13;  KEY4 ~PA0;

其中KEY1,2,3作为外部中断引脚,KEY4作为唤醒引脚,后续会讲解。

知晓了工作原理图,下面就要确定其对应的中断线号了,这个在参考手册外部中断/事件线路映像章节中有详细的说明,这里截图部分:

STM32学习笔记(九) 外部中断,待机模式和事件唤醒第1张

从上面可以看出,不同区域的相同位置的管脚共用同一个中断线号,依次类推,上面的四个管脚分别对应的中断线号为EXIT4, EXIT10, EXIT13,EXIT0,在这里还有个注意点:那就是一个中断线号只能反过来对应一个管脚,这就需要设计外部中断硬件电路时不要重复,如PA0和PB0不能同时设计为外部中断。

了解了这些之后,如果熟悉STM32设计流程的话,那么就知道顺序是:

1.外部中断管脚GPIO初始化,代码如下:

/****************************************************************
* function    : EXTI_GPIO_Config
* Description : 外部中断触发对应GPIO口配置
                KEY1 PC4  外部中断4
                KEY2 PB10 外部中断10
                KEY3 PC13 外部中断13
                KEY4 PA0  WAKEUP唤醒事件
* input       : 无
* output      : 无
*****************************************************************/
void EXTI_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB 
                           | RCC_APB2Periph_GPIOC |RCC_APB2Periph_AFIO, ENABLE); 
    GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin =EXTI_KEY1_Pin;
    GPIO_Init(EXTI_KEY1_Port, &GPIO_InitStructure); 
   GPIO_EXTILineConfig(EXTI_KEY1_PortSource, EXTI_KEY1_PinSource);        //将GPIO复用为外部中断触发端口

    GPIO_InitStructure.GPIO_Pin =EXTI_KEY1_Pin;
    GPIO_Init(EXTI_KEY2_Port, &GPIO_InitStructure); 
    GPIO_EXTILineConfig(EXTI_KEY2_PortSource, EXTI_KEY2_PinSource);
    GPIO_InitStructure.GPIO_Pin =EXTI_KEY3_Pin;
    GPIO_Init(EXTI_KEY3_Port, &GPIO_InitStructure); 
   GPIO_EXTILineConfig(EXTI_KEY3_PortSource, EXTI_KEY3_PinSource);
    GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPD;
    GPIO_InitStructure.GPIO_Pin =EXTI_KEY4_Pin;
    GPIO_Init(EXTI_KEY4_Port, &GPIO_InitStructure); 
   GPIO_EXTILineConfig(EXTI_KEY4_PortSource, EXTI_KEY4_PinSource);
}

2.外设EXTI初始化

3.在中断屏蔽寄存器中允许对应中断触发

/****************************************************************
* function    : EXTI_MODE_Config
* Description : 外部中断触发配置及向量表开启对应中断
                其中KEY1作为中断进入_WFE模式
                KEY2和KEY3作为普通中断点亮对应LED灯
                KEY4作为事件用来唤醒CPU
* input       : 无
* output      : 无
*****************************************************************/
void EXTI_MODE_Config(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    EXTI_DeInit();
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;        //外部按键触发中断
   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;    //下降沿触发
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;                  //外部中断使能
    EXTI_InitStructure.EXTI_Line = EXTI_KEY1_Line;             //外部中断线号4
    EXTI_Init(&EXTI_InitStructure);
    EXTI_InitStructure.EXTI_Line = EXTI_KEY2_Line;             //外部中断线号10
    EXTI_Init(&EXTI_InitStructure);
    EXTI_InitStructure.EXTI_Line = EXTI_KEY3_Line;             //外部中断线号13
    EXTI_Init(&EXTI_InitStructure);
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Event;            //外部按键触发事件
    EXTI_InitStructure.EXTI_Line = EXTI_KEY4_Line;             //外部中断线号0
    EXTI_Init(&EXTI_InitStructure);
    //PWR_WakeUpPinCmd(ENABLE);                                //PA0作为唤醒引脚使能

    NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);               //向量表位于FLASH中,偏移0
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    /*在向量表中激活对应的中断线号*/
    NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannel =EXTI_KEY1_IRQn;                  
    NVIC_Init(&NVIC_InitStructure);
//NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
//NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
//NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;                  
//NVIC_Init(&NVIC_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannel =EXTI_KEY2_3_IRQn;          
    NVIC_Init(&NVIC_InitStructure);
}

4.中断函数处理

按键PC4对应外部中断入口,因为按键默认高电平,当有按键按下时,就会产生下降沿信号,触发中断,此时CPU就在中断向量表里查询外部中断的入口地址,如PC4对应的入口地址就是void EXTI4_IRQHandler(void) ,开始执行中断中内容,具体实现流程可参考SysTick章节。

/****************************************************************
* function       : EXTI4_IRQHandler
* Description    : 外部中断4入口函数,实现LED点亮以及系统进入_WFE模式
* input          : 无
* output         : 无
*****************************************************************/
void EXTI4_IRQHandler(void)        
{
    led_light_up(0);
    EXTI_ClearFlag(EXTI_Line4);                                      //清除中断线号4
    PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFE);    //进入WFE停止低功耗模式 仅事件能唤醒
    SystemInit();                                                    //退出STOP模式要初始化时钟,因为睡眠时切换到内部时钟
LED1_OFF();
}

在stm32的头文件和启动文件设计中,中断线号10~15共用相同的入口函数,因此需要在中断中进行判断,来确定是那个信号触发了中断。

/****************************************************************
* function       : EXTI15_10_IRQHandler
* Description    : 外部中断10和13共用中断入口,通过触发后状态检查确定
                   触发中断的管脚并执行相应代码。
* input          : 无
* output         : 无
*****************************************************************/
void EXTI15_10_IRQHandler(void)   
{
   ITStatus EXTI10_Status;
   ITStatus EXTI13_Status;
   EXTI10_Status = EXTI_GetITStatus(EXTI_Line10);    //获得外部中断10的状态
   EXTI13_Status =EXTI_GetITStatus(EXTI_Line13);     //获得外部中断13的状态
if(EXTI10_Status == SET) 
{
led_light_up(1);
}
if(EXTI13_Status == SET)
{
led_light_up(2);
}
EXTI_ClearFlag(EXTI_Line10 | EXTI_Line13); /*清除外部中断10或者13的挂起位 */
}

外部中断涉及到的知识并并不多,不过仔细观察上面的代码,就会发现KEY4(PA0)并没有配置为中断,而配置为了事件,且被设置为唤醒引脚,KEY1(PC4)在中断里不只点亮了LED,还调用了PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFE); 这种功能其实很有用,涉及到低功耗和外部事件唤醒,下面我来详细说明。

2.外部事件和中断的区别和联系

外部事件和中断都是由管脚信号触发的,参考下图:

STM32学习笔记(九) 外部中断,待机模式和事件唤醒第2张

这张图可以很直观的看出中断和事件的区别,当外部有信号输入时,如果通过了事件屏蔽寄存器,那么事件信号就进入脉冲触发器,引发一个脉冲信号,直接传递给相应的外设,用于触发,这就是一个纯硬件的过程,理解DMA的应该知道,这个方式不需要CPU参与,但是这也有它的缺点,如功能比较单一,仅能提供信号,不能提供信息,也就是只能产生指定功能的事件。如果通过中断屏蔽寄存器,就被直接送到CPU中,产生中断,如进入上面的入口函数开始处理。从这就可看出,事件是单纯硬件触发执行的过程,与CPU本身设计支持有关,而中断中则可以软件实现各种功能,而低功耗模式和事件唤醒就是stm32支持的事件之一。

3.低功耗模式和事件唤醒

低功耗模式是嵌入式设计用于可移动设备的重要功能,在这种状态下,CPU会关闭时钟,从而降低耗电,延长单次使用时间。

STM32学习笔记(九) 外部中断,待机模式和事件唤醒第3张

上面进入的就是停机-低功耗-WFE模式,因此只能由按键4事件唤醒。其实低功耗模式还有待机模式以及睡眠模式,这里并没有使用到,以后如果用到会穿插讲解。中断无法唤醒,另外,当CPU退出停止模式时,会强制切换到内部时钟,因此在进入停止模式后一句要加上SystemInit()重新配置系统时钟,避免时钟改变。具体代码参考:http://files.cnblogs.com/files/zc110747/7.EXTI_LED.7z

免责声明:文章转载自《STM32学习笔记(九) 外部中断,待机模式和事件唤醒》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Oracle 数据类型本地快速搭建MarkDown语法网站下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

高通Android Camera Bring up

高通Android Camera的移植 注:此文档以在高通8916平台移植OV5648为例,给大家讲解Android SOC的底层Camera。 Reference: https://blog.csdn.net/weijory/article/details/53811140 https://www.jianshu.com/p/70bdb79e5026...

(stm32f103学习总结)—ADC模数转换实验

一、STM32F1 ADC介绍  TM32F103 系列一般都有 3 个 ADC,这些 ADC 可以独立使用,也可 以使用双重(提高采样率)。STM32F1 的 ADC 是 12 位逐次 逼近型的模拟数字转换器。它具有多达 18个复用通道,可测量来自16 个外部源、2 个内部源信号。 这些通道的 A/D 转换可 以单次、连续、扫描或间断模式执行。ADC 的...

u-boot核心初始化

异常向量表:异常:因为内部或者外部的一些事件,导致处理器停下正在处理的工作,转而去处理这些发生的事件。ARM Architecture Reference Manual p54页。7种异常的类型:Reset异常:突然按下重启键。Undefined Instruction:未定义指令。()software interrup:软中断()Prefetch Abo...

[加密]非对称加密STM32实现

转自:https://blog.csdn.net/kangerdong/article/details/82432701 把所有的准备工作都做完了以后,可以将加密算法移植到我们具体的项目中去了,在STM32中在出厂前已经将RSA的公钥私钥,CA数字签名和CA公钥烧写在STM32的flash上了。 4.1 身份认证 在wifi连接上服务器上后,客户端首先发...

十天学会单片机Day1点亮数码管(数码管、外部中断、定时器中断)

1.引脚定义 P3口各引脚第二功能定义 标号 引脚 第二功能 说明 P3.0 10 RXD 串行输入口 P3.1 11 TXD 串行输出口 P3.2 12 INT0(上划线) 外部中断0 P3.3 13 INT1(上划线) 外部中断1 P3.4 14 T0 定时器/计数器0 外部输入端 P3.5 15 T1 定时器/计数器1...

一、STM32简介、选型及其目标

STM32简介 STM32系列是由意法半导体公司推出的ARM Cortex-M内核单片机,从字面上来看,ST为意法半导体公司的缩写,M是Microcontrollers即单片机的缩写,32代表32位 芯片系列 STM32系列芯片分类 STM32后缀的型号说明 模块准备 STM8S103F3P6 STM8S芯片,20引脚,8KB闪存,TSSOP封装,工...