[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-16 21:34

FreeRTOS移植——基于stm32f1
准备 在移植之前,我们首先要获取到FreeRTOS的官方的源码包。这里我们提供两个下载链接: 一个是官网:http://www.freertos.org/ 另外一个是代码托管网站:https://sourceforge.net/projects/freertos/files/FreeRTOS/ 这里我们演示如何在代码托管网站里面下载。打开网站链接之后,我们选择FreeRTOS的最新版本V9.0.0(2016年),尽管现在FreeRTOS的版本已经更新到V10.0.1了,但是我们还是选择V9.0.0,因为内核很稳定,并且网上资料很多,因为V10.0.0版本之后是亚马逊收购了FreeRTOS之后才出来的版本,主要添加了一些云端
[单片机]
<font color='red'>FreeRTOS</font>移植——基于stm32f1
stm32 FreeRTOS中如何创建任务
#include config.h #include global.h #include stdio.h #include PC.h #include FreeRTOS.h #include task.h #include list.h void vLED1Task(void *pvParameters) { while(1) { GPIO_Reverse (); vTaskDelay(1000/portTICK_RATE_MS); } } void vLED2Task(void *pvParameters) { portTickType xLastWakeTime; //xLastWakeTi
[单片机]
基于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>应用问题解答
移植freeRTOS V10.2.0到stm32f103zet6
应用FPU 1、工程文件 startup_stm32f40_41xxx.s 新建一个 test.c 文件,并保存在 USER 文件夹下 2、工程文件夹 USER 文件夹专门用来存放启动文件(startup_stm32f40_41xxx.s)、工程文件(test.uvprojx)等不可缺少的文件, OBJ 则用来存放这些编译过程中产生的中间文件(包括.hex 文件也将存放在这个文件夹里面) SYSTEM文件夹,该文件夹由 ALIENTEK 提供,可以在光盘任何一个实例的工程目录下找到 3、工程分组 Target 目录树上点击右键 Manage Project Items 我没改文件夹,还是
[单片机]
移植<font color='red'>freeRTOS</font> V10.2.0到stm32f103zet6
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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