930电子网

 找回密码
 立即注册
艾克姆科技推出最新产品STC32G12K128开发板
查看: 2311|回复: 0

NRF52832开启HFCLK后遇到低功耗和睡眠问题

[复制链接]

1

主题

1

帖子

19

积分

新手上路

Rank: 1

积分
19
发表于 2024-5-26 09:02:09 | 显示全部楼层 |阅读模式

在验证NRF52832的低功耗,没有使用softdevice,外接高速、低速晶振,并使用外部的晶振为时钟源。
现在做了一个简答的测试,功能主要是:
a、将HFCLK、LFCLK开启,分别使用外部晶振。
b、使能一个GPIO作为Led电灯,开启rtc0的比较中断0,作为唤醒,设置时间为5秒,rtc的中断中再次设置下次超时时间为5秒
c、while循环中包含以下几个步骤:
    - 关闭HFCLK(即HFXO)(降低功耗)
    - 进入休眠(这里为了测试,验证了几种写法:WFI、WFE、WFE SEV WFE、SEV WFE WFE)
    - 因rtc中断退出休眠,重新开启HFCLK(即HFXO)
    - 电量Led灯,循环等待一段时间,然后关闭Led,这样Led发光更为明显


预期结果:每隔5秒Led闪烁一次


测试遇到如下问题:
1、在main中的循环中,睡眠之前不关闭HFCLK,功耗比较高有280uA左右,如果关闭HCLK,低功耗可以到3uA。但是我从手册里面看HFCLK描述的是如果没有peripheral需要HCLK,不需要关闭,他自动会进入节能模式,这里的200uA已经是节能模式了吗?感觉还是在运行。从sdk里面看无softdevice的低功耗例程,睡眠之前并没有对HFCLK进行处理。




2、基于1中的需要在睡眠之前进行HCLK的开启和关闭,如果睡眠使用WFI,整个功能是正常的,但是使用WFE或WFE SEV WFE都是不正常的,其实也就是意味着执行WFE的时候,有“原因导致”无法进入低功耗。如果在睡眠前后不对HFCLK进行开启、关闭,则可以正常睡眠,只是功耗高,后定位与HFCLK关闭没有关系,主要是开启导致的问题。但是SEV WFE WFE是正常的,因为SEV WFE会把所有事件清除,后面的WFE会让MCU进入低功耗状态。但是这种方式是有风险的,先清除事件,会导致某个真实的唤醒没有阻止进入休眠。
这里的问题在于clock的中断都是开启的,低功耗后面的HFCLK开启时触发的中断已经在ISR进行事件清除,为什么还会影响接下来的睡眠呢?

以下是测试的代码:
  1. static void _rtc0_timer_callback(nrfx_rtc_int_type_t int_type);

  2. #define LED_PIN 13

  3. static void led_init(void)
  4. {
  5.   nrf_gpio_cfg_output(LED_PIN);
  6. }

  7. static void led_turn_on(void)
  8. {
  9.   nrf_gpio_pin_write(LED_PIN, 0);
  10. }

  11. static void led_turn_off(void)
  12. {
  13.   nrf_gpio_pin_write(LED_PIN, 1);
  14. }

  15. void _rtc_timer_start(void)
  16. {
  17.     nrfx_rtc_t            timer_inst = NRFX_RTC_INSTANCE(0);
  18.     nrfx_rtc_config_t     timer_cfg = NRFX_RTC_DEFAULT_CONFIG;
  19.    
  20.     // low frequency clock
  21.     nrf_clock_lf_src_set((nrf_clock_lfclk_t)1);
  22.     nrfx_clock_lfclk_start();
  23.    
  24.     // config
  25.     timer_cfg.prescaler = RTC_FREQ_TO_PRESCALER(32768);
  26.    
  27.     nrfx_rtc_init(&timer_inst, &timer_cfg, _rtc0_timer_callback);
  28.     nrfx_rtc_counter_clear(&timer_inst);
  29.     nrfx_rtc_overflow_enable(&timer_inst, true);
  30.     nrfx_rtc_enable(&timer_inst);
  31. }

  32. void _rtc_timer_set_next(uint32_t time_us)
  33. {
  34.     uint32_t tick;
  35.     tick = (uint32_t)(time_us / (1000000.0 / 32768));
  36.    
  37.     nrfx_rtc_t timer_inst = NRFX_RTC_INSTANCE(0);
  38.     tick = (tick + nrfx_rtc_counter_get(&timer_inst));
  39.     nrfx_rtc_cc_set(&timer_inst, 0, tick, true);
  40. }

  41. static void _rtc0_timer_callback(nrfx_rtc_int_type_t int_type)
  42. {
  43.     // set next timeout
  44.     _rtc_timer_set_next(5000000);
  45. }

  46. static void clk_event_handler(nrfx_clock_evt_type_t event)
  47. {
  48. }

  49. int main(void)
  50. {
  51.     nrfx_clock_init(clk_event_handler);
  52.     nrfx_clock_enable();
  53.     nrfx_clock_hfclk_start();
  54.     while(nrfx_clock_hfclk_is_running() == false)
  55.     {
  56.     }
  57.     nrfx_clock_lfclk_start();
  58.     while(nrfx_clock_lfclk_is_running() == false)
  59.     {
  60.     }
  61.    
  62.     led_init();
  63.     led_turn_off();
  64.    
  65.     _rtc_timer_start();
  66.     _rtc_timer_set_next(5000000);
  67.    
  68.     while(1)
  69.     {
  70.         // 关闭外部高速晶振,切换到内部,降低功耗
  71.         nrfx_clock_hfclk_stop();
  72.         
  73.         // 使用这个睡眠,灯一直在点亮,无法进入低功耗
  74.         // __WFE();
  75.         // __SEV();
  76.         // __WFE();
  77.         
  78.         // 使用这个睡眠,行为符合预期,但是可能前面的某个事件无法中止进入睡眠
  79.         // __SEV();
  80.         // __WFE();
  81.         // __WFE();
  82.         
  83.         // 使用这个睡眠,行为符合预期
  84.         __WFI();
  85.         
  86.         // 使用这个睡眠,灯一直在点亮,无法进入低功耗
  87.         // __WFE();
  88.         
  89.         // 重新开启外部高速晶振
  90.         // 只要把这一行注释掉,上面的几种睡眠行为都符合预期,
  91.         // 但是clock的中断是使能的,为什么会影响wfe的行为?
  92.         nrfx_clock_hfclk_start();
  93.         while(nrfx_clock_hfclk_is_running() == false)
  94.         {
  95.         }
  96.         
  97.         // 点亮一会Led,使其观察明显
  98.         led_turn_on();
  99.         for(uint32_t i = 1000000; i > 0; i--)
  100.         {
  101.             __NOP();
  102.         }
  103.         led_turn_off();
  104.     }
  105. }
复制代码



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|官方淘宝店|930电子网 ( 皖ICP备16000695号-2 )

GMT+8, 2024-11-21 16:52 , Processed in 0.065436 second(s), 23 queries .

快速回复 返回顶部 返回列表