[nrf51][nrf52][SDK17] NRF系列怎么实现低功耗运行,带freertos能进入吗?

发布者:自由梦想最新更新时间:2022-08-19 来源: csdn关键字:nrf51  nrf52  freertos 手机看文章 扫描二维码
随时随地手机看文章

一、NRF51/NRF52系统低功耗表

(浅睡)

image.png

(深睡,唤醒就复位重启)

image.png

二、实测产品没有达到低功耗怎么办?

测量有100uA,这个时候需要检查[调试器]是否断开,需要掉电一次,再测量。

测量有几百uA,这一定是外设没有关闭。如下列表:

image.png

引用官方手册:


System ON模式,就是CPU可以不工作而外设可以继续工作的一种低功耗模式。

idle模式下,当CPU和所有外设都不工作时,系统电流也就有2uA左右。

(注:除了idle模式,nRF5芯片还支持一种更低功耗的低功耗模式:sleep模式(Nordic芯片手册称为System OFF模式),sleep模式下,CPU和所有外设都强制关闭,所以功耗非常低:只有零点几微安。由于sleep模式下,芯片无法发出广播包或者与手机保持蓝牙连接,所以sleep模式在BLE应用中运用得并不是很多)。

Idle模式可以被任何中断唤醒(sleep模式只能被IO口唤醒),所以idle模式在实际应用中使用得比较多。

在idle模式下,芯片仍然可以正常发出广播或者与手机保持蓝牙连接,所以大部分BLE应用都是工作在idle模式下,这样既保持了BLE功能又可以实现低功耗。


三、如何进入低功耗?

1. 软件部分优化

1.1 广播优化

1.1.1 发射功率

设置发射功率具有 9 个发射等级。系统默认的发射功率是 0dbm,发射功率越大,发射距离就越远,相应的电流消耗就越大。

在0dBm时,打开DC/DC, nRF52832发射电流5.3mA。将TX功率增加到+4dBm只增加2.2mA。减少到- 40dbm只节省2.6mA。


1.1.2 广播间隔

就是广播包发出的频率,广播间隔越长,功耗越低。


1.1.3 广播负载

蓝牙的广播包普通包长度在 31 字节,扫描响应包也有 31 字节。如果蓝牙 5.0 下的第二广播包长度更长,越长的广播负载,会造成越大的电流消耗。


1.2 连接状态优化

1.2.1 连接间隔和从机潜伏周期

连接间隔是保证主从机维持连接,相互发空包的时间间隔。连接间隔可以在 GAP 初始化中进行设置。当设置的连接间隔越长,设备的功耗越低。因此,可以在维持连接状态下,保证数据正常通信的基础下,设置尽可能长的连接间隔。


从机潜伏周期和连接间隔是同时进行配置的,从机潜伏周期允许蓝牙设备一定次数的周期不对蓝牙主机数据进行回复。在这个周期次数范围内,蓝牙主机即使没有收到蓝牙从机设备的回复确认信息包,也会认为设备正常。这种方式也可以降低蓝牙设备的功耗。


连接间隔是保证主从机维持连接,相互发空包的时间间隔。连接间隔可以在 GAP 初始化中进行设置。当设置的连接间隔越长,设备的功耗越低。因此,可以在维持连接状态下,保证数据正常通信的基础下,设置尽可能长的连接间隔。


从机潜伏周期和连接间隔是同时进行配置的,从机潜伏周期允许蓝牙设备一定次数的周期不对蓝牙主机数据进行回复。在这个周期次数范围内,蓝牙主机即使没有收到蓝牙从机设备的回复确认信息包,也会认为设备正常。这种方式也可以降低蓝牙设备的功耗。


确认理论功耗值。BLE功耗跟广播间隔或者连接间隔是成正比关系的,所以20ms连接间隔下的功耗几乎是1s状态下的50倍!,单纯地问“1mA功耗高不高?”是没有意义的,必须结合特定的应用场景才有意义。


不管是广播还是连接,特定的使用场景会有一个理论功耗值,NRF功耗网址,以获得你的使用场景下理论功耗多少,比如连接模式下,每1秒钟发20个字节的数据包,这种模式下理论功耗为:7.6uA


1.2.2 发射和接收的数据量

蓝牙数据发送和接收的数据量大小,直观的影响到了功耗。数据吞吐量越大,功耗越高。


1.3 系统及外设功耗优化

1.3.1 协议栈时钟选择

协议栈时钟可以选择外部低速时钟和内部低速时钟。选取外部低速时钟具有更低的功耗,使能外部 32kHz 晶振,通常可以节省 1-2% 的电能。默认使用外部低速晶振。在 main.c 文件,ble_stack_init() 函数中 nrf_sdh_enable_request() 找到


nrf_clock_lf_cfg_t const clock_lf_cfg =

    {

        .source       = NRF_SDH_CLOCK_LF_SRC, // <0=> NRF_CLOCK_LF_SRC_RC      // 内部时钟源

          // <1=> NRF_CLOCK_LF_SRC_XTAL    // 外部晶振源

          // <2=> NRF_CLOCK_LF_SRC_SYNTH   // 合成时钟源

        .rc_ctiv      = NRF_SDH_CLOCK_LF_RC_CTIV,

        .rc_temp_ctiv = NRF_SDH_CLOCK_LF_RC_TEMP_CTIV,

        .accuracy     = NRF_SDH_CLOCK_LF_ACCURACY

    };


sdk_config.h


#ifndef NRF_SDH_CLOCK_LF_SRC

#define NRF_SDH_CLOCK_LF_SRC 1

#endif


[nrf51][nrf52][S130][SDK12.3] 修改协议栈时钟


1.3.2 关闭日志打印

在这里插入图片描述

裸机情况下,除非jlink调试器已连接,否则 RTT 不会使用电流。

os(freertos)情况:


单独开一个线程刷log,功能大约在2.2uA和40uA跳动。

将log放在空闲线程中刷新,功耗大约在11uA。

空闲线程每1000个滴答,刷新一次,功耗大约在3uA。(失去实时性)

void sys_sleep(void)

{

#ifdef SOFTDEVICE_PRESENT

#if NRF51

    sd_app_evt_wait();

#else

nrf_pwr_mgmt_run();

#endif

#else

    // Wait for an event.

    __WFE();

    // Clear the internal event register.

    __SEV();

    __WFE();

#endif

}


/**

 * @brief  线程空闲处理函数

 */

void idle_state_handle(void)

{

static uint16_t tick = 0;

tick ++;

    if (get_ble_conn_state())

    {

        ble_data_send_dispose();

        tick = 0;

    }


   if (get_ble_is_bus())

   {

       return;

   }

   if (tick > 1000)

   {

   // 刷新RTT LOG缓存区

   if (NRF_LOG_PROCESS() == false)

   {

    sys_sleep();

   }

   }

}


/**

 * @brief  [弱函数] 线程空闲

 * @param  *argument: NULL

 */

void vApplicationIdleHook(void)

{

    idle_state_handle();

}


1.3.3 动态使用UART


首先 UART 模块本身只需要 55uA 的工作电流,同时会自动打开高频时钟电路,也需要消耗 250uA 左右电流。如果使能了 UARTE 的 EasyDMA,那么 DMA 还需要消耗额外的 2mA 电流。这样 UARTE 工作消耗的电流会很高。因此在 UART 没有数据传输的时候建议将 UART 关掉,以节省功耗。


注:为了达到低功耗和实时性双重目的,在设计 UART 通信的时候,我们经常会额外再加 2 个 GPIO 口用来通知对方 UART要传送数据了。


关闭 UART 的 API 为:nrf_drv_uart_uninit() 或者 app_uart_close()。


如果只是单向发送,无需接收,可以采用队列的形式,当队列空闲1000滴答,则关闭串口。队列不为空,则初始化串口,开始发送。

[单片机框架] [queue] 实现一个简易的消息队列


void idle_state_handle(void)

{

static uint16_t tick = 0;

tick ++;

    if (get_ble_conn_state())

    {

        ble_data_send_dispose();

        tick = 0;

    }


   if (get_ble_is_bus())

   {

       return;

   }

if (queue_de(&m_urat_send_q, g_uart_send_data))

{

tick = 0;

bsp_uart_init(BSP_UART_0);

bsp_uart_send_nbyte(BSP_UART_0, g_uart_send_data);

return;

}

        

   if (tick > 1000)

   {

       bsp_uart_deinit(BSP_UART_0); // 内置标志位,不会每次都操作关闭

   // 刷新RTT LOG缓存区

   if (NRF_LOG_PROCESS() == false)

   {

    sys_sleep();

   }

   }

}


1.3.4 动态使用SPI/TWI

在不使用的时候建议采用 uninit 函数进行关闭,这部分的外设也消耗电流。需要使用的时候进行 init 初始化开启。


SPI 开启和关闭:nrf_drv_spi_init 和 nrf_drv_spi_uninit

TWI 开启和关闭:nrf_drv_twi_enable 和 nrf_drv_twi_disable


1.3.5 动态使用SAADC


在不使用的时候建议采用 uninit 函数进行关闭,需要使用的时候进行 init 初始化开启。


ADC 开启和关闭:nrfx_saadc_init 和 nrfx_saadc_uninit

如果你发现 uninit ADC 后,功耗还是很高,建议打开这个宏 NRFX_SAADC_CONFIG_LP_MODE,再试一下,功耗有可能就降下来了。

在这里插入图片描述

1.3.5 建议使用GPIOE低精度模式

GPIOE 事件模式下具有两钟模式:高精度模式(hi_accuracy 为 true)和低精度模式(hi_accuracy 为 false)。高精度模式 IN event 中断比低精度模式 Port event 中断消耗更多的电流 10~20uA。如果只是检测 IO 口电平,建议使用低精度模式,也就是所有的输入信号都使用一个中断申请,库函数调用配置:

GPIOTE_CONFIG_IN_SENSE_HITOLO(false);


1.3.5 Timer–>不建议使用硬件定时器


Timer0/1/2/3/4。Timer 的工作电流大概为 5~50uA 左右(nRF51功耗会更高),对低功耗应用来说,已经非常大了。如果你的定时精度要求不高,而且是毫秒的倍数,那么强烈建议你使用 RTC 来实现定时功能。协议栈下为 app_timer 软件定时器,app_timer 的功耗只有 0.2uA 左右。


1.3.6 FPU


由于 nRF52x 系列处理器不同于 nRF51 系列,其内核为 ARM Cortex M4 处理器。ARM Cortex M4 处理器 带 FPU 浮点运算单元。每当程序要执行浮点运算的时候,内核就会自动把 FPU 打开i。FPU 将消耗 7mA 以上的电流,此种情况下,进入 idle 模式之前必须手动关闭 FPU,手动关闭 FPU 代码如下所示:


/* Clear FPSCR register and clear pending FPU interrupts. This code is base on


         * nRF5x_release_notes.txt in documentation folder. It is necessary part of code when


         * application using power saving mode and after handling FPU errors in polling mode.


*/


__set_FPSCR(__get_FPSCR() & ~(FPU_EXCEPTION_MASK));


(void) __get_FPSCR();


NVIC_ClearPendingIRQ(FPU_IRQn);


在新版本 SDK17 中已经默认添加了


xnRF5_SDK_17.0.2_d674ddecomponentslibrariespwr_mgmtnrf_pwr_mgmt.c

函数:nrf_pwr_mgmt_run()

在这里插入图片描述

1.3.7 nrf_pwr_mgmt_run()函数解析

打开 nrf_pwr_mgmt_run() 函数,BLE 状态下,如果 CPU 处于空闲状态就会进入 sd_app_evt_wait() 函数,这个函数是进入低功耗的关键,是协议栈提供的一个等待事件函数。


void nrf_pwr_mgmt_run(void)

{

    PWR_MGMT_FPU_SLEEP_PREPARE();  // 清除FDU异常,避免FDU中断被挂起

    PWR_MGMT_SLEEP_LOCK_ACQUIRE();  // 锁定临界区

    PWR_MGMT_CPU_USAGE_MONITOR_SECTION_ENTER();  // 用户监视段进入,监听进入低功耗的时间

    PWR_MGMT_DEBUG_PIN_SET();  // 置位仿真引脚


    // Wait for an event.

#ifdef SOFTDEVICE_PRESENT  // 带协议栈状态下

    if (nrf_sdh_is_enabled())  // 如果协议栈被使能

    {

        ret_code_t ret_code = sd_app_evt_wait();  //调用协议栈等待函数

        ASSERT((ret_code == NRF_SUCCESS) || (ret_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED));

        UNUSED_VARIABLE(ret_code);

    }

    else

#endif // SOFTDEVICE_PRESENT  // 否则,不带协议栈状态

    {

        // Wait for an event.

        __WFE();

        // Clear the internal event register.

        __SEV();

        __WFE();

    }


    PWR_MGMT_DEBUG_PIN_CLEAR();  // 清除仿真引脚

    PWR_MGMT_CPU_USAGE_MONITOR_SECTION_EXIT();  // 用户监视段退出

    PWR_MGMT_SLEEP_LOCK_RELEASE();  // 锁定临界区释放

}


1.4 软件进入低功耗需要调用的函数

static void idle_state_handle(void)

{

    if(NRF_LOG_PROCESS() == false)  // 如果调试缓冲区没有更多日志

    {

        nrf_pwr_mgmt_run();

    }

}

int main(void)

{

    ···

    ···

    for(;;)

    {

        idle_state_handle();

    }

}


2. 硬件部分优化

不同的内部稳压器选择,会造成不同的电路消耗。可以通过选择不同的硬件电路配置,来选取下面两种内部稳压器:


内部 LDO 稳压器

内部 DC/DC 稳压器

LDO 是系统默认的稳压器,而 DC/DC 稳压器可用作 LDO 稳压器的替代产品。与使用 LDO 稳压器相比,使用 DC/DC 稳压器具有更低的电流消耗,但 DC/DC 稳压器需要连接外部 LC 滤波器:

在这里插入图片描述

其中关于 DC/DC 稳压器所连接的 外部 LC 滤波器电路上的电感和电容参数,请参看芯片手册 53 节 Reference circuitry 所提供的参考电路。

在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述

由于默认选择的是内部 LDO 稳压器,因此如果需要切换到使用内部 DC/DC 稳压器,还需要在软件上进行配置。

首先需要在主函数 main.c 中,初始化 softDevice 协议栈前,执行 NRF_POWER->DCDCEN=1。

或者在初始化softDevice 协议栈后,执行 sd_power_dcdc_mode_set(1)。


sdk_config.h 配置文件中勾选 NRFX_POWER_ENABLED 使能选项,同时把选项下的 DC/DC 使能选项 NRFX_POWER_CONFIG_DEFAULT_DCDCEN 进行勾选。

在这里插入图片描述

在选取电源电压为 3.0 V ,广播间隔为 500ms,发射功率为 0dbm 的情况下,选择 DC/DC 稳压方式的总平均功耗电流为 20uA,而选择 LDO 稳压方式的总平均电流在 32uA 左右。因此,选择 DC/DC 稳压方式可以大幅度的降低功耗。

在这里插入图片描述

电池寿命预估

已知设备的平均电流消耗和电池的容量,计算电池寿命。以下是不同能量容量电池的电池寿命计算实例:


例1:

设备的平均电流消耗 :20uA

电池容量:220mAh (标准CR2032纽扣电池 )

电池寿命:0.22Ah/0.00002A=11000hours=458days


例2:

设备的平均电流消耗 :100uA

电池容量:220mAh (标准CR2032纽扣电池 )

电池寿命:0.22Ah/0.0001A=2200hours=91days


例3:

设备的平均电流消耗 :100uA

电池容量:1000mAh (标准CR2477纽扣电池 )

电池寿命:1Ah/0.0001A=10000hours=417days

关键字:nrf51  nrf52  freertos 引用地址:[nrf51][nrf52][SDK17] NRF系列怎么实现低功耗运行,带freertos能进入吗?

上一篇:[bsp层][nrf52832][nrf52840][nrf52810][nrf52820][ESB(2.4G)] ESB(2.4G)使用说明
下一篇:[nrf51][nrf52][S130][SDK12.3] 修改协议栈时钟

推荐阅读最新更新时间:2024-11-06 15:24

基于STM32F407的FreeRTOS学习笔记(2)
上一期配置完FreeRTOS的环境后,这一期记录自己关于任务创建的学习过程。 官方的API手册中有这些函数,xTaskCreate和xTaskCreateStatic分别是利用动态方法和静态方法创建任务。(动态和静态的区别之后再研究)vTaskDelete是删除任务,因为freeRTOS的任务内存空间存储在堆区,所以很像C语言的动态内存分配,任务使用和结束我们都应该创建和删除这些任务防止占用过多空间。 xTaskCreate的函数模型如下,参数内容总共有六项:任务函数的函数指针,任务函数的名称,任务函数所需堆栈空间,任务函数的类型,任务函数的优先级,以及任务函数的函数句柄 vTaskDelete的函数模型如下,参数内容为函
[单片机]
基于STM32F407的<font color='red'>FreeRTOS</font>学习笔记(2)
嵌入式开发:如何使用机智云+STM32F407+ESP8266+freeRTOS设计
前言 随着物联网的发展,未来的嵌入式产品必然朝着更加智能化、场景多样化、实时性更高等趋势发展,要处理好这些任务时,一个好的RTOS少不了。对于嵌入式开发者来说,了解和学习一个RTOS也是必要项之一,上手简单、及时性和可靠性高的FreeRTOS是最佳选择,和对开发者友好、物联网开发平台机智云配合,刚好满足了我对智能化开发的需求。 下面,我将从基础入手,来讲讲使用机智云+STM32F407+ESP8266+freeRTOS的设计,分别定义了GPIO输入输出,PWM输入输出。(本文由机智云开发者发表于CSDN,ID号:霁雪寒霄) 01 WiFi模块烧录GAgent 1.1 在机智云官网上下载固件,下载好的固件如图1-1所示。 1
[单片机]
嵌入式开发:如何使用机智云+STM32F407+ESP8266+<font color='red'>freeRTOS</font>设计
STM32CubeMX FreeRTOS软件定时器实验
系统:linux mint xfce 64bit 软件: 1、SW4STM32 2、STM32CubeMX 关于这两个软件在linux的安装教程请看我另一篇博文 Linux/Windows配置stm32免费开发环境详细流程 sw4stm32比较难下载,在此提供百度网盘链接: 链接:https://pan.baidu.com/s/1nxgh1VF 密码:rvzu 3、开发板:STM32F407VET6核心 FreeRTOS软件定时器特点: (1)是RTOS的一个组件 (2)可以用来扩展STM32的定时器 (3)不是很精确,但可以用作处理循环事件或者延时事件 (4)两种模式,periodic和one puls
[单片机]
STM32CubeMX <font color='red'>FreeRTOS</font>软件定时器实验
FreeRTOS移植到STM32F103
1.创建工程 2.将FreeRTOS源码,拷贝到工程目录 3.删除其它架构和编译器的代码 查看portable文件夹发现 MemMang为内存管理相关文件需要保留 Commom里面有个mpu相关代码,我们不使用mpu,可以删除 我们的开发环境是keil,打开keil文件夹,提示我们参照RVDS,因此保留RVDS,其它删除 打开RVDS文件夹 STM32F103的内核为CORTEX-M3,删除其它架构相关文件 4.将FreeRTOS文件添加进工程 添加好之后,编译出现错误,缺少FreeRTOSConfig.h文件 5.添加配置文件
[单片机]
<font color='red'>FreeRTOS</font>移植到STM32F103
Nordic第二届全球技术巡展介绍nRF52 SoC系列
培训研讨会将于10月至12月在美国、欧洲和亚太地区举办,软件开发人员可与Nordic nRF52系列开发人员亲身会面,使用具有突破性性能的系统级芯片开展下一个蓝牙智能或ANT+应用项目 超低功耗 (Ultra low power, ULP) 射频 (RF)专业厂商Nordic Semiconductor ASA (OSE: NOD) 宣布第二次举办备受欢迎的全球技术巡展。于2012年成功举办的首次技术巡展涵盖nRF51系列系统级芯片 (SoC),今年的技术巡展将会向嵌入式应用开发工程师介绍功能强大的蓝牙智能(Bluetooth Smart)/ANT /2.4GHz ULP无线连接解决方案nRF52系列SoC,该器件于20
[嵌入式]
AVR开发 Arduino方法(七) 嵌入式操作系统FreeRTOS
FreeRTOS可以提供任务管理,队列管理,中断管理,资源管理和内存管理等功能,由于占用资源少,它可以运行在Arduino UNO R3开发板上。 你可以在 https://github.com/greiman/FreeRTOS-Arduino 上下载到它,将下载到的FreeRTOS-Arduino-master.zip解压,并将/FreeRTOS-Arduino-master/libraries文件夹下的内容全部复制到Arduino IDE安装目录下的libraries文件夹里就可以使用了。下面是它提供的frBlink示例: 1 // frBlink.ino 2 #include FreeRTOS_AVR.h 3
[单片机]
基于STM32的FreeRTOS应用问题解答
1、如何将 FreeRTOS 移植 到不同的Cortex-M 内核? 答:如果要将 FreeRTOS 移植到正确的Cortex-M 产品,你必须从正确的目录导入 port.c 文件。例如,若微控制器是带有IAR 工具的 Cortex-M0 内核,则您必须从 FreeRTOS\Source\portable\IAR\ARM_CM0 获取 port.c。 2、 FreeRTOS 使用需要ROM/RAM? 答:这取决于您的编译器、代码架构,以及RTOS 内核配置。一般来说, RTOS 内核本身需要大约 5到 10 K 字节 ROM 空间。 如果创建的线程或队列数增加,RAM 使用量就会上升。 3、怎样设置 CPU 时钟? 答:C
[单片机]
基于STM32的<font color='red'>FreeRTOS</font>应用问题解答
基于mc35i的m2m终端设计与研究
  引言   目前,对输油管道、电力装置、油井等进行远程监控主要采用人工巡逻的方式,这种方式存在实时性差、成本高、浪费人力资源、无法对环境恶劣的地区进行监控、可能出现误报等缺点。随着工业领域现代化水平的提高和通信技术的发展,这种生产方式亟待得到改善。   m2m是指应用无线移动通信技术,实现机器与机器、机器与人之间数据通信和交流的一系列技术及其组合的总称。GPRS具有覆盖地域广、通信距离远、网络可靠性高等优点。随着GPRS的推广和应用,以及基于GPRS的M2M产品的推出,采用GPRS技术来解决上述问题成为一种较好的方案。   嵌入式系统是当前国内外研究的热点之一。采用嵌入式系统技术设计一种可以解决远程监控领域数据传输问题的通
[工业控制]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved