[应用相关]

STM32F0低功耗设计(转载)

[复制链接]
1475|10
手机看帖
扫描二维码
随时随地手机跟帖
木木guainv|  楼主 | 2019-6-18 13:58 | 显示全部楼层 |阅读模式

项目中需要使单片机STM32F070F6P6进入低功耗模式,本文记录整个过程。

1、STM32F070的低功耗模式:

20181125155559151.jpg


使用特权

评论回复
木木guainv|  楼主 | 2019-6-18 13:59 | 显示全部楼层

2、低功耗模式描述,在项目中希望外部中断予以唤醒,所以三种低功耗模式,都可以使用。

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3Fpbmd3dWZlaXlhbmcxMjM0Ng==,size_16,color_FFFFFF,t_70.jpg


使用特权

评论回复
木木guainv|  楼主 | 2019-6-18 13:59 | 显示全部楼层
3、进入Stop模式的代码如下,实际测得进入Stop模式后,8.0uA。在这里需要注意的是,我选用的单片机STM32F070F6P6,仅有端口A、端口B和端口F。我使用参考例程,没有注意里面的具体写法,增加了端口C和端口D,则一直进入不了Stop模式,网上说需要停止SysTick,这些都是不正确的。只有进入Sleep模式,才需停止SysTick,在Stop模式中,不需事先关闭SysTick。程序开始将所有的引脚都设置为GPIO_MODE_ANALOG模式,以节省功耗;后续关闭GPIO时钟,进一步节省功耗;然后调用SetStopModeAwakenPinCallback回调函数,设置外部中断引脚,由于在设置外部中断引脚时,需打开相应的GPIO时钟,在这里为了程序的书写方便,没有关闭GPIO时钟,测试只差0.1uA。

void CTarget::EnterStopMode(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
       
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOF_CLK_ENABLE();

    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Pin = GPIO_PIN_All;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

//  __HAL_RCC_GPIOA_CLK_DISABLE();
//  __HAL_RCC_GPIOB_CLK_DISABLE();
//  __HAL_RCC_GPIOF_CLK_DISABLE();
       
    SetStopModeAwakenPinCallback();

    HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
}


使用特权

评论回复
木木guainv|  楼主 | 2019-6-18 14:39 | 显示全部楼层
4、SetStopModeAwakenPinCallback的定义如下,可以看到只是一个空函数,实际结果在main.cpp完成。

__weak void SetStopModeAwakenPinCallback(void)
{
       
}

使用特权

评论回复
木木guainv|  楼主 | 2019-6-18 14:39 | 显示全部楼层
5、下面是在main.cpp中的SetStopModeAwakenPinCallback函数,其功能是将相应的IO引脚设置为外部中断引脚,传递的具体参数,我们参看STM32CubeMX生成的例程就可以了。

void SetStopModeAwakenPinCallback(void)
{
        Target.HAL.LC.SetExternalInterrupt(EXTI0_1_IRQn);
}


使用特权

评论回复
木木guainv|  楼主 | 2019-6-18 14:39 | 显示全部楼层
6、为了使外部中断生效,还需设置相应的中断处理函数,在stm32f0xx_it.h中加入中断服务处理函数

#ifndef __STM32F0xx_IT_H
#define __STM32F0xx_IT_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "stm32f0xx_hal.h"
#include "main.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */

void NMI_Handler(void);
void HardFault_Handler(void);
void SVC_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void TIM16_IRQHandler(void);
void USART1_IRQHandler(void);
void USART2_IRQHandler(void);
void TIM1_BRK_UP_TRG_COM_IRQHandler(void);
void EXTI0_1_IRQHandler(void);

#ifdef __cplusplus
}
#endif

#endif /* __STM32F0xx_IT_H */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/


使用特权

评论回复
木木guainv|  楼主 | 2019-6-18 14:40 | 显示全部楼层
7、在main.cpp中,完成中断服务处理函数的实现。

void EXTI0_1_IRQHandler(void)
{
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}



使用特权

评论回复
木木guainv|  楼主 | 2019-6-18 14:41 | 显示全部楼层
8、上述设置完成后,就可以在main函数中进行测试了,代码如下,程序很简单,上电后L2闪10次,然后L1闪10次,接着进入Stop模式,当外部唤醒后,程序复位。

for (i = 0; i < 10; i++)
{
    Target.HAL.L2.Turn();
    Target.Delayms(500, FALSE);
}
               
for (i = 0; i < 10; i++)
{
    Target.HAL.L1.Turn();
    Target.Delayms(500, FALSE);
}
               
Target.EnterStopMode();

Target.Restart();

使用特权

评论回复
heimaojingzhang| | 2019-7-9 11:02 | 显示全部楼层
有专用的低功耗型号啊

使用特权

评论回复
wakayi| | 2019-7-9 11:05 | 显示全部楼层
非常感谢楼主分享

使用特权

评论回复
木木guainv|  楼主 | 2019-8-6 12:51 | 显示全部楼层
客气了  举手之劳

使用特权

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

本版积分规则

134

主题

3870

帖子

5

粉丝