历史上的今天
今天是:2024年09月10日(星期二)
2018年09月10日 | 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已经能够满足项目本身的设计了,还算不错。
史海拾趣
|
见附件: ◆ 语音为 MP3 格式,音质优美,通用性好,占据容量小,容易制作◆ SD 卡作为存储语音的载体,存储容量大,性能高,安全性高◆ 语音更新十分方便,只需 SD 卡与电脑连接即可.◆ 存储内容按文件夹的形 ...… 查看全部问答> |
|
本帖最后由 jameswangsynnex 于 2015-3-3 19:58 编辑 么叫做虚拟内存呢?有很多朋友会从“虚拟磁盘”、“虚拟光驱”等概念简单推广到内存方面,认为用做内存交换和扩展空间的“磁盘页面文件”就是“虚拟内存”,因为不是内存芯片,却要做内存的用 ...… 查看全部问答> |
|
目前有个棘手的问题,需要控制一台电脑的键盘事件。但是这台电脑不允许安装其他软件,所以采用安装软件方式控制键盘是没办法了,只能通过可编程键盘连接控制电脑和被控制电脑,在控制电脑发送相应键值,以达到被控电脑的相关操作。就是需要数据线( ...… 查看全部问答> |
|
编译的环境是STANDARDSDK_42 Win32(WCE ARMV4I)Release STANDARDSDK_420 Emulator Linking... MFCCE400d.lib(mfcce400d.dll) : fatal error LNK1112: module machine type \'THUMB\' conflicts with target machine type \ ...… 查看全部问答> |
|
如何在ARM处理器上实现如malloc函数的功能 标准库中的malloc函数是不需要提前分配好存储空间的,我测试过,一段代码有没有malloc只跟代码段的大小有关,而跟数据段都没有关系的。 但是在ucos和freeRtos里面,类似于malloc函数的实现,都是提前分 ...… 查看全部问答> |
|
#include<reg51.h>uchar code tab[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}void view() /*七段数码管显示程序 七个管轮流 ...… 查看全部问答> |
|
LM3S811使用心得(一) 仅仅就心得写八百字确实有难度,于是乎把使用的过程加上滥竽充数,希望对大伙有所帮助。 我们的口号延续以往竞赛精神:只要懂C语言就会开发ARM! 内容适合入门级菜鸟,老鸟就别看了,浪费时间。附带代码。   ...… 查看全部问答> |
|
承接嵌入式笔划输入法开发(另外附送数字输入法、英文大小写输入法和符号输入法,与手机的输入法效果完全一模一样),共有触屏型与按键型两种笔划输入法。 有意者可详谈,用旺旺或者QQ:1309563701。 详情可见http://item.taobao.com/item.htm?i ...… 查看全部问答> |




