芯查查logo
  • 物料选型
  • 数据服务
    1. 新品推荐
    2. 查替代料
    3. 丝印反查
    4. 查品牌
    5. PCN/PDN
    6. 查代理
    7. 数据合作
  • 应用方案
  • SaaS产品
      SaaS产品
    1. 供应链波动监测预警
    2. 半导体产业链地图
    3. 智能BOM管家
    4. 解决方案
    5. 汽车电子
    6. 政府机构
    7. 数据API
  • 商城
  • 行业资讯
    1. 资讯
    2. 直播
  • 论坛社区
    1. 论坛
    2. 学习
    3. 测评中心
    4. 活动中心
    5. 积分商城
  • 查一下
正在使用账号登录iCEasy商城
从前的电阻Mia
RA4L1-SENSOR(04) 低功耗测评及简易秒表的实现

一、综述


随着物联网终端向电池供电和长续航方向发展,MCU 的待机功耗已成为系统设计的关键指标。本文基于 Renesas RA4L1,对 Sleep、Snooze、Software Standby 三种低功耗模式进行了实验验证,并制作了一个低功耗运行的简易秒表。

下面是三种低功耗模式的简介,参考了FSP用户手册:

1.Sleep Mode|睡眠模式

上电后,默认的低功耗模式即为 Sleep。
该模式使用最方便,不需要额外配置,只需设置可用于唤醒 MCU 的中断或事件,即可在唤醒后回到正常程序执行。在 Sleep 模式中,SRAM、处理器寄存器以及硬件外设的状态都会被保留,进入和退出所需时间极短。任何中断都会使 MCU 从 Sleep 模式唤醒,包括 RTOS 调度器使用的 SysTick 中断。

2.Software Standby Mode|软件待机模式

在 Software Standby 模式下,CPU、片上大多数外设功能以及所有内部振荡器都会停止,但 CPU 寄存器内容、SRAM 数据、外设状态以及 I/O 端口配置都保持不变。由于大多数振荡器停止,该模式可显著降低功耗。与 Sleep 类似,Standby 也必须配置并启用中断或事件才能唤醒。

3.Snooze Mode|贪睡模式

Snooze 模式允许部分 MCU 外设在 MCU 保持低功耗的同时执行基本任务。许多核心外设以及全部时钟都可以选择在 Snooze 中运行,使其相比 Software Standby 拥有更灵活的低功耗配置能力。要启用 Snooze,需要在“Low Power Mode”选项中选择“启用 Snooze 的 Software Standby 模式”。Snooze 的进入/退出条件可在“Standby Options”中配置。

 

三种模式的工作条件及支持的中断源


查硬件手册表10.2得下表,展示了三种不同低功耗模式下可以使用的外设,已经翻译成中文:

表10.2 每种低功耗模式的工作条件

项目 睡眠模式(Sleep mode) 软件待机模式(Software Standby mode) 贪睡模式(Snooze mode)
进入条件 SBYCR.SSBY = 0 时执行 WFI 指令 SBYCR.SSBY = 1 时执行 WFI 指令 在 Software Standby 模式下由 Snooze 请求触发,SNZCR.SNZE = 1
取消方式(退出方式) 所有中断;该模式下可用的任何复位 表 10.3 所示中断;该模式下可用的任何复位 表 10.3 所示中断;该模式下可用的任何复位
中断取消后的状态 程序执行状态(中断处理) 程序执行状态(中断处理) 程序执行状态(中断处理)
复位取消后的状态 复位状态 复位状态 复位状态
主时钟振荡器(Main clock) 可选 停止 可选
子时钟振荡器(Sub-clock) 可选 可选 可选
高速片上振荡器(HOCO) 可选 停止 可选
中速片上振荡器(MOCO) 可选 停止 可选
低速片上振荡器(LOCO) 可选 可选 可选
IWDT 专用振荡器 可选  可选 可选 
PLL 可选 停止 可选 
振荡停止检测功能 可选 禁止操作 禁止操作
子振荡停止检测功能 可选 可选 可选
时钟/蜂鸣器输出功能 可选 停止  可选
CPU 停止(保持寄存器) 停止(保持寄存器) 停止(保持寄存器)
SRAM 可选 停止(保持)  可选
Flash 存储器 运行 停止(保持) 停止(保持)
DMA 控制器(DMAC) 可选 停止(保持) 禁止操作
DTC 数据传输控制器 可选 停止(保持) 可选
USB FS 可选 停止(保持),支持 USB 恢复检测 禁止操作(但可检测 USB 恢复)
WDT 可选  停止(保持) 停止(保持)
IWDT 可选  可选  可选 
RTC 实时时钟 可选 可选 可选
AGT(低功耗定时器) 可选 可选  可选 
12-bit ADC(ADC12) 可选 停止(保持) 可选 (需阈值比较)
DAC 可选 停止(保持) 可选
CTSU 电容触摸 可选 可选 可选
DOC(数据操作电路) 可选 停止(保持) 可选
SCI0(串口) 可选 停止(保持) 可选(仅异步模式,RXD0 下降沿可进入 Snooze)
SCI(1,3,5,9 等) 可选 停止(保持) 禁止操作
UARTA(UARTA0, UARTA1) 可选 可选 可选 
I2C(IICO) 可选 可选 可选(仅支持唤醒中断)
I3C 总线 可选 可选 可选 
ELC(事件链接控制器) 可选 停止(保持) 可选 
模拟比较器(ACMPLP) 可选 可选  可选
SLCDC 段式 LCD 驱动 可选 停止(保持) 可选 
外部中断 IRQ 可选 可选 可选
NMI 可选 可选 可选
LVD(低电压检测) 可选 可选 可选
上电复位电路 POR 运行 运行 运行
其他外设模块 可选 停止(保持) 禁止操作
I/O 端口 运行 保持 运行

表 10.3 退出 Snooze / Software Standby 模式的中断源

中断源名称

Software Standby 模式

Snooze 模式

NMI

是

是

端口中断 PORT_IRQn(n = 0~15)

是

是

LVD(低电压检测)

LVD_LVD1

是

是

LVD_LVD2

是

是

IWDT

IWDT_NMIUNDF(下溢 NMI)

是

是

USBFS

USBFS0_USBR

是

是

RTC 实时时钟

RTC_ALM(闹钟中断)

是

是

RTC_PRD(周期中断)

是

是

UARTA

UARTA0_INTUR

是

是

UARTA0_INTURE

是

是

UARTA1_INTUR

是

是

UARTA1_INTURE

是

是

SOSC(子时钟)

SOSC_STOP(停止中断)

是

是

I3C

I3C_WU(唤醒中断)

是

是

AGT1

AGT1_AGTI

是

是 

AGT1_AGTCMAI

是

是

AGT1_AGTCMBI

是

是

ACMPLP(低功耗模拟比较器)

ACMP_LP0

是

是

IIC0

IIC0_WUI

是

是

ADC12n(n=0)

ADC12n_WCMPM(窗口比较中断:进入窗口)

否

是(需 SELSR0 )

ADC12n_WCMPUM(窗口比较中断:超出窗口)

否

是(需 SELSR0 )

SCI0(串口)

SCI0_AM(异步模式唤醒)

否

是(需 SELSR0 )

SCI0_RXI_OR_ERI

否

是(需 SELSR0 )

DTC

DTC_COMPLETE

否

是(需 SELSR0 )

DOC(数据操作电路)

DOC_DOPCI

否

是(需 SELSR0 )

CTSU 电容触摸

CTSU_CTSUFN

否

是(需 SELSR0 )

DMAC / DTC

DMA_TRANSERR

否

是

ICU(中断控制单元)

ICU_SNZCANCEL

否

是

总而言之,三者的区别简单概括如下:

模式 功耗 唤醒速度 外设运行 典型用途
Sleep 低功耗模式中最高 最快 大部分外设继续运行 CPU 空闲时节能
Snooze 中等 适中 特定外设允许运行,如 ADC/UART 自动检测事件并唤醒
Software Standby 最低功耗 最慢 几乎全部关闭 长时间待机

下面是手册中给出的低功耗系统框图:

 

二、低功耗测试

1.电流测试

按照图示新建低功耗模组:

点击低功耗模组,在Properties里面修改低功耗模式,分别有Sleep Mode,Snooze Mode 和 Software Standby Mode。

  fsp_err_t err = R_LPM_Open(&g_lpm0_ctrl, &g_lpm0_cfg);
   /* Handle any errors. */
   assert(FSP_SUCCESS == err);
   R_BSP_SoftwareDelay(1000,BSP_DELAY_UNITS_MILLISECONDS);
   err = R_LPM_LowPowerModeEnter(&g_lpm0_ctrl);
   assert(FSP_SUCCESS == err);

 

下面是没有任何外设下测试的结果,测试的是3V3到GND间的电流,由于板上3V3网络连接的串口芯片、电源芯片等的影响,测试效果可能不够准确:

非低功耗模式下的电流:21.7mA

Sleep模式下的电流:17.0mA

snooze模式下的电流:17.8mA

Software Standby模式下的电流:13.0mA

根据官方介绍,RA4L1 mcu采用专有的低功耗技术,在保留所有SRAM的情况下,可提供168 μ A/MHz的有源模式@ 80 MHz,待机电流仅为1.70 μ A。测试结果差别较大,因为不完全是单纯对芯片的测试,在板上直接测量无法排除其他硬件的干扰。即便如此,测试得到的功耗最低也只有40mW,可见该芯片的功耗之低。


三、做一个具有低功耗特性的小秒表

1.时钟:

内部时钟HOCO和LOCO的精度都不高,如果是对始终精度高、并且不太要求低功耗的应用场合,建议使用外部时钟;在这里,为了满足低功耗的需求,我们直接使用HOCO和LOCO作为时钟源;

  • 禁用外部晶振和锁相环,使用HOCO作为高频时钟;

2.按键外部中断:

开启定时和停止定时的按键,板上按键为P000和P001;

添加外部中断引脚,P000对应通道6,P001对应通道7,二选一即可;

添加中断模组,设置通道和回调函数名称等属性;

  • IRQ6(P000)的配置:

 

  • IRQ7(P001)的配置:

 

3.SLCDC液晶显示屏的配置

具体可以参考我之前写的文章

  • SLCDC模组的配置:

 

SLCDC管脚的配置:

4.AGT低功耗定时器的配置:

注意到Software Standby模式只响应AGT1通道的中断信号,所以我们必须把时钟通道配置为1;

5.低功耗模式配置

配置为Software Standby模式;

配置低功耗模式下的中断源,若不配置会导致无法进入中断;

6.代码实现

LCD的驱动使用我前面实现的查表函数文件,具体查看文章的代码示例4:

这边可以直接复制到文件目录下,新建一个文件夹BSP,同时在Keil中加入此文件和目录:

文件前面包含该头文件:

#include "segment_LCD_4c_disp.h"

变量声明

定义要用到的LCD位数,因为只实现分钟和秒钟,所以只用到前4位;同时声明一个uint8_t类型的数组,用于临时存放要显示的数字:

#define TRANSFER_LENGTH 4
uint8_t num_array[4]={0};

外部中断响应状态标志位,此处按第一下开始计时,状态量值为true,再按一下取反,状态量值为false:

bool g_external_irq_complete = false;

用于计算进入中断次数的变量:

uint16_t Time_Count = 0;

AGT低功耗定时器中断状态标志位:

volatile bool agt_flag = 0;//AGT延时1s标志位

循环用的变量i:

uint8_t i = 0;

定义一个结构体,存放分钟和秒钟:

typedef struct
{
   uint8_t minute;
   uint8_t second;
} time_ms_t;

 

函数定义

用于将定时器计时值转化为分、秒的函数:

time_ms_t convert_time(uint16_t total_seconds)
{
   time_ms_t t;
   t.minute = total_seconds / 60;   // 分钟
   t.second = total_seconds % 60;   // 秒
   return t;
}

用于将定时器计时值转化为显示缓冲区每一位的值的函数,封装了convert_time():

void update_num_array(uint16_t total_seconds)
{
   time_ms_t t = convert_time(total_seconds);
   uint8_t min_tens  = t.minute / 10;
   uint8_t min_ones  = t.minute % 10;
   uint8_t sec_tens  = t.second / 10;
   uint8_t sec_ones  = t.second % 10;
   num_array[0] = min_tens;
   num_array[1] = min_ones;
   num_array[2] = sec_tens;
   num_array[3] = sec_ones;
}

外部中断回调函数,这边根据各自配置的IRQ通道和回调函数编写,IRQ6和IRQ7只需要选一种:

//外部中断回调函数,标志位逻辑不是置1/清零,而是取反:用于主函数中判断,最开始是0,第一次按下的时候是1,当按下第二次的时候取反为0,循环往复,起到一个第一次按下开始计时,第二次按下停止计时、显示数据的效果
void external_irq6_callback (external_irq_callback_args_t * p_args)
{
   (void) p_args;
   g_external_irq_complete = !g_external_irq_complete;
}
void external_irq7_callback (external_irq_callback_args_t * p_args)
{
   (void) p_args;
   g_external_irq_complete = !g_external_irq_complete;
}

AGT回调函数,事件标志是TIMER_EVENT_CYCLE_END,当然此处可不判断,当有多种AGT中断事件时可以加入;

//AGT回调函数
void agt_callback(timer_callback_args_t *p_args)
{
   //AGT定时中断的标志是TIMER_EVENT_CYCLE_END
   if(p_args->event == TIMER_EVENT_CYCLE_END)
       agt_flag=1;
}

 

hal_entry()主函数

主循环前的初始化:

fsp_err_t err;
   //打开外部中断
   err = R_ICU_ExternalIrqOpen(&g_external_irq6_ctrl, &g_external_irq6_cfg);
   assert(FSP_SUCCESS == err);
   err = R_ICU_ExternalIrqOpen(&g_external_irq7_ctrl, &g_external_irq7_cfg);
   assert(FSP_SUCCESS == err);
   err = R_ICU_ExternalIrqEnable(&g_external_irq6_ctrl);
   assert(FSP_SUCCESS == err);
   err = R_ICU_ExternalIrqEnable(&g_external_irq7_ctrl);
   assert(FSP_SUCCESS == err);
   
   //打开AGT
   err = R_AGT_Open(&g_timer1_ctrl, &g_timer1_cfg);
   assert(FSP_SUCCESS == err);  
   err = R_AGT_Enable(&g_timer1_ctrl);
   assert(FSP_SUCCESS == err);
 
   //打开SLCDC
   err = R_SLCDC_Open(&g_slcdc0_ctrl, &g_slcdc0_cfg);
   assert(FSP_SUCCESS == err);
   err = R_SLCDC_Start(&g_slcdc0_ctrl);
   assert(FSP_SUCCESS == err);
   
   //显示全0
    for(i=1;i<=TRANSFER_LENGTH;i++){
       R_SLCDC_Modify(&g_slcdc0_ctrl,get_seg_pos(i)[0],get_seg_num(num_array[i-1])[0],0xFF);
       R_SLCDC_Modify(&g_slcdc0_ctrl,get_seg_pos(i)[1],get_seg_num(num_array[i-1])[1],0xFF);
   }
   
   //打开低功耗模式
   err = R_LPM_Open(&g_lpm0_ctrl, &g_lpm0_cfg);
   assert(FSP_SUCCESS == err);
   //err = R_LPM_LowPowerRecondiv(&g_lpm0_ctrl, &g_lpm0_cfg);
  // assert(FSP_SUCCESS == err);
   err = R_LPM_LowPowerModeEnter(&g_lpm0_ctrl);
   assert(FSP_SUCCESS == err);

主循环:

    while(1){
      if(g_external_irq_complete == true)//判断是否是第一次/奇数次按下,标志位不清零,当按下第二次的时候清零
      {
         if (Time_Count == 0)//判断是否是刚开始按下,还未计时
        {
            err = R_AGT_Start(&g_timer1_ctrl);//打开定时器
            assert(FSP_SUCCESS == err);
        }
        if(agt_flag == 1)//判断是定时器中断
         {
          agt_flag = 0;
          
        //转换Time_Count 并显示
          update_num_array(Time_Count);
          
 for(i=1;i<=TRANSFER_LENGTH;i++)
    {
        R_SLCDC_Modify(&g_slcdc0_ctrl,
                        get_seg_pos(i)[0],
                        get_seg_num(num_array[i-1])[0],
                        0xFF);

        R_SLCDC_Modify(&g_slcdc0_ctrl,
                        get_seg_pos(i)[1],
                        get_seg_num(num_array[i-1])[1],
                        0xFF);
    }
          //显示点并闪烁,一秒钟切换一次
          //也可以把定时值设置为500ms,一秒闪烁一次,其他地方按照相应的逻辑改动
          switch (Time_Count%2){
            case 0:
                R_SLCDC_Modify(&g_slcdc0_ctrl,16,0x00,0x08);
              break;
            case 1:
                R_SLCDC_Modify(&g_slcdc0_ctrl,16,0x08,0x08);
              break;
            }
          Time_Count ++; //增加计数值
        }
      
      }
      
      else{ //第二次/双数次按下,表示停止
        err = R_AGT_Stop(&g_timer1_ctrl); //停止定时器
        assert(FSP_SUCCESS == err);
        R_SLCDC_Modify(&g_slcdc0_ctrl,16,0x08,0x08);
 //显示点
        Time_Count = 0;
      }
      
    err = R_LPM_LowPowerModeEnter(&g_lpm0_ctrl);
    assert(FSP_SUCCESS == err);
      
    }

实验结果:

可以看到板上电流在13.1mA左右,如果不是低功耗模式,电流应该在20mA以上。


⚠问题附录:

Software Standby低功耗模式下的程序下载之后,想要再次下载新的程序,J-Link会报错?

因为Software Standby模式会禁用所有GPIO的功能,所以要再次下载程序,需要把BOOT跳线帽从原本连接3V3改到连接GND,进入BootLoader模式,按下RESET按键重置一下,并使用串口下载。

串口下载需要使用Renesas Flash Programmer :

点击后进入发布页面,下载适合自己系统的压缩包;

安装后打开软件,新建下载工程,工具配置为COM口:

切换到Operation Settings,Command设置为Erase就好,我暂时只用串口方式来擦除闪存:

将串口连接到电脑,BOOT连接到GND,按下RESET;

电脑上Renesas Flash Programmer切换回Operation页面,点击Start,等待擦除成功,后续即可重新用J-Link下载程序。

工程附件
FSP_LowPower.zip
瑞萨
版块: 开发板测评与实战
2025/11/22 21:52
  • 举报
😁😂😃😄😅😆😉😊😋😌😍😏😒😓😔😖😘😚😜😝😞😠😡😢😣😤😥😨😩😪😫😭😰😱😲😳😵😷😸😹😺😻😼😽😾😿🙀🙅🙆🙇🙈🙉🙊🙋🙌🙍🙎🙏✂✅✈✉✊✋✌✏✒✔✖✨✳✴❄❇❌❎❓❔❕❗❤➕➖➗➡➰🚀🚃🚄🚅🚇🚉🚌🚏🚑🚒🚓🚕🚗🚙🚚🚢🚤🚥🚧🚨🚩🚪🚫🚬🚭🚲🚶🚹🚺🚻🚼🚽🚾🛀Ⓜ🅰🅱🅾🅿🆎🆑🆒🆓🆔🆕
@好友

全部评论

加载中
游客登录通知
已选择 0 人
自定义圈子
移动
发布帖子
发布动态
发布问答
最新帖子
学而思可多编程掌机改装2PCB设计翻车实录:我踩过的5个大坑,每个都值一万块从0到1学PCB:硬件工程师Layout实战避坑指南从0到1做硬件:智能硬件产品经理全流程实战指南《图解功率半导体》书评
热门版块
查看更多
萤火工场
单片机/MCU论坛
电子元器件
问型号
飞腾
开源硬件项目
每日打卡
电子DIY
维修技术交流
抄图联盟

2

收藏

分享

微信扫码
分享给好友

评论