[应用相关]

STM32L0低功耗设计——STOP_RTC模式的真实功耗

[复制链接]
1425|9
手机看帖
扫描二维码
随时随地手机跟帖
xiaoqizi|  楼主 | 2019-6-13 15:00 | 显示全部楼层 |阅读模式

版权声明:本文为博主原创**,未经博主允许不得转载。 https://blog.csdn.net/qingwufeiyang12346/article/details/80685245

单片机型号:STM32L053R8T6



本例程测试STOP_RTC模式的真实功耗,主程序如下:

int main(void)
{
        while(1)
        {
    HAL_Delay(5000);
                Target.HAL.Rtc.EnterStopRtcMode();
                Target.HAL.SystemClock.SetMode(2);
        }
}









使用特权

评论回复
xiaoqizi|  楼主 | 2019-6-13 15:01 | 显示全部楼层

系统进入主循环后,先进行5秒延时,然后进入低功耗模式,低功耗模式设置的RTC时间为4秒,4秒过后退出低功耗模式,重新进行时钟设置。


    在进入main函数之前,执行了3个操作:时钟设置、低功耗设置和RTC设置,如下面程序:


class CHAL

{

public:

        CSystemClock SystemClock;

        CSystemLowPower SystemLowPower;

        CRtc Rtc;

};



使用特权

评论回复
xiaoqizi|  楼主 | 2019-6-13 15:01 | 显示全部楼层
时钟设置相关程序如下:

void CClock::SetMode(uint8_t mode)
{
        RCC_OscInitTypeDef RCC_OscInitStruct;
        RCC_ClkInitTypeDef RCC_ClkInitStruct;
        RCC_PeriphCLKInitTypeDef PeriphClkInit;
       
        __HAL_RCC_PWR_CLK_ENABLE();
       
        if (mode  == 0)
        {
                //Configure the main internal regulator output voltage
                __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

                //Initializes the CPU, AHB and APB busses clocks
                RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
                RCC_OscInitStruct.HSEState = RCC_HSE_ON;
                RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
                RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
                RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8;
                RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;
                if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
                {
                        Target.ErrorHandler(__FILE__, __LINE__);
                }

                //Initializes the CPU, AHB and APB busses clocks
                RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                                                                                                                |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
                RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
                RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
                RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
                RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

                if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
                {
                        Target.ErrorHandler(__FILE__, __LINE__);
                }

                PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_USART2;
                PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
                PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
                if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
                {
                        Target.ErrorHandler(__FILE__, __LINE__);
                }

                //Configure the Systick interrupt time
                HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

                //Configure the Systick
                HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

                //SysTick_IRQn interrupt configuration
                HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
        }
        else if (mode  == 1)
        {
                //Configure the main internal regulator output voltage
                __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

                //Initializes the CPU, AHB and APB busses clocks
                RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
                RCC_OscInitStruct.HSEState = RCC_HSE_ON;
                RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
                RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
                RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8;
                RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;
                if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
                {
                        Target.ErrorHandler(__FILE__, __LINE__);
                }

                //Initializes the CPU, AHB and APB busses clocks
                RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                                                                                                                |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
                RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
                RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
                RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
                RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

                if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
                {
                        Target.ErrorHandler(__FILE__, __LINE__);
                }

                PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_USART2
                                                                                                                                |RCC_PERIPHCLK_USB;
                PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
                PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
                PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL;
                if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
                {
                        Target.ErrorHandler(__FILE__, __LINE__);
                }

                //Configure the Systick interrupt time
                HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

                //Configure the Systick
                HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

                //SysTick_IRQn interrupt configuration
                HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
        }
        else if (mode == 2)
        {
                //Configure the main internal regulator output voltage
                __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

                //Initializes the CPU, AHB and APB busses clocks
                RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI;
                RCC_OscInitStruct.HSEState = RCC_HSE_ON;
                RCC_OscInitStruct.LSIState = RCC_LSI_ON;
                RCC_OscInitStruct.HSIState = RCC_HSI_ON;
                RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
                RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
                RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8;
                RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;
                RCC_OscInitStruct.HSICalibrationValue = 0x10;                                        //HSIÐÞÕýÖµ
                if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
                {
                        Target.ErrorHandler(__FILE__, __LINE__);
                }

                //Initializes the CPU, AHB and APB busses clocks
                RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
                RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
                RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
                RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
                RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
                if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
                {
                        Target.ErrorHandler(__FILE__, __LINE__);
                }

                PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_USART2|RCC_PERIPHCLK_RTC;
                PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
                PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
                PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
                if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
                {
                        Target.ErrorHandler(__FILE__, __LINE__);
                }

                //Configure the Systick interrupt time
                HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

                //Configure the Systick
                HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

                //SysTick_IRQn interrupt configuration
                HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);               
        }
}


使用特权

评论回复
xiaoqizi|  楼主 | 2019-6-13 15:01 | 显示全部楼层
低功耗设置相关程序如下:

CLowPower::CLowPower(uint8_t mode)
{
        if (mode == 1)
        {
                GPIO_InitTypeDef GPIO_InitStructure;
                HAL_PWREx_EnableUltraLowPower();                                                                                                                    
    HAL_PWREx_EnableFastWakeUp();                                                                                                                              
                __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI);            
               
    __HAL_RCC_GPIOA_CLK_ENABLE();
                __HAL_RCC_GPIOB_CLK_ENABLE();
                __HAL_RCC_GPIOC_CLK_ENABLE();
                __HAL_RCC_GPIOD_CLK_ENABLE();
                __HAL_RCC_GPIOH_CLK_ENABLE();  
                GPIO_InitStructure.Pin = GPIO_PIN_All;
                GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
                GPIO_InitStructure.Pull = GPIO_NOPULL;
                HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
                HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
                HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
                HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
                HAL_GPIO_Init(GPIOH, &GPIO_InitStructure);
                __HAL_RCC_GPIOA_CLK_DISABLE();
                __HAL_RCC_GPIOB_CLK_DISABLE();
                __HAL_RCC_GPIOC_CLK_DISABLE();
                __HAL_RCC_GPIOD_CLK_DISABLE();
                __HAL_RCC_GPIOH_CLK_DISABLE();
        }
}


使用特权

评论回复
xiaoqizi|  楼主 | 2019-6-13 15:02 | 显示全部楼层
RTC设置相关程序如下:

CRtc::CRtc(void)
{
  this->hRTC.Instance = RTC;
        pRTC = &this->hRTC;
        this->hRTC.Init.HourFormat = RTC_HOURFORMAT_24;
        this->hRTC.Init.AsynchPrediv = 124;
        this->hRTC.Init.SynchPrediv = 295;
        this->hRTC.Init.OutPut = RTC_OUTPUT_DISABLE;
        this->hRTC.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;       
        this->hRTC.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
        this->hRTC.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
        if (HAL_RTC_Init(&this->hRTC) != HAL_OK)
        {
                Target.ErrorHandler(__FILE__, __LINE__);
        }                       
}


使用特权

评论回复
xiaoqizi|  楼主 | 2019-6-13 15:03 | 显示全部楼层
  程序运行后,5秒为正常功耗,4秒为低功耗,测得实际功耗2.4uA,手册中指出的STOP_RTC模式为1uA,产生差错的原因在《STM32L0低功耗设计3: Stop模式下的真实功耗》中已经介绍过,2.4uA已经能够满足项目本身的设计了,还算不错。

使用特权

评论回复
观海| | 2019-7-5 09:58 | 显示全部楼层
已经很难得了

使用特权

评论回复
heimaojingzhang| | 2019-7-5 10:04 | 显示全部楼层
硬件上其他外设都没有吗

使用特权

评论回复
keaibukelian| | 2019-7-5 10:30 | 显示全部楼层
要是能有硬件图就更好了

使用特权

评论回复
xiaoqizi|  楼主 | 2019-7-5 11:54 | 显示全部楼层
回头我找找硬件图

使用特权

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

本版积分规则

71

主题

3810

帖子

3

粉丝