API GUIDE / ADC / EXAMPLES
示例与验证
8. 示例程序与使用方式
8.1 示例程序索引与接入方式
ADC示例只位于 code/examples。这些文件不会自动编译进主固件,应用需要将选定的 .c 文件显式加入自身构建目标;示例用于说明调用方式,不属于与HAL/LL同等级的稳定二进制接口。
| 示例 | 层级 | 调用入口 | 覆盖内容 |
|---|---|---|---|
|
HAL | example_adc_sample_run()、example_adc_sample_run_on() |
单通道采样、SEQ0/SEQ1/SEQ2轮询、多序列启动。 |
|
HAL | example_hal_adc_dma_run() |
SEQ1/SEQ2循环DMA、ADC DMA完成中断和回调。 |
|
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时钟由调用方配置。 |
|
HAL | example_tcu_trig_adc0_run()、example_tcu_trig_adc1_run() |
SEQ1 TCU外部触发,TCU channel 0 HALF/FULL输出分别触发ADC0/ADC1。 |
|
LL | example_adc_seq_sample_run() |
直接配置寄存器,完成SEQ0/SEQ1/SEQ2软件触发轮询和寄存器dump。 |
接入方式:
- HAL示例需要包含
hal_adc.h并启用CONFIG_DRIVER_ADC;再按示例实际使用的功能启用GPIO、TCU、IRQ等驱动。CONFIG_DRIVER_ADC会自动选择CONFIG_DRIVER_DMA;示例本身不调用CPM HAL,SADC时钟由调用方准备。 - LL示例需要包含
ll_adc.h,不需要链接ADC HAL。 - 示例未提供独立公共头文件时,应用应显式把示例
.c加入构建目标,并在应用侧声明需要调用的入口函数;不要同时编译和包含同一个.c文件,避免重复定义。 - 调用示例前完成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及中断流程见
,多轮停止再启动和CPM时钟配置见
hal_adc_dma_example.c。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.cexample_adc_seq_sample_run()。该示例不链接ADC HAL,直接完成GPIO功能配置、PHY初始化、
时钟/优先级配置、SEQ0/SEQ1/SEQ2软件触发、状态轮询、packed数据解析和寄存器dump,适合用于确认
“HAL问题还是寄存器配置问题”。