API GUIDE / ADC / EXAMPLES

示例与验证

8. 示例程序与使用方式

8.1 示例程序索引与接入方式

ADC示例只位于 code/examples。这些文件不会自动编译进主固件,应用需要将选定的 .c 文件显式加入自身构建目标;示例用于说明调用方式,不属于与HAL/LL同等级的稳定二进制接口。

示例 层级 调用入口 覆盖内容
adc_polling_example.c HAL example_adc_sample_run()、example_adc_sample_run_on() 单通道采样、SEQ0/SEQ1/SEQ2轮询、多序列启动。
hal_adc_dma_example.c HAL example_hal_adc_dma_run() SEQ1/SEQ2循环DMA、ADC DMA完成中断和回调。
hal_adc_dma_loop_example.c HAL example_hal_adc_dma_loop_run()、example_hal_adc_dma_loop_soak_get_default_config()、example_hal_adc_dma_loop_soak_run() 多轮DMA、停止后重启和长时间运行观察;SADC时钟由调用方配置。
tcu_trig_adc_example.c HAL example_tcu_trig_adc0_run()、example_tcu_trig_adc1_run() SEQ1 TCU外部触发,TCU channel 0 HALF/FULL输出分别触发ADC0/ADC1。
adc_seq_example.c LL example_adc_seq_sample_run() 直接配置寄存器,完成SEQ0/SEQ1/SEQ2软件触发轮询和寄存器dump。

接入方式:

  1. HAL示例需要包含 hal_adc.h 并启用 CONFIG_DRIVER_ADC;再按示例实际使用的功能启用GPIO、TCU、IRQ等驱动。CONFIG_DRIVER_ADC 会自动选择 CONFIG_DRIVER_DMA;示例本身不调用CPM HAL,SADC时钟由调用方准备。
  2. LL示例需要包含 ll_adc.h,不需要链接ADC HAL。
  3. 示例未提供独立公共头文件时,应用应显式把示例 .c 加入构建目标,并在应用侧声明需要调用的入口函数;不要同时编译和包含同一个 .c 文件,避免重复定义。
  4. 调用示例前完成2.1节中的时钟、引脚、IRQ、systick和模拟信号准备。不同示例覆盖的前置条件不同,以各文件头部说明为准。

本文列出的 ADC HAL/LL 示例都不配置CPM,SADC源时钟和门控由板级代码或调用方预先建立;示例中的GPIO配置只负责把目标GPIOC引脚切到function 0。

8.2 单通道轮询采样

hal_adc_handle_t hadc0;
uint32_t value;
error_code_t ret;

ret = hal_adc_handle_init(&hadc0, ADC0);
if (ret != IM_OK) {
    return ret;
}

hadc0.init.adc_clk_div = 2U;
hadc0.init.soc_extra_cycle = (uint8_t)HAL_ADC_SOC_EXTRA_CYCLE_0;
ret = hal_adc_init(&hadc0);
if (ret != IM_OK) {
    return ret;
}

ret = hal_adc_channel_value_get(&hadc0, 0U, &value, 1000000U);

8.3 SEQ1 多通道扫描中断模式

static void adc_seq1_done(hal_adc_handle_t *hadc)
{
    hal_adc_data_t data[8];

    (void)hal_adc_data_get(hadc, HAL_ADC_SEQUENCE_1, data, 8U);
}

hal_adc_sequence_config_t config = {0};

config.sequence = HAL_ADC_SEQUENCE_1;
config.trigger = HAL_ADC_TRIGGER_SOFTWARE;
config.data_ready_type = HAL_ADC_DRT_SEQUENCE_END;
config.channel_number_enable = 1U;
config.channel_count = 4U;
config.channel[0] = 0U;
config.channel[1] = 2U;
config.channel[2] = 5U;
config.channel[3] = 6U;
config.storage_mask = 0x0FU;
config.dma_enable = 0U;
config.continuous_enable = 0U;

hal_adc_sequence_config(&hadc0, &config);
hal_adc_callback_register(&hadc0, HAL_ADC_CALLBACK_SEQ1_COMPLETE, adc_seq1_done);
hal_adc_start_it(&hadc0, HAL_ADC_SEQUENCE_1);

8.4 SEQ1 连续组与 TCU 外部触发

hal_adc_sequence_config_t config = {0};

config.sequence = HAL_ADC_SEQUENCE_1;
config.trigger = HAL_ADC_TRIGGER_TCU;
config.data_ready_type = HAL_ADC_DRT_GROUP_END;
config.channel_number_enable = 1U;
config.channel_count = 8U;
config.continuous_enable = 1U;
config.group_count = 2U;
config.group_length[0] = 4U;
config.group_interval[0] = 100U;
config.group_length[1] = 4U;
config.group_interval[1] = 100U;

hal_adc_sequence_config(&hadc0, &config);

/* TCU/PWM外部触发模式不调用 hal_adc_start();由外部触发源启动转换。 */

该片段省略了 channel[0..7] 的有效通道填充;实际配置必须为每个转换rank提供合法通道号。

本段只展示ADC侧配置。完整的TCU时钟、比较值和 HAL_ADC_TRIGGER_TCU 路由见 tcu_trig_adc_example.c。

8.5 SEQ2 DMA 采样

static uint32_t adc_dma_buffer[256];
hal_adc_sequence_config_t config = {0};

static void adc_seq2_dma_done(hal_adc_handle_t *hadc)
{
    (void)hadc;
    /* adc_dma_buffer中保存本次DMA采样结果。 */
}

config.sequence = HAL_ADC_SEQUENCE_2;
config.trigger = HAL_ADC_TRIGGER_SOFTWARE;
config.data_ready_type = HAL_ADC_DRT_SEQUENCE_END;
config.channel_number_enable = 1U;
config.channel_count = 4U;
config.channel[0] = 0U;
config.channel[1] = 1U;
config.channel[2] = 2U;
config.channel[3] = 3U;
config.storage_mask = 0x0FU;
config.dma_enable = 1U;
config.dma_buffer = adc_dma_buffer;
config.dma_len = sizeof(adc_dma_buffer);
config.dma_mode = HAL_ADC_DMA_MODE_SINGLE;
config.dma_desc = NULL;
config.dma_desc_count = 0U;

hal_adc_sequence_config(&hadc0, &config);
hal_adc_callback_register(&hadc0,
                          HAL_ADC_CALLBACK_SEQ2_DMA_COMPLETE,
                          adc_seq2_dma_done);

/* start_it先配置DMA完成/错误中断,再由统一start路径启动DMA和ADC。 */
hal_adc_start_it(&hadc0, HAL_ADC_SEQUENCE_2);

单次SEQ1/SEQ2 DMA及中断流程见 hal_adc_dma_example.c,多轮停止再启动和CPM时钟配置见 hal_adc_dma_loop_example.c。

8.6 AWD 高低阈值检测

hal_adc_awd_config_t awd_config = {0};
uint32_t low_flags;
uint32_t high_flags;

awd_config.channel = 0U;
awd_config.low_threshold = 0x100U;
awd_config.high_threshold = 0xE00U;
awd_config.low_threshold_enable = 1U;
awd_config.high_threshold_enable = 1U;
awd_config.interrupt_enable = 1U;
awd_config.fail_enable = 1U;

hal_adc_awd_config(&hadc0, &awd_config);
hal_adc_awd_status_get(&hadc0, &low_flags, &high_flags);
hal_adc_awd_status_clear(&hadc0,
                         HAL_ADC_AWD_CHANNEL_FLAG(0U),
                         HAL_ADC_AWD_CHANNEL_FLAG(0U));

8.7 LL 寄存器级序列采样

adc_seq_example.c 的入口为 example_adc_seq_sample_run()。该示例不链接ADC HAL,直接完成GPIO功能配置、PHY初始化、 时钟/优先级配置、SEQ0/SEQ1/SEQ2软件触发、状态轮询、packed数据解析和寄存器dump,适合用于确认 “HAL问题还是寄存器配置问题”。