STM 32開発ノート29:STM 32 L 0低消費電力設計——STOP_RTCモードの実消費電力
8377 ワード
単片機型番:STM 32 L 053 R 8 T 6
本ルーチンテストSTOP_RTCモードの実際の消費電力は以下の通りである.
システムがメインサイクルに入ると、まず5秒の遅延を行い、その後、低消費電力モードに入り、低消費電力モード設定のRTC時間は4秒、4秒後に低消費電力モードを終了し、クロック設定を再開する.
main関数にアクセスする前に、クロック設定、低消費電力設定、RTC設定の3つの操作を行います.次の手順に従います.
クロック設定に関するプログラムは次のとおりです.
低消費電力設定に関するプログラムは次のとおりです.
RTC設定に関する手順は以下の通りです.
プログラム実行後、5秒が通常消費電力、4秒が低消費電力、実測消費電力2.4 uA、マニュアルに記載のSTOP_RTCモードは1 uAであり、エラーの原因は『STM 32 L 0低消費電力設計3:Stopモードでのリアル消費電力』で紹介されており、2.4 uAはすでにプロジェクト自体の設計を満たすことができ、まあまあです.
オリジナルの文章、転載は出典を明記してください
CSDN:http://blog.csdn.net/qingwufeiyang12346
本ルーチンテストSTOP_RTCモードの実際の消費電力は以下の通りである.
int main(void)
{
while(1)
{
HAL_Delay(5000);
Target.HAL.Rtc.EnterStopRtcMode();
Target.HAL.SystemClock.SetMode(2);
}
}
システムがメインサイクルに入ると、まず5秒の遅延を行い、その後、低消費電力モードに入り、低消費電力モード設定のRTC時間は4秒、4秒後に低消費電力モードを終了し、クロック設定を再開する.
main関数にアクセスする前に、クロック設定、低消費電力設定、RTC設定の3つの操作を行います.次の手順に従います.
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.4 uA、マニュアルに記載のSTOP_RTCモードは1 uAであり、エラーの原因は『STM 32 L 0低消費電力設計3:Stopモードでのリアル消費電力』で紹介されており、2.4 uAはすでにプロジェクト自体の設計を満たすことができ、まあまあです.
オリジナルの文章、転載は出典を明記してください
CSDN:http://blog.csdn.net/qingwufeiyang12346