单片机
返回首页

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

2018-09-10 来源:eefocus

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


int main(void)

{

while(1)

{

    HAL_Delay(5000);

Target.HAL.Rtc.EnterStopRtcMode();

Target.HAL.SystemClock.SetMode(2);

  }

}

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


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


class CHAL

{

public:

CSystemClock SystemClock;

CSystemLowPower SystemLowPower;

CRtc Rtc;

};

    时钟设置相关程序如下:


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);

}

}

    低功耗设置相关程序如下:


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); //½«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();

}

}

    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__);

}

}

    程序运行后,5秒为正常功耗,4秒为低功耗,测得实际功耗2.4uA,手册中指出的STOP_RTC模式为1uA,产生差错的原因在《STM32L0低功耗设计3: Stop模式下的真实功耗》中已经介绍过,2.4uA已经能够满足项目本身的设计了,还算不错。


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 红外线探测报警器

  • 短波AM发射器电路设计图

  • RS-485基础知识:处理空闲总线条件的两种常见方法

  • 如何调制IC555振荡器

  • 基于ICL296的大电流开关稳压器电源电路

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章