You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中如何访问Nordic SDK宏定义的SAADC默认配置成员?

问题:如何复用Nordic SDK中SAADC默认配置的部分字段?

背景

Nordic SDK的SAADC驱动中,定义了NRFX_SAADC_DEFAULT_CONFIG宏用于生成nrfx_saadc_config_t结构体的默认初始化配置:

/** @brief Macro for setting @ref nrfx_saadc_config_t to default settings. */
#define NRFX_SAADC_DEFAULT_CONFIG                                               \
{                                                                               \
    .resolution         = (nrf_saadc_resolution_t)NRFX_SAADC_CONFIG_RESOLUTION, \
    .oversample         = (nrf_saadc_oversample_t)NRFX_SAADC_CONFIG_OVERSAMPLE, \
    .interrupt_priority = NRFX_SAADC_CONFIG_IRQ_PRIORITY,                       \
    .low_power_mode     = NRFX_SAADC_CONFIG_LP_MODE                             \
}

用户需求与错误代码

用户希望自定义ADC初始化配置时,指定部分字段的自定义值,同时复用宏中的默认中断优先级,编写了如下代码:

static const nrfx_saadc_config_t adc_conf =
{
    .resolution         = NRF_SAADC_RESOLUTION_12BIT,
    .oversample         = NRF_SAADC_OVERSAMPLE_DISABLED,
    .interrupt_priority = NRFX_SAADC_DEFAULT_CONFIG.interrupt_priority,  // 报错行
    .low_power_mode     = false
};

编译时出现以下错误:

drv_adc.c(73): error:  #253: 预期"," 
        .interrupt_priority = NRFX_SAADC_DEFAULT_CONFIG.interrupt_priority,
drv_adc.c(73): error:  #146: 初始化值过多
        .interrupt_priority = NRFX_SAADC_DEFAULT_CONFIG.interrupt_priority,
drv_adc.c(73): error:  #3626: 指示符不能用于非聚合类型"uint8_t"
        .interrupt_priority = NRFX_SAADC_DEFAULT_CONFIG.interrupt_priority,
drv_adc.c: 0 warnings, 3 errors

错误原因

NRFX_SAADC_DEFAULT_CONFIG是展开为结构体初始化列表的宏,并非已定义的结构体变量。C语言中无法直接对结构体初始化列表字面量进行成员访问操作,因此编译器报错。

解决方案

方法1:直接引用原始定义宏

观察默认配置宏的实现可知,中断优先级字段使用的是NRFX_SAADC_CONFIG_IRQ_PRIORITY宏,直接引用该宏即可复用默认值:

static const nrfx_saadc_config_t adc_conf =
{
    .resolution         = NRF_SAADC_RESOLUTION_12BIT,
    .oversample         = NRF_SAADC_OVERSAMPLE_DISABLED,
    .interrupt_priority = NRFX_SAADC_CONFIG_IRQ_PRIORITY,
    .low_power_mode     = false
};

这是最简洁高效的方案,因为默认配置的中断优先级本质就是由这个宏定义的。

方法2:先初始化默认配置,再覆盖自定义字段

如果需要复用多个默认字段,可以先通过宏生成完整的默认配置,再修改需要自定义的部分:

// 先创建临时变量初始化默认配置
nrfx_saadc_config_t temp_conf = NRFX_SAADC_DEFAULT_CONFIG;
// 覆盖自定义字段
temp_conf.resolution = NRF_SAADC_RESOLUTION_12BIT;
temp_conf.oversample = NRF_SAADC_OVERSAMPLE_DISABLED;
temp_conf.low_power_mode = false;
// 赋值给最终的const变量
static const nrfx_saadc_config_t adc_conf = temp_conf;

注意:直接定义const变量后无法修改,因此需要先使用非const临时变量完成配置修改,再赋值给const变量。

方法3:使用C99复合字面量(编译器需支持C99)

如果编译器支持C99标准,可以将宏展开的初始化列表转换为复合字面量,进而访问其成员:

static const nrfx_saadc_config_t adc_conf =
{
    .resolution         = NRF_SAADC_RESOLUTION_12BIT,
    .oversample         = NRF_SAADC_OVERSAMPLE_DISABLED,
    .interrupt_priority = ((nrfx_saadc_config_t)NRFX_SAADC_DEFAULT_CONFIG).interrupt_priority,
    .low_power_mode     = false
};

这里通过强制类型转换将初始化列表转为nrfx_saadc_config_t类型的复合字面量,从而支持成员访问。

内容的提问来源于stack exchange,提问作者ilja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 17:34:51