Nordic RTC 函数说明

Nordic Semiconductor的 nrf_rtc_cc_set 函数用于配置 RTC(实时时钟)的比较通道(Compare Channel),以便在 RTC 的计数器达到预设值时触发事件或中断。以下是该函数的参数说明及使用详解:


函数原型

1
void nrf_rtc_cc_set(NRF_RTC_Type *p_rtc, uint32_t cc_channel, uint32_t cc_value);

参数说明

参数 类型 说明
p_rtc NRF_RTC_Type * 指向 RTC 外设实例的指针。例如:NRF_RTC0, NRF_RTC1, NRF_RTC2(具体取决于芯片型号)。
cc_channel uint32_t 比较通道的编号,取值范围:0NRF_RTC_CC_COUNT - 1(通常为 0~3,共4个通道)。
cc_value uint32_t 比较值(24位有效值),当 RTC 计数器(COUNTER)达到此值时触发比较事件。取值范围:0 ~ 0x00FFFFFF

功能详解

  1. RTC 实例选择(p_rtc
    Nordic 芯片通常有多个 RTC 实例(如 nRF52 系列有 RTC0、RTC1、RTC2),需根据实际需求选择:

    • RTC0:常用于协议栈(如蓝牙 SoftDevice)。
    • RTC1/RTC2:推荐用户自定义任务(如定时唤醒、周期性事件)。
    • 示例
      1
      nrf_rtc_cc_set(NRF_RTC1, 0, 32768);  // 使用 RTC1 的通道0,设置比较值为32768
  2. 比较通道(cc_channel

    • 每个 RTC 实例有多个比较通道(通常为4个),可独立配置。
    • 注意:避免与其他模块(如协议栈或库)占用同一通道。例如,蓝牙协议栈可能默认使用 RTC0 的通道0。
  3. 比较值(cc_value

    • RTC 计数器为 24位,因此 cc_value 最大为 0x00FFFFFF(16,777,215)。
    • 时间计算
      实际时间与 RTC 的时钟源和分频系数相关。例如:

      • 若 RTC 时钟源为 32.768 kHz,分频系数为 1(PRESCALER = 0),则:

        1
        2
        1 秒 = 32768 个计数周期  
        cc_value = 目标时间(秒) * 32768
      • 若设置 cc_value = 32768,则比较事件将在 1 秒后触发。


使用示例

场景:配置 RTC1 的通道0,在 5 秒后触发中断。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "nrf_drv_rtc.h"

// 1. 初始化 RTC
nrf_drv_rtc_config_t rtc_config = NRF_DRV_RTC_DEFAULT_CONFIG;
nrf_drv_rtc_init(&rtc1, &rtc_config, rtc_handler); // rtc_handler 为中断处理函数

// 2. 设置比较值(假设时钟源为 32.768 kHz,分频系数为 0)
uint32_t timeout_seconds = 5;
uint32_t cc_value = timeout_seconds * 32768; // 5秒 = 163840 个计数周期
nrf_rtc_cc_set(NRF_RTC1, 0, cc_value);

// 3. 启用比较中断
nrf_rtc_event_enable(NRF_RTC1, NRF_RTC_INT_COMPARE0_MASK);
nrf_rtc_int_enable(NRF_RTC1, NRF_RTC_INT_COMPARE0_MASK);

// 4. 启动 RTC
nrf_rtc_task_trigger(NRF_RTC1, NRF_RTC_TASK_START);

注意事项

  1. 计数器溢出
    RTC 是 24 位计数器,若 cc_value 小于当前计数器值,需等待计数器溢出后重新计数到 cc_value 才会触发事件。

  2. 中断处理

    • 在中断服务程序(如 rtc_handler)中需清除事件标志:

      1
      2
      3
      4
      5
      6
      void rtc_handler(nrf_drv_rtc_int_type_t int_type) {
      if (int_type == NRF_DRV_RTC_INT_COMPARE0) {
      nrf_rtc_event_clear(NRF_RTC1, NRF_RTC_EVENT_COMPARE_0);
      // 处理逻辑
      }
      }
    • 若未清除事件标志,可能导致中断持续触发。

  3. 分频系数(PRESCALER)
    RTC 的时钟频率由分频系数决定,需在初始化时配置:

    1
    rtc_config.prescaler = 31;  // 32.768 kHz / (31 + 1) = 1024 Hz
  4. 多通道协同
    可配置多个比较通道实现复杂定时逻辑(如周期触发、超时检测)。


常见问题

  • Q1:设置了 cc_value,但未触发事件?

    • 检查 RTC 是否已启动(NRF_RTC_TASK_START)。
    • 确认中断已启用且未与其他模块冲突。
  • Q2:如何计算 cc_value 对应的时间?

    • 公式:
      1
      cc_value = (目标时间秒数) * (RTC时钟频率 / (PRESCALER + 1))

总结

nrf_rtc_cc_set 是 Nordic RTC 外设的核心函数,通过配置比较通道实现精准定时。使用时需注意时钟源、分频系数及中断处理,适用于低功耗定时任务(如传感器采样、蓝牙连接间隔等)。