历史上的今天
返回首页

历史上的今天

今天是:2025年07月16日(星期三)

正在发生

2019年07月16日 | STM32开发笔记29:STM32L0低功耗设计——STOP_RTC模式的真实功耗

2019-07-16 来源:eefocus

单片机型号:STM32L053R8T6


   本例程测试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已经能够满足项目本身的设计了,还算不错。



推荐阅读

史海拾趣

浙江东亚电子(DongYa)公司的发展小趣事

浙江东亚电子自成立以来,一直致力于技术创新和研发。公司拥有一支由50余名技术研发人员组成的专业团队,不断开发新产品和解决方案,以满足市场需求。这些创新产品不仅在国内外市场上获得了广泛认可,还为公司在新能源、通讯和军工等领域树立了良好的品牌形象。

Etron公司的发展小趣事

进入21世纪,电子行业的竞争日益激烈,钰创科技意识到必须不断进行技术创新才能保持竞争优势。公司加大了研发投入,成功开发出了一系列先进的内存芯片和系统芯片技术。这些技术突破不仅提升了产品的性能和质量,也帮助公司赢得了更多国际客户的认可和信任。

EXXELIA Group公司的发展小趣事

面对未来电子行业的发展趋势和挑战,钰创科技始终保持着清醒的认识和前瞻性的思考。公司将继续加大研发投入和人才培养力度,推动技术创新和产业升级;同时加强与国际知名企业的合作与交流,拓展国际市场;并积极响应国家政策和市场需求变化,不断调整和优化产品结构和市场布局;为实现公司的可持续发展和长远目标奠定坚实基础。

请注意,以上故事为虚构内容,旨在展示Etron公司(钰创科技)在电子行业中的发展历程和可能遇到的挑战与机遇。实际情况可能因各种因素而有所不同。

DALLAS公司的发展小趣事

Dallas公司一直将技术研发作为公司发展的核心驱动力。公司投入大量资源用于半导体领域的技术研发,不断探索新的技术方向和产品应用。这种持续的技术研发投入使得Dallas公司能够不断推出具有创新性和竞争力的产品,保持了在市场中的领先地位。

General Diode Corp公司的发展小趣事
用于对焊机内部的电源模块、电磁振动系统等关键部件进行冷却,确保其正常运行。
Helium_Systems__Inc.公司的发展小趣事

在20世纪90年代初,一家名为“海曼电子”(虚构名称,类似HEIMANN发音)的初创公司在德国慕尼黑成立。创始人海曼博士凭借其在半导体材料领域的深厚研究背景,带领团队成功研发出了一种新型高效能传感器芯片。这种芯片在温度测量领域表现出色,迅速获得了市场的认可。随着技术的不断迭代,海曼电子逐渐在传感器市场占据了一席之地,并通过持续的技术创新,将产品线扩展至光电子、汽车电子等多个领域。

问答坊 | AI 解惑

通用同步/异步通信的应用(2)

 单片机双机同步通信 1  单片机PIC1编程(主控发送) #include  <pic.h> /*该程序实现单片机双机同步通信功能,是主控发送部分。程序上电后显示 *相应的字符,表示系统正常工作。发送完毕后显示发送的数据*/ unsigned &nbs ...…

查看全部问答>

LS波段集成锁相频率源设计

    摘要集成锁相源是通信设备至关重要的部件。本文叙述集成锁相源的原理,关健放术及设计过程。并应用MOTOROLA大规模镜相坏集成屯路,采用“脉冲吞食”可变分倾技术设计工另波段锁柏源,达到很好的指标。…

查看全部问答>

APEX芯片大全(pdf)

APEX芯片大全(pdf),包括了APEX公司的大部分芯片手册,以及运放选择资料,相当全,若无芯币,可告知邮箱,资源交换,呵呵…

查看全部问答>

【EEWORLD模块整理】+LED显示

本帖最后由 paulhyde 于 2014-9-15 03:01 编辑 自己弄的led数码管显示的程序,    …

查看全部问答>

半导体公司最稀缺的人才——模拟设计高手

模拟设计工程师短缺的情况正日益恶化,正迫使甚至像飞思卡尔半导体公司这样强大的数字芯片公司加倍努力征募和培养模拟设计工程师,以应对混合信号处理中“魔法艺术”的挑战。 “模拟集成电路设计存在一定的艺术性,”iSuppli公司负责模拟IC和半 ...…

查看全部问答>

IA32如何开启MMU

弱问一个问题  arm开启MMU,需要对MMU进行初始化 那么X86是否也需要这样的一段初始化代码?  我找了后发现只对CR3寄存器进行设置 没有这段初始化代码…

查看全部问答>

关于WinCE下如何采集视频

目前要在基于一套硬件平台来做wince下的视频处理,由于sdk不支持vfw,也不支持dshow的枚举,所以不知道该怎么采集视频信号了。在网上找了两天了,很多人问这个问题,但是没有妥当的解决方案,请知道的弟兄姐妹帮忙,谢谢! …

查看全部问答>

请教:计算机标志码(PCID)一定是由数字而非英文字母组成码?

请教:计算机标志码(PCID)一定是由数字而非英文字母组成码?…

查看全部问答>

红外测温

需要使用红外进行测量温度,不知大家有没有什么好的建议,例如红外热电堆的型号,注意事项,相关帖子? 需要考虑测量速度,做好30~40ms以内,测量范围-20~100摄氏度左右。…

查看全部问答>

如何在装有linux下的ARM9开发板驱动直流电机

最近做一个项目,想实现控制,能够降温,就打算用直流电机来模拟风扇。 我的开发板是tq2440,移植的是linux系统。初步想法是想买一个直流电机,再找到对应的直流电机驱动程序,将驱动程序编译进内核,通过编写程序,open( )设备文件,再write( )的 ...…

查看全部问答>