API GUIDE / ADC / HAL
G32S10 ADC HAL 接口
HAL 层接口:分层职责如下:
1. 分层关系
分层职责如下:
HAL ADC封装初始化、序列配置、启动停止、轮询、中断、DMA侧控制、AWD和寄存器dump
维护参数合法性、模块级状态、活跃序列mask和统一返回码
提供便于上层使用的解包数据结构、回调注册和错误查询接口
LL ADC提供寄存器位级访问入口
不维护软件状态,不做复杂业务语义判断
公开接口均为
static inline,首参数为adc_regs_t *adcxadc_regs.h定义ADC基地址、寄存器结构体布局、通道数量、序列长度和位域mask
2. 资源模型与公开类型
2.1 模块基地址与实例
| 实例 | 基地址宏 | 基地址 |
|---|---|---|
ADC0 | SADC0_IOBASE | 0x13720000UL |
ADC1 | SADC1_IOBASE | 0x13730000UL |
当前SDK中 SADC0_IOBASE / SADC1_IOBASE 定义在 base.h,adc_regs.h 中提供如下实例宏:
#define ADC0 ((adc_regs_t *)(uintptr_t)SADC0_IOBASE) #define ADC1 ((adc_regs_t *)(uintptr_t)SADC1_IOBASE)
说明:
实例宏使用
(uintptr_t)做整数地址到指针的中间转换,避免部分编译器对整数直接转指针产生告警。驱动接口通过
adc_regs_t *或hal_adc_handle_t.instance传递外设基地址。
2.2 HAL 公开宏
| 宏 | 使用说明 | 取值/约束 |
|---|---|---|
HAL_ADC_MAX_SEQUENCE_LENGTH | HAL层通用序列数组最大长度。 | 8。 |
HAL_ADC_MAX_GROUP_COUNT | SEQ1连续组配置数组最大长度。 | 8。 |
HAL_ADC_CHANNEL_COUNT / HAL_ADC_CHANNEL_MAX | HAL开放的ADC通道数量和最大通道号。 | 通道0~7。 |
HAL_ADC_SEQ0_MAX_LENGTH | SEQ0最大转换次数。 | 4。 |
HAL_ADC_SEQ1_MAX_LENGTH | SEQ1当前开放最大转换次数。 | 8,高位8次暂不开放。 |
HAL_ADC_SEQ2_MAX_LENGTH | SEQ2最大转换次数。 | 8。 |
HAL_ADC_THRESHOLD_MAX | ADC采样值/AWD阈值最大值。 | 0x0FFF。 |
HAL_ADC_CLK_DIV_MAX | ADC转换时钟分频字段最大值。 | 0xFF,HAL接口入参为 uint8_t。 |
HAL_ADC_DELAY_CLK_DIV_MAX | SEQ1/SEQ2延时时钟分频最大值。 | 0x00FFFFFF。 |
HAL_ADC_DEFAULT_* | HAL默认初始化配置。 | 用于 hal_adc_init_config_default();SOC默认值为 HAL_ADC_SOC_EXTRA_CYCLE_0。 |
HAL_ADC_SEQ_MASK_ALL | 选择全部序列的mask。 | bit0/1/2分别对应SEQ0/SEQ1/SEQ2。 |
HAL_ADC_SEQ_BUSY_STATE_MASK | 序列FSM忙状态mask。 | HAL内部判断序列busy使用。 |
HAL_ADC_SEQ0_STORAGE_MASK | SEQ0有效存储rank mask。 | bit3:0。 |
HAL_ADC_SEQ_STORAGE_MASK | SEQ1/SEQ2有效存储rank mask。 | bit7:0。 |
HAL_ADC_SEQ1_DELAY_MAX | SEQ1单rank延时和连续组间隔最大值。 | 0xFFFF。 |
HAL_ADC_SEQ2_DELAY_MAX | SEQ2单rank延时最大值。 | 0xFF。 |
HAL_ADC_RCNT_MAX_VALUE | SEQ1/SEQ2读计数器字段最大值。 | 0xFFFF。 |
HAL_ADC_DMA_UNIT_SIZE | ADC FIFO与DMA传输粒度。 | 4字节。 |
HAL_ADC_DUMP_READ_FIFO | 寄存器dump时是否读取FIFO。 | 默认0,避免读取FIFO改变硬件状态。 |
HAL_ADC_AWD_FLAG_MASK | AWD低/高阈值原始flag总mask。 | bit7:0为低阈值,bit23:16为高阈值。 |
HAL_ADC_AWD_CHANNEL_FLAG(channel) | 生成HAL层AWD通道flag。 | 用于 low_flags / high_flags,channel为0~7。 |
HAL_ADC_AWD_CHANNEL_FLAG_ALL | 选择全部AWD通道flag。 | bit7:0。 |
HAL_ADC_AWD_DETECT_LOW / HAL_ADC_AWD_DETECT_HIGH / HAL_ADC_AWD_DETECT_BOTH | AWD检测方向选择。 | 用于 detect_mask。 |
说明:HAL层不再提供 HAL_ADC_SOC_EXTRA_CYCLE_MAX 作为合法性依据。SOC额外周期不是0~0xFF连续范围,必须使用 hal_adc_soc_extra_cycle_t 中列出的离散值。
2.3 HAL 运行状态
typedef enum {
HAL_ADC_STATE_RESET = 0,
HAL_ADC_STATE_READY,
HAL_ADC_STATE_BUSY,
HAL_ADC_STATE_TIMEOUT,
HAL_ADC_STATE_ERROR,
} hal_adc_state_t;说明:state 为模块级状态;序列空闲/忙状态通过 active_sequence_mask 独立跟踪。TIMEOUT、ERROR 的迁移和恢复路径见 7.7 状态迁移、错误锁存与恢复。
2.4 ADC 序列类型
typedef enum {
HAL_ADC_SEQUENCE_0 = 0,
HAL_ADC_SEQUENCE_1 = 1,
HAL_ADC_SEQUENCE_2 = 2,
} hal_adc_sequence_t;2.5 ADC 触发类型
typedef enum {
HAL_ADC_TRIGGER_SOFTWARE = 0,
HAL_ADC_TRIGGER_TCU = 1,
HAL_ADC_TRIGGER_PWM0 = 2,
HAL_ADC_TRIGGER_PWM1 = 3,
} hal_adc_trigger_t;说明:
SEQ0仅支持HAL_ADC_TRIGGER_SOFTWARE。SEQ1和SEQ2支持HAL_ADC_TRIGGER_SOFTWARE、HAL_ADC_TRIGGER_TCU、HAL_ADC_TRIGGER_PWM0、HAL_ADC_TRIGGER_PWM1。当前ADC寄存器只配置触发源,不配置TCU通道;TCU通道选择由TCU模块侧完成。
hal_adc_start()/hal_adc_start_multi()只用于软件触发序列。
2.6 ADC 序列优先级
typedef enum {
HAL_ADC_PRIORITY_LOWEST = 0,
HAL_ADC_PRIORITY_LOW = 1,
HAL_ADC_PRIORITY_HIGH = 2,
HAL_ADC_PRIORITY_HIGHEST = 3,
} hal_adc_priority_t;说明:数值越大优先级越高;多个序列优先级相同时,硬件默认优先级为 SEQ0 > SEQ1 > SEQ2。
2.7 ADC SOC 额外周期
typedef enum {
HAL_ADC_SOC_EXTRA_CYCLE_0 = ADC_SOC_EXTRA_CYCLE_0,
HAL_ADC_SOC_EXTRA_CYCLE_5 = ADC_SOC_EXTRA_CYCLE_5,
HAL_ADC_SOC_EXTRA_CYCLE_10 = ADC_SOC_EXTRA_CYCLE_10,
HAL_ADC_SOC_EXTRA_CYCLE_15 = ADC_SOC_EXTRA_CYCLE_15,
HAL_ADC_SOC_EXTRA_CYCLE_30 = ADC_SOC_EXTRA_CYCLE_30,
HAL_ADC_SOC_EXTRA_CYCLE_45 = ADC_SOC_EXTRA_CYCLE_45,
HAL_ADC_SOC_EXTRA_CYCLE_60 = ADC_SOC_EXTRA_CYCLE_60,
HAL_ADC_SOC_EXTRA_CYCLE_210 = ADC_SOC_EXTRA_CYCLE_210,
} hal_adc_soc_extra_cycle_t;说明:硬件仅支持上述离散 SOC_EXT_CYCLE 值。HAL配置字段和接口入参使用 uint8_t 保存实际寄存器字段值,但参数校验必须满足 hal_adc_soc_extra_cycle_t 枚举值。
2.8 ADC DMA 传输模式
typedef enum {
HAL_ADC_DMA_MODE_SINGLE = 0U,
HAL_ADC_DMA_MODE_CYCLIC = 1U,
} hal_adc_dma_mode_t;说明:
HAL_ADC_DMA_MODE_SINGLE使用DMA非descriptor传输;hal_adc_irq_handler()处理DMA_FIN后清除对应sequence的DMA active状态。HAL_ADC_DMA_MODE_CYCLIC使用调用方提供的descriptor数组,DMA保持循环运行,直到调用stop或重新配置/deinit。
2.9 回调 ID
typedef enum {
HAL_ADC_CALLBACK_SEQ0_COMPLETE = 0U,
HAL_ADC_CALLBACK_SEQ1_COMPLETE = 1U,
HAL_ADC_CALLBACK_SEQ2_COMPLETE = 2U,
HAL_ADC_CALLBACK_SEQ1_DMA_COMPLETE = 3U,
HAL_ADC_CALLBACK_SEQ2_DMA_COMPLETE = 4U,
HAL_ADC_CALLBACK_ERROR = 5U,
} hal_adc_callback_id_t;2.10 ADC 采样数据
typedef struct {
uint16_t value;
uint8_t channel;
} hal_adc_data_t;| 字段 | 说明 |
|---|---|
value | 12bit转换值,范围0~0x0FFF。 |
channel | 通道号,开启 channel_number_enable 时有效。 |
2.11 ADC 初始化配置
typedef struct {
uint8_t adc_clk_div;
uint32_t seq1_cont_clk_div;
uint32_t seq1_delay_clk_div;
uint32_t seq2_delay_clk_div;
uint8_t soc_extra_cycle;
uint8_t break_enable;
hal_adc_priority_t seq0_priority;
hal_adc_priority_t seq1_priority;
hal_adc_priority_t seq2_priority;
} hal_adc_init_config_t;2.12 ADC 序列配置
typedef struct {
hal_adc_sequence_t sequence;
hal_adc_trigger_t trigger;
hal_adc_drt_t data_ready_type;
uint8_t data_ready_custom_mask;
uint8_t channel_number_enable;
uint8_t channel_count;
uint8_t channel[HAL_ADC_MAX_SEQUENCE_LENGTH];
uint16_t delay_count[HAL_ADC_MAX_SEQUENCE_LENGTH];
uint32_t storage_mask;
uint8_t dma_enable;
void *dma_buffer;
uint32_t dma_len;
hal_adc_dma_mode_t dma_mode;
void *dma_desc;
uint32_t dma_desc_count;
uint8_t continuous_enable;
uint8_t group_count;
uint8_t group_length[HAL_ADC_MAX_GROUP_COUNT];
uint16_t group_interval[HAL_ADC_MAX_GROUP_COUNT];
} hal_adc_sequence_config_t;关键约束:
channel_count:SEQ0为14,SEQ1/SEQ2为18。channel[i]:HAL当前开放0~7。data_ready_custom_mask:SEQ0只允许bit3:0;SEQ1/SEQ2使用bit7:0。dma_enable:仅SEQ1/SEQ2有效。为0时,dma_mode必须为HAL_ADC_DMA_MODE_SINGLE,其余dma_*字段必须为NULL或0。dma_buffer/dma_len:DMA使能时必须提供;buffer需4字节对齐,len必须非0且为HAL_ADC_DMA_UNIT_SIZE的整数倍。HAL_ADC_DMA_MODE_SINGLE:使用非descriptor DMA,dma_desc必须为NULL且dma_desc_count必须为0。HAL_ADC_DMA_MODE_CYCLIC:必须提供按HAL_DMA_DESCRIPTOR_ALIGN对齐的descriptor存储;dma_desc_count为实际使用的descriptor数量,且不能超过HAL_DMA_MAX_DESCRIPTOR_COUNT。dma_len必须可被其整除,每段长度必须为4字节的整数倍。continuous_enable、group_count、group_length[]、group_interval[]:仅SEQ1连续组模式有效。storage_mask:SEQ0只允许bit3:0;SEQ1/SEQ2只允许bit7:0;为0时HAL默认按转换次数全存储。
2.13 ADC 模拟看门狗配置
typedef struct {
uint8_t channel;
uint16_t low_threshold;
uint16_t high_threshold;
uint8_t low_threshold_enable;
uint8_t high_threshold_enable;
uint8_t interrupt_enable;
uint8_t fail_enable;
} hal_adc_awd_config_t;2.14 ADC 回调类型
typedef void (*hal_adc_callback_t)(hal_adc_handle_t *hadc); typedef void (*hal_adc_awd_callback_t)(hal_adc_handle_t *hadc, uint32_t low_flags, uint32_t high_flags);
说明:普通ADC回调和AWD回调使用不同函数指针类型,避免通过 void *callback 做强制转换,保持编译期类型安全。
2.15 ADC 句柄
typedef struct hal_adc_handle hal_adc_handle_t;
struct hal_adc_handle {
adc_regs_t *instance;
hal_adc_init_config_t init;
hal_adc_state_t state;
uint32_t active_sequence_mask;
uint32_t error_code;
hal_adc_callback_t seq0_complete_callback;
hal_adc_callback_t seq1_complete_callback;
hal_adc_callback_t seq2_complete_callback;
hal_adc_callback_t seq1_dma_complete_callback;
hal_adc_callback_t seq2_dma_complete_callback;
hal_adc_awd_callback_t awd_callback;
hal_adc_callback_t error_callback;
void *user_data;
hal_dma_handle_t seq1_dma;
hal_dma_handle_t seq2_dma;
void *seq1_dma_buffer;
uint32_t seq1_dma_len;
uint8_t seq1_dma_active;
hal_adc_dma_mode_t seq1_dma_mode;
void *seq2_dma_buffer;
uint32_t seq2_dma_len;
uint8_t seq2_dma_active;
hal_adc_dma_mode_t seq2_dma_mode;
};说明:
active_sequence_mask使用bit0/1/2分别记录SEQ0/SEQ1/SEQ2是否处于HAL跟踪的活跃状态。error_code为hal_adc_error_t定义的bitmask,可同时记录多个错误来源。user_data是调用方上下文指针,HAL只保存不解释。seq1_dma/seq2_dma由ADC HAL持有并管理;cyclic descriptor存储仍由调用方持有,生命周期必须覆盖DMA配置和运行阶段。seq1_dma_*/seq2_dma_*保存当前sequence配置中的DMA buffer、长度、模式和运行状态,供统一的start/stop路径使用。
3. HAL 接口规范
3.1 HAL 层实现边界
HAL层公开接口首参数优先使用
hal_adc_handle_t *hadc或const hal_adc_handle_t *hadc,寄存器基地址通过hadc->instance传递。对不修改handle内容的接口使用
const hal_adc_handle_t *;这不影响通过hadc->instance写硬件寄存器。HAL层使用
IM_HAL_PARAM_CHECK_RETURN/IM_HAL_PARAM_CHECK_RETURN_VOID做参数合法性检查。HAL层普通可失败接口返回
error_code_t,不定义ADC私有状态码类型。hal_adc_start()、hal_adc_start_multi()、hal_adc_start_it()、hal_adc_start_multi_it()只允许启动配置为HAL_ADC_TRIGGER_SOFTWARE的序列。ADC HAL已接入DMA控制器;
hal_adc_sequence_config()在配置阶段保存DMA参数并绑定DMA handle/descriptor,hal_adc_start()/hal_adc_start_multi()在触发ADC前自动启动已配置的DMA。普通start/stop接口不管理ADC中断;
hal_adc_start_it()/hal_adc_start_multi_it()和对应stop接口统一管理所选sequence的普通或DMA中断。寄存器dump默认不读取SEQ1/SEQ2 FIFO,避免读取FIFO改变硬件状态;如需读取,由
HAL_ADC_DUMP_READ_FIFO宏控制。
3.2 初始化和反初始化
3.2.1 hal_adc_init_config_default
error_code_t hal_adc_init_config_default(hal_adc_init_config_t *init);
功能说明: 填充ADC全局初始化默认值,不访问硬件。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
init | hal_adc_init_config_t * | 输出 | 待填充的ADC初始化配置结构体,不能为NULL |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
init不能为NULL;填充HAL_ADC_DEFAULT_*默认值,soc_extra_cycle默认HAL_ADC_SOC_EXTRA_CYCLE_0。
3.2.2 hal_adc_handle_init
error_code_t hal_adc_handle_init(hal_adc_handle_t *hadc, adc_regs_t *instance);
功能说明: 初始化软件handle,绑定ADC实例并填充默认init配置。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | hal_adc_handle_t * | 输入/输出 | ADC句柄,必须绑定合法ADC实例 |
instance | adc_regs_t * | 输入 | ADC外设寄存器基地址,必须为 ADC0 或 ADC1 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
hadc不能为NULL;instance必须为ADC0或ADC1。本接口只初始化软件handle,不释放硬件、IRQ或DMA资源;只能在首次初始化前或
hal_adc_deinit()之后调用,不能直接用于活动handle的重置。
3.2.3 hal_adc_init
error_code_t hal_adc_init(hal_adc_handle_t *hadc);
功能说明:
根据 hadc->init 初始化硬件,清中断/状态,关闭AWD中断和fail,初始化AWD阈值,配置时钟、优先级并打开PHY。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | hal_adc_handle_t * | 输入/输出 | ADC句柄,必须绑定合法ADC实例 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
IM_ERR_BUSY | ADC句柄不处于 HAL_ADC_STATE_RESET |
补充说明:
参数约束:
hadc必须有效;hadc->init分频、SOC离散值、优先级、break配置必须合法。初始化时清除ADC/AWD中断和状态,初始化默认回调,并将句柄状态切换为
HAL_ADC_STATE_READY。
3.2.4 hal_adc_deinit
error_code_t hal_adc_deinit(hal_adc_handle_t *hadc);
功能说明: 关闭ADC中断/AWD/DMA,复位SEQ0/1/2,关闭PHY和PAD,状态切为RESET。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | hal_adc_handle_t * | 输入/输出 | ADC句柄,必须绑定合法ADC实例 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
hadc必须有效。本接口停止并释放SEQ1/SEQ2 DMA handle和运行配置,然后复位sequence并关闭PHY/PAD。
3.3 基础配置
3.3.1 hal_adc_clock_config
error_code_t hal_adc_clock_config(hal_adc_handle_t *hadc, uint8_t adc_clk_div, uint32_t seq1_cont_clk_div, uint32_t seq1_delay_clk_div, uint32_t seq2_delay_clk_div);
功能说明:
配置ADC转换时钟、SEQ1连续间隔时钟、SEQ1/SEQ2延时时钟,并同步更新 hadc->init。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | hal_adc_handle_t * | 输入/输出 | ADC句柄,必须绑定合法ADC实例 |
adc_clk_div | uint8_t | 输入 | ADC转换时钟分频字段值,范围0~`HAL_ADC_CLK_DIV_MAX` |
seq1_cont_clk_div | uint32_t | 输入 | SEQ1连续转换间隔时钟分频,范围0~`HAL_ADC_DELAY_CLK_DIV_MAX` |
seq1_delay_clk_div | uint32_t | 输入 | SEQ1延时计数时钟分频,范围0~`HAL_ADC_DELAY_CLK_DIV_MAX` |
seq2_delay_clk_div | uint32_t | 输入 | SEQ2延时计数时钟分频,范围0~`HAL_ADC_DELAY_CLK_DIV_MAX` |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
adc_clk_div为uint8_t;其余分频<= HAL_ADC_DELAY_CLK_DIV_MAX。本接口不检查序列是否处于活动状态;调用方必须先停止所有受这些时钟字段影响的序列,参见 7.8 配置修改时机与资源所有权。
3.3.2 hal_adc_priority_config
error_code_t hal_adc_priority_config(hal_adc_handle_t *hadc, hal_adc_priority_t seq0_priority, hal_adc_priority_t seq1_priority, hal_adc_priority_t seq2_priority, uint8_t break_enable);
功能说明:
配置SEQ0/1/2优先级和break模式,并同步更新 hadc->init。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | hal_adc_handle_t * | 输入/输出 | ADC句柄,必须绑定合法ADC实例 |
seq0_priority | hal_adc_priority_t | 输入 | SEQ0优先级,使用 HAL_ADC_PRIORITY_* |
seq1_priority | hal_adc_priority_t | 输入 | SEQ1优先级,使用 HAL_ADC_PRIORITY_* |
seq2_priority | hal_adc_priority_t | 输入 | SEQ2优先级,使用 HAL_ADC_PRIORITY_* |
break_enable | uint8_t | 输入 | 是否允许高优先级序列打断低优先级序列,仅允许0或1 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:priority使用
HAL_ADC_PRIORITY_*;break_enable只能为0或1。本接口不检查序列是否处于活动状态;调用方必须先停止所有相关序列,参见 7.8 配置修改时机与资源所有权。
3.3.3 hal_adc_soc_extra_cycle_config
error_code_t hal_adc_soc_extra_cycle_config(hal_adc_handle_t *hadc, uint8_t cycle);
功能说明:
配置SOC额外周期并同步更新 hadc->init。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | hal_adc_handle_t * | 输入/输出 | ADC句柄,必须绑定合法ADC实例 |
cycle | uint8_t | 输入 | SOC额外周期,HAL使用 HAL_ADC_SOC_EXTRA_CYCLE_*,LL使用 ADC_SOC_EXTRA_CYCLE_* 离散值 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
cycle为uint8_t,但必须等于hal_adc_soc_extra_cycle_t中定义的离散值。本接口不检查序列是否处于活动状态;SPEC要求所有序列停止后再修改,参见 7.8 配置修改时机与资源所有权。
3.4 序列配置
3.4.1 hal_adc_sequence_config
error_code_t hal_adc_sequence_config(hal_adc_handle_t *hadc, const hal_adc_sequence_config_t *config);
功能说明:
按 config->sequence 配置SEQ0/SEQ1/SEQ2通道、长度、触发源、数据就绪模式、存储mask、延时、连续组和DMA模式。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | hal_adc_handle_t * | 输入/输出 | ADC句柄,必须绑定合法ADC实例;配置DMA时会更新内部DMA handle和运行配置 |
config | const hal_adc_sequence_config_t * | 输入 | 配置结构体指针,不能为NULL |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
IM_ERR_BUSY | 目标资源或序列忙 |
| 底层DMA错误 | DMA handle打开或配置失败时,透传DMA HAL返回的错误码 |
补充说明:
参数约束:
hadc和config不能为NULL;SEQ0只支持软件触发、不支持DMA/连续;SEQ2不支持连续;通道07;长度SEQ0为14,SEQ1/SEQ2为1~8。目标sequence处于HAL active状态、DMA active状态或硬件busy状态时返回
IM_ERR_BUSY。重新配置SEQ1/SEQ2会先停止并释放该sequence原有DMA配置、复位sequence/FIFO,再应用新配置。
dma_enable != 0U时,本接口只保存DMA参数并打开DMA handle,不启动传输;DMA在后续start路径中启动。如果DMA handle在sequence寄存器已更新后才打开失败,本接口会返回错误,但该sequence寄存器可能已经处于新配置状态;调用方不应在未重新配置或重新初始化的前提下继续启动该sequence。
3.4.2 hal_adc_sequence_unstorage_config
error_code_t hal_adc_sequence_unstorage_config(const hal_adc_handle_t *hadc, uint32_t adc_sequence, uint8_t unstorage_mask);
功能说明: 配置SEQ1/SEQ2的非存储rank,HAL内部转换为storage mask。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | const hal_adc_handle_t * | 输入 | ADC句柄,必须绑定合法ADC实例 |
adc_sequence | uint32_t | 输入 | 目标序列,使用 HAL_ADC_SEQUENCE_0/1/2;部分接口仅支持SEQ1/SEQ2 |
unstorage_mask | uint8_t | 输入 | 调用方需保证参数符合接口约束 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
adc_sequence仅支持HAL_ADC_SEQUENCE_1/2;unstorage_mask为uint8_t,bit7:0有效。本接口不检查目标sequence是否活动;调用方应先停止该sequence,参见 7.8 配置修改时机与资源所有权。
3.5 启动、停止和轮询
3.5.1 hal_adc_start
error_code_t hal_adc_start(hal_adc_handle_t *hadc, uint32_t adc_sequence);
功能说明: 软件触发启动单个序列,不等待转换完成。若目标sequence已配置DMA,本接口先启动DMA,再触发ADC。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | hal_adc_handle_t * | 输入/输出 | ADC句柄,必须绑定合法ADC实例 |
adc_sequence | uint32_t | 输入 | 目标序列,使用 HAL_ADC_SEQUENCE_0/1/2;部分接口仅支持SEQ1/SEQ2 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
IM_ERR_UNSUPPORTED | 当前配置或目标序列不支持该操作 |
IM_ERR_BUSY | 目标资源或序列忙 |
| 底层DMA错误 | DMA handle打开或传输启动失败时,透传DMA HAL返回的错误码 |
补充说明:
参数约束:
adc_sequence为HAL_ADC_SEQUENCE_0/1/2;目标序列必须已配置为软件触发。ADC硬件start位只适用于软件触发序列。
外部触发序列应由TCU/PWM等外部触发源启动。
本接口不使能ADC中断;需要完成/错误中断时使用
hal_adc_start_it()。DMA启动失败时不触发ADC,并返回DMA接口错误码。
3.5.2 hal_adc_start_multi
error_code_t hal_adc_start_multi(hal_adc_handle_t *hadc, uint32_t sequence_mask);
功能说明: 软件触发同时启动多个序列。被选sequence中已配置的DMA会在ADC multi-start前逐一启动。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | hal_adc_handle_t * | 输入/输出 | ADC句柄,必须绑定合法ADC实例 |
sequence_mask | uint32_t | 输入 | bit0/bit1/bit2分别选择SEQ0/SEQ1/SEQ2,必须至少选择一个有效序列 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
IM_ERR_UNSUPPORTED | 当前配置或目标序列不支持该操作 |
IM_ERR_BUSY | 目标资源或序列忙 |
| 底层DMA错误 | DMA handle打开或传输启动失败时,透传DMA HAL返回的错误码 |
补充说明:
参数约束:
sequence_mask使用bit0/1/2选择SEQ0/1/2;被选序列必须均为软件触发。任一DMA启动失败时,HAL会停止本次已启动的其他DMA,不触发ADC multi-start,并返回错误码。
本接口不使能ADC中断;需要完成/错误中断时使用
hal_adc_start_multi_it()。当前
hal_adc_start_multi()不会像hal_adc_start()那样在启动前清除所选sequence的data-ready和错误状态。复用sequence时,应先停止或重新配置目标sequence,不应依赖multi-start清理旧状态。
3.5.3 hal_adc_stop
error_code_t hal_adc_stop(hal_adc_handle_t *hadc, uint32_t adc_sequence);
功能说明: 停止指定sequence。SEQ1/SEQ2处于DMA模式时同时停止DMA传输并关闭ADC侧DMA请求,然后复位sequence/FIFO。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | hal_adc_handle_t * | 输入/输出 | ADC句柄,必须绑定合法ADC实例 |
adc_sequence | uint32_t | 输入 | 目标序列,使用 HAL_ADC_SEQUENCE_0/1/2;部分接口仅支持SEQ1/SEQ2 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
adc_sequence为HAL_ADC_SEQUENCE_0/1/2。本接口保留sequence配置和DMA buffer/长度/模式/descriptor配置,后续可再次调用
hal_adc_start()。本接口不管理ADC中断;由
hal_adc_stop_it()关闭对应中断。
3.5.4 hal_adc_stop_multi
error_code_t hal_adc_stop_multi(hal_adc_handle_t *hadc, uint32_t sequence_mask);
功能说明:
停止mask选中的多个sequence;对DMA sequence执行与 hal_adc_stop() 相同的停止动作,并保留配置。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | hal_adc_handle_t * | 输入/输出 | ADC句柄,必须绑定合法ADC实例 |
sequence_mask | uint32_t | 输入 | bit0/bit1/bit2分别选择SEQ0/SEQ1/SEQ2,必须至少选择一个有效sequence |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
本接口保留所选sequence及其DMA配置,后续可再次调用
hal_adc_start_multi()。本接口不管理ADC中断;由
hal_adc_stop_multi_it()关闭对应中断。
3.5.5 hal_adc_poll_for_conversion
error_code_t hal_adc_poll_for_conversion(hal_adc_handle_t *hadc, uint32_t adc_sequence, uint32_t timeout_us);
功能说明: 轮询等待指定序列数据准备,并检测错误状态。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | hal_adc_handle_t * | 输入/输出 | ADC句柄,必须绑定合法ADC实例 |
adc_sequence | uint32_t | 输入 | 目标序列,使用 HAL_ADC_SEQUENCE_0/1/2;部分接口仅支持SEQ1/SEQ2 |
timeout_us | uint32_t | 输入 | 超时时间,单位微秒 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
IM_ERR_NOT_READY | systick未初始化,或检测到硬件错误 |
IM_ERR_TIMEOUT | 等待超时 |
补充说明:
参数约束:
timeout_us为超时时间,单位微秒;依赖SDK systick时间基准。timeout_us == 0U时立即返回IM_ERR_TIMEOUT并锁存HAL_ADC_ERROR_EOC_TIMEOUT。systick未初始化时返回
IM_ERR_NOT_READY,不进入轮询。轮询超时时会进入
HAL_ADC_STATE_TIMEOUT并锁存HAL_ADC_ERROR_EOC_TIMEOUT,目标sequence的HAL active状态可能仍然保留,调用方应在恢复流程中停止或重新配置该sequence。本接口只等待data-ready,不读取数据。
3.6 数据读取
3.6.1 hal_adc_data_get
error_code_t hal_adc_data_get(const hal_adc_handle_t *hadc, uint32_t adc_sequence, hal_adc_data_t *data_out, uint32_t length);
功能说明:
批量读取指定序列转换结果并解包为 hal_adc_data_t。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | const hal_adc_handle_t * | 输入 | ADC句柄,必须绑定合法ADC实例 |
adc_sequence | uint32_t | 输入 | 目标序列,使用 HAL_ADC_SEQUENCE_0/1/2;部分接口仅支持SEQ1/SEQ2 |
data_out | hal_adc_data_t * | 输出 | 采样数据输出数组,不能为NULL |
length | uint32_t | 输入 | 期望读取的数据个数,不能为0,且不能超过目标序列最大长度 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
data_out不能为NULL;length不能为0;读取数量受序列最大长度限制;读取前调用方必须先确认data-ready。调用方必须在调用前通过
hal_adc_poll_for_conversion()、中断回调或DMA事件确认数据已经准备好。本接口不做data-ready防御性检查。
length只与sequence最大长度比较,不核对当前channel_count或storage_mask;调用方应保证读取范围与实际配置有效rank一致。读取完成后会清除对应序列data-ready状态。
3.6.2 hal_adc_value_get
error_code_t hal_adc_value_get(const hal_adc_handle_t *hadc, uint32_t adc_sequence, uint8_t rank, uint32_t *value_out);
功能说明: 读取指定序列指定rank的12bit转换值。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | const hal_adc_handle_t * | 输入 | ADC句柄,必须绑定合法ADC实例 |
adc_sequence | uint32_t | 输入 | 目标序列,使用 HAL_ADC_SEQUENCE_0/1/2;部分接口仅支持SEQ1/SEQ2 |
rank | uint8_t | 输入 | 目标rank,SEQ0范围03,SEQ1/SEQ2范围07 |
value_out | uint32_t * | 输出 | 12bit采样值输出指针,不能为NULL |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
rank为uint8_t;SEQ0范围03,SEQ1/SEQ2范围07;value_out不能为NULL。rank只与sequence最大长度比较,不核对当前channel_count或storage_mask;超出实际有效rank时可能读到旧值。本接口不清除sequence的data-ready状态。
3.6.3 hal_adc_channel_value_get
error_code_t hal_adc_channel_value_get(hal_adc_handle_t *hadc, uint8_t channel, uint32_t *value_out, uint32_t timeout_us);
功能说明: 使用SEQ0完成单通道软件触发采样,适合低频单点读取。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | hal_adc_handle_t * | 输入/输出 | ADC句柄,必须绑定合法ADC实例 |
channel | uint8_t | 输入 | ADC通道号,范围0~7 |
value_out | uint32_t * | 输出 | 12bit采样值输出指针,不能为NULL |
timeout_us | uint32_t | 输入 | 超时时间,单位微秒 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
IM_ERR_NOT_READY | 硬件错误或数据未就绪 |
IM_ERR_TIMEOUT | 在 timeout_us 内未完成转换 |
IM_ERR_BUSY | SEQ0当前active或硬件busy |
补充说明:
参数约束:
channel为uint8_t,范围0~7;value_out不能为NULL;timeout_us单位微秒。本接口内部使用SEQ0,会覆盖SEQ0原有配置。
3.7 中断模式
3.7.1 hal_adc_start_it
error_code_t hal_adc_start_it(hal_adc_handle_t *hadc, uint32_t adc_sequence);
功能说明: 根据目标sequence是否配置DMA,使能对应的普通完成或DMA完成/错误中断,并通过统一start路径软件触发转换。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | hal_adc_handle_t * | 输入/输出 | ADC句柄,必须绑定合法ADC实例 |
adc_sequence | uint32_t | 输入 | 目标序列,使用 HAL_ADC_SEQUENCE_0/1/2;部分接口仅支持SEQ1/SEQ2 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
IM_ERR_UNSUPPORTED | 目标sequence不是软件触发 |
IM_ERR_BUSY | 目标sequence或DMA资源忙 |
补充说明:
参数约束:
adc_sequence为HAL_ADC_SEQUENCE_0/1/2;sequence必须为软件触发。DMA已配置时使能
DMA_FIN、DATA_OVR、EVT_OVR和全局PHY_EOC_ERR;未配置DMA时使能普通DR/EOQ、sequence错误和全局PHY_EOC_ERR。启动失败时会回滚本次使能的中断。
3.7.2 hal_adc_start_multi_it
error_code_t hal_adc_start_multi_it(hal_adc_handle_t *hadc, uint32_t sequence_mask);
功能说明:
为mask选中的sequence统一使能普通或DMA完成/错误中断,然后调用 hal_adc_start_multi() 启动。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | hal_adc_handle_t * | 输入/输出 | ADC句柄,必须绑定合法ADC实例 |
sequence_mask | uint32_t | 输入 | bit0/bit1/bit2分别选择SEQ0/SEQ1/SEQ2,必须至少选择一个有效sequence |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
IM_ERR_UNSUPPORTED | 任一被选sequence不是软件触发 |
IM_ERR_BUSY | 任一被选sequence或DMA资源忙 |
补充说明:
每个sequence的中断mask由其DMA配置决定,并统一使能全局
PHY_EOC_ERR。hal_adc_start_it()是该接口的单sequence封装。启动失败时会回滚本次使能的全部中断。
本接口沿用
hal_adc_start_multi()的状态清理约束;复用sequence前应先停止或重新配置目标sequence。
3.7.3 hal_adc_stop_it
error_code_t hal_adc_stop_it(hal_adc_handle_t *hadc, uint32_t adc_sequence);
功能说明: 屏蔽指定sequence对应的普通或DMA中断,停止sequence/DMA,并保留配置。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | hal_adc_handle_t * | 输入/输出 | ADC句柄,必须绑定合法ADC实例 |
adc_sequence | uint32_t | 输入 | 目标序列,使用 HAL_ADC_SEQUENCE_0/1/2;部分接口仅支持SEQ1/SEQ2 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
adc_sequence为HAL_ADC_SEQUENCE_0/1/2。hal_adc_stop_it()是hal_adc_stop_multi_it()的单sequence封装。若停止后仍有其他active sequence,全局
PHY_EOC_ERR中断保持使能。
3.7.4 hal_adc_stop_multi_it
error_code_t hal_adc_stop_multi_it(hal_adc_handle_t *hadc, uint32_t sequence_mask);
功能说明: 关闭mask选中的普通或DMA中断,停止对应sequence/DMA,并保留sequence和DMA配置。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | hal_adc_handle_t * | 输入/输出 | ADC句柄,必须绑定合法ADC实例 |
sequence_mask | uint32_t | 输入 | bit0/bit1/bit2分别选择SEQ0/SEQ1/SEQ2,必须至少选择一个有效sequence |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
只有停止后没有其他active sequence时,才同时关闭共享的
PHY_EOC_ERR中断。本接口直接复用内部sequence停止逻辑,不经过普通单sequence stop接口。
3.7.5 hal_adc_irq_handler
void hal_adc_irq_handler(hal_adc_handle_t *hadc);
功能说明: ADC中断服务入口,由BSP ISR调用,分发SEQ完成、DMA完成、AWD和ERROR回调并清除中断标志。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | hal_adc_handle_t * | 输入/输出 | ADC句柄,必须绑定合法ADC实例 |
返回值表:
| 返回值 | 说明 |
|---|---|
| 无 | 接口不返回状态码 |
补充说明:
参数约束:
hadc必须有效;无效时直接返回。本接口分发的业务回调运行在中断上下文,不得阻塞或执行耗时操作,参见 7.9 回调与中断上下文。
DMA完成时HAL会对目标buffer执行cache invalidate;single DMA完成后清除对应active状态,cyclic DMA保持active直到显式stop。
ADC错误会更新
error_code/state并调用ERROR回调;全局PHY_EOC_ERR按ADC级错误处理。
3.7.6 hal_adc_callback_register
error_code_t hal_adc_callback_register(hal_adc_handle_t *hadc, hal_adc_callback_id_t callback_id, hal_adc_callback_t callback);
功能说明: 注册或恢复普通ADC回调函数。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | hal_adc_handle_t * | 输入/输出 | ADC句柄,必须绑定合法ADC实例 |
callback_id | hal_adc_callback_id_t | 输入 | 回调ID,使用 HAL_ADC_CALLBACK_* 枚举值 |
callback | hal_adc_callback_t | 输入 | 回调函数指针;传NULL表示恢复默认空回调 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
callback_id使用hal_adc_callback_id_t;callback类型为hal_adc_callback_t;callback == NULL表示恢复默认空回调。
3.7.7 hal_adc_awd_callback_register
error_code_t hal_adc_awd_callback_register(hal_adc_handle_t *hadc, hal_adc_awd_callback_t callback);
功能说明: 注册或恢复AWD回调函数。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | hal_adc_handle_t * | 输入/输出 | ADC句柄,必须绑定合法ADC实例 |
callback | hal_adc_awd_callback_t | 输入 | 回调函数指针;传NULL表示恢复默认空回调 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
callback类型为hal_adc_awd_callback_t;callback == NULL表示恢复默认空回调。
3.8 DMA 配置和状态
3.8.1 DMA 生命周期
DMA不是独立的ADC启动模式,而是SEQ1/SEQ2 sequence配置的一部分。公开调用流程如下:
hal_adc_sequence_config(hadc, &config); hal_adc_start(hadc, adc_sequence); /* 或 hal_adc_start_multi() */ hal_adc_stop(hadc, adc_sequence); /* 或 hal_adc_stop_multi() */
需要ADC完成/错误中断时,启动和停止分别使用对应的IT接口:
hal_adc_start_it(hadc, adc_sequence); /* 或 hal_adc_start_multi_it() */ hal_adc_stop_it(hadc, adc_sequence); /* 或 hal_adc_stop_multi_it() */
行为说明:
hal_adc_sequence_config()根据dma_enable/dma_buffer/dma_len/dma_mode/dma_desc/dma_desc_count保存DMA配置并打开DMA handle,但不启动传输。普通和DMA sequence统一由
hal_adc_start()/hal_adc_start_multi()启动;HAL保证先启动DMA,再触发ADC。hal_adc_start_it()/hal_adc_start_multi_it()只在统一start路径之外增加中断配置,不重复配置DMA生命周期。hal_adc_stop()/hal_adc_stop_multi()停止当前DMA传输并关闭ADC侧DMA请求,但保留buffer、长度、模式、descriptor和DMA handle,以便再次start。重新调用
hal_adc_sequence_config()配置同一sequence或调用hal_adc_deinit()时,HAL才释放原DMA handle并清除运行配置。当前DMA传输只能通过
hal_adc_start()/hal_adc_start_multi()激活,因此公开HAL流程中的DMA-enabled sequence必须配置为软件触发;当前没有供外部触发DMA使用的prepare-only启动接口。
3.8.2 hal_adc_dma_read_counter_get
error_code_t hal_adc_dma_read_counter_get(const hal_adc_handle_t *hadc, uint32_t adc_sequence, uint32_t *counter_out);
功能说明: 读取SEQ1/SEQ2 DMA读计数寄存器。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | const hal_adc_handle_t * | 输入 | ADC句柄,必须绑定合法ADC实例 |
adc_sequence | uint32_t | 输入 | 目标序列,使用 HAL_ADC_SEQUENCE_0/1/2;部分接口仅支持SEQ1/SEQ2 |
counter_out | uint32_t * | 输出 | DMA读计数输出指针,不能为NULL |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
counter_out不能为NULL;adc_sequence仅支持HAL_ADC_SEQUENCE_1/2。本接口不检查DMA是否已配置或正在运行,只返回对应DMA读计数寄存器的原始值;计数单位、回绕和清零时机由硬件及当前传输模式决定,HAL不在软件层换算。
3.9 模拟看门狗
3.9.1 hal_adc_awd_config
error_code_t hal_adc_awd_config(const hal_adc_handle_t *hadc, const hal_adc_awd_config_t *config);
功能说明: 配置单通道AWD阈值、低/高阈值检测使能、中断使能和fail输出使能。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | const hal_adc_handle_t * | 输入 | ADC句柄,必须绑定合法ADC实例 |
config | const hal_adc_awd_config_t * | 输入 | 配置结构体指针,不能为NULL |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
channel范围07;阈值0HAL_ADC_THRESHOLD_MAX;low_threshold <= high_threshold;enable字段只能为0或1。
3.9.2 hal_adc_awd_threshold_set
error_code_t hal_adc_awd_threshold_set(const hal_adc_handle_t *hadc, uint8_t channel, uint16_t low_threshold, uint16_t high_threshold);
功能说明: 只更新指定通道AWD高低阈值,不改变低/高阈值检测、中断或fail使能状态。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | const hal_adc_handle_t * | 输入 | ADC句柄,必须绑定合法ADC实例 |
channel | uint8_t | 输入 | ADC通道号,范围0~7 |
low_threshold | uint16_t | 输入 | AWD低阈值,范围0~`HAL_ADC_THRESHOLD_MAX` |
high_threshold | uint16_t | 输入 | AWD高阈值,范围0~`HAL_ADC_THRESHOLD_MAX`,且不小于低阈值 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
channel为uint8_t,范围07;阈值0HAL_ADC_THRESHOLD_MAX;low_threshold <= high_threshold。
3.9.3 hal_adc_awd_enable
error_code_t hal_adc_awd_enable(const hal_adc_handle_t *hadc, uint8_t channel, uint32_t detect_mask);
功能说明: 使能指定通道低阈值和/或高阈值检测。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | const hal_adc_handle_t * | 输入 | ADC句柄,必须绑定合法ADC实例 |
channel | uint8_t | 输入 | ADC通道号,范围0~7 |
detect_mask | uint32_t | 输入 | AWD检测类型,使用 HAL_ADC_AWD_DETECT_LOW/HIGH/BOTH |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
channel范围0~7;detect_mask使用HAL_ADC_AWD_DETECT_LOW/HIGH/BOTH。
3.9.4 hal_adc_awd_disable
error_code_t hal_adc_awd_disable(const hal_adc_handle_t *hadc, uint8_t channel, uint32_t detect_mask);
功能说明: 关闭指定通道低阈值和/或高阈值检测。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | const hal_adc_handle_t * | 输入 | ADC句柄,必须绑定合法ADC实例 |
channel | uint8_t | 输入 | ADC通道号,范围0~7 |
detect_mask | uint32_t | 输入 | AWD检测类型,使用 HAL_ADC_AWD_DETECT_LOW/HIGH/BOTH |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
channel范围0~7;detect_mask使用HAL_ADC_AWD_DETECT_LOW/HIGH/BOTH。
3.9.5 hal_adc_awd_status_get
error_code_t hal_adc_awd_status_get(const hal_adc_handle_t *hadc, uint32_t *low_flags_out, uint32_t *high_flags_out);
功能说明: 读取AWD低/高阈值触发通道flag。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | const hal_adc_handle_t * | 输入 | ADC句柄,必须绑定合法ADC实例 |
low_flags_out | uint32_t * | 输出 | 低阈值触发通道flag输出,可为NULL |
high_flags_out | uint32_t * | 输出 | 高阈值触发通道flag输出,可为NULL |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
low_flags_out和high_flags_out至少一个非NULL;输出flag使用HAL_ADC_AWD_CHANNEL_FLAG()或HAL_ADC_AWD_CHANNEL_FLAG_ALL语义。
3.9.6 hal_adc_awd_status_clear
error_code_t hal_adc_awd_status_clear(const hal_adc_handle_t *hadc, uint32_t low_flags, uint32_t high_flags);
功能说明: 清除AWD低/高阈值触发flag,并在有flag时同步清除ADC总AWD中断状态。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | const hal_adc_handle_t * | 输入 | ADC句柄,必须绑定合法ADC实例 |
low_flags | uint32_t | 输入 | 待清除低阈值flag,bit7:0有效 |
high_flags | uint32_t | 输入 | 待清除高阈值flag,bit7:0有效 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
low_flags/high_flags只允许bit7:0;使用HAL_ADC_AWD_CHANNEL_FLAG()或HAL_ADC_AWD_CHANNEL_FLAG_ALL。
3.9.7 hal_adc_awd_fail_enable
error_code_t hal_adc_awd_fail_enable(const hal_adc_handle_t *hadc, uint8_t channel, uint32_t detect_mask);
功能说明: 使能指定通道AWD fail输出。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | const hal_adc_handle_t * | 输入 | ADC句柄,必须绑定合法ADC实例 |
channel | uint8_t | 输入 | ADC通道号,范围0~7 |
detect_mask | uint32_t | 输入 | AWD检测类型,使用 HAL_ADC_AWD_DETECT_LOW/HIGH/BOTH |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
channel范围0~7;detect_mask使用HAL_ADC_AWD_DETECT_LOW/HIGH/BOTH。
3.9.8 hal_adc_awd_fail_disable
error_code_t hal_adc_awd_fail_disable(const hal_adc_handle_t *hadc, uint8_t channel, uint32_t detect_mask);
功能说明: 屏蔽指定通道AWD fail输出。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | const hal_adc_handle_t * | 输入 | ADC句柄,必须绑定合法ADC实例 |
channel | uint8_t | 输入 | ADC通道号,范围0~7 |
detect_mask | uint32_t | 输入 | AWD检测类型,使用 HAL_ADC_AWD_DETECT_LOW/HIGH/BOTH |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
channel范围0~7;detect_mask使用HAL_ADC_AWD_DETECT_LOW/HIGH/BOTH。
3.10 调试、状态和错误查询
3.10.1 hal_adc_regs_dump
error_code_t hal_adc_regs_dump(const hal_adc_handle_t *hadc);
功能说明: 打印ADC全部常规寄存器值,FIFO寄存器默认跳过。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | const hal_adc_handle_t * | 输入 | ADC句柄,必须绑定合法ADC实例 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
IM_ERR_UNSUPPORTED | Debug helper在构建配置中未使能 |
补充说明:
参数约束:
hadc必须有效;HAL_ADC_DUMP_READ_FIFO != 0U时才读取SEQ1/SEQ2 FIFO。默认不读取SEQ1/SEQ2 FIFO,避免dump时改变硬件状态。
如需读取FIFO,由
HAL_ADC_DUMP_READ_FIFO宏控制。该接口只有同时开启
CONFIG_SDK_ENABLE_DEBUG_HELPERS和CONFIG_ADC_ENABLE_DEBUG_HELPERS时才访问寄存器并输出日志。
3.10.2 hal_adc_state_get
error_code_t hal_adc_state_get(const hal_adc_handle_t *hadc, hal_adc_state_t *state_out);
功能说明: 获取HAL ADC模块级运行状态。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | const hal_adc_handle_t * | 输入 | ADC句柄,必须绑定合法ADC实例 |
state_out | hal_adc_state_t * | 输出 | 状态输出指针,不能为NULL |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 接口执行成功 |
IM_ERR_INVALID_PARAM | 参数非法 |
补充说明:
参数约束:
hadc必须有效;state_out不能为NULL。若
active_sequence_mask非0且当前状态不是ERROR、RESET或TIMEOUT,接口返回HAL_ADC_STATE_BUSY;否则返回句柄记录的原始状态。
3.10.3 hal_adc_active_sequence_mask_get
uint32_t hal_adc_active_sequence_mask_get(const hal_adc_handle_t *hadc);
功能说明: 获取HAL跟踪的活跃序列mask。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | const hal_adc_handle_t * | 输入 | ADC句柄,必须绑定合法ADC实例 |
返回值表:
| 返回值 | 说明 |
|---|---|
uint32_t | bit0/1/2分别对应SEQ0/SEQ1/SEQ2。 |
补充说明:
参数约束:
hadc无效时返回0。
3.10.4 hal_adc_error_get
uint32_t hal_adc_error_get(const hal_adc_handle_t *hadc);
功能说明: 获取HAL ADC错误flag。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
hadc | const hal_adc_handle_t * | 输入 | ADC句柄,必须绑定合法ADC实例 |
返回值表:
| 返回值 | 说明 |
|---|---|
uint32_t | 有效时返回 hadc->error_code;无效时返回 HAL_ADC_ERROR_INVALID_PARAM。 |
补充说明:
参数约束:
hadc无效时不访问硬件。本接口只读取锁存错误,不清除历史;错误清除和恢复路径参见 7.7 状态迁移、错误锁存与恢复。
4. 当前实现约束与行为说明
4.1 SOC 额外周期
| 参数 | 约束 |
|---|---|
soc_extra_cycle / cycle | 必须为 hal_adc_soc_extra_cycle_t 中定义的离散值。 |
| 有效值 | HAL_ADC_SOC_EXTRA_CYCLE_0/5/10/15/30/45/60/210。 |
| 修改时机 | SPEC要求禁止在 SEQ0/SEQ1/SEQ2 工作期间配置 SOC_EXT_CYCLE。 |
4.2 DMA 注意事项
DMA模式只支持
SEQ1和SEQ2。ADC HAL已接入DMA控制器,DMA request使用
ADCx_SEQy_RX,bus width为32-bit,unit size为4字节。HAL_ADC_DMA_MODE_SINGLE使用非descriptor DMA;HAL_ADC_DMA_MODE_CYCLIC使用调用方提供的descriptor存储。DMA参数统一通过
hal_adc_sequence_config()的dma_enable/dma_buffer/dma_len/dma_mode/dma_desc/dma_desc_count配置,不再提供独立的ADC DMA start/stop接口。软件触发DMA统一使用
hal_adc_start()/hal_adc_start_multi();需要ADC DMA完成/错误中断时使用对应的*_it接口。当前DMA传输只能由统一start路径激活,因此DMA-enabled sequence必须使用软件触发;外部触发DMA当前没有公开的prepare-only启动入口。
cyclic模式下
dma_desc和dma_desc_count必须有效,descriptor存储必须保持有效直到该sequence重新配置或ADC deinit。hal_adc_stop()/hal_adc_stop_multi()只停止当前DMA并保留配置,可直接再次start;重新配置同一sequence或deinit才释放DMA配置。DMA启动前HAL维护目标buffer cache,DMA完成中断中再次维护一次,停止路径(stop/deinit/重新配置)再维护一次,因此 stop 返回后可直接读取目标 buffer;DMA active 期间调用方不得写入该buffer,读取也可能读到部分更新的数据。
SEQn_DMA_RCNT可通过hal_adc_dma_read_counter_get()读取,软件可比较前后两次计数值判断进度;有效长度换算需要结合硬件计数单位并处理回绕。
4.3 实现约束
LL层只做寄存器访问封装,公开接口均为
static inline,不依赖RTOS、不申请内存、不调用DMA驱动。HAL层当前依赖公共错误码、参数检查、日志组件、微秒时间基准、cache维护接口和DMA HAL;IRQ入口由BSP ISR调用。
hal_adc_irq_handler()先读取一次ADC_IR快照并处理错误;DMA完成flag在cache处理和回调前单独清除,其余已处理flag在本次IRQ末尾统一清除。高频采样场景应优先使用
SEQ1/SEQ2 + DMA,避免CPU读取FIFO过慢导致DATA_OVR;或者CPU模式下直接读取对应序列的数据寄存器。
4.4 状态迁移、错误锁存与恢复
HAL 运行状态是软件状态,活动序列则由 active_sequence_mask 单独跟踪。主要变化如下:
| 操作或事件 | state 变化 | active_sequence_mask | error_code |
|---|---|---|---|
hal_adc_handle_init() | RESET | 清零 | 清零 |
hal_adc_init() | READY | 清零 | 清零 |
hal_adc_start*() 在正常READY路径成功启动 | BUSY | 置位所选序列 | 通常保持;DMA启动失败时锁存 HAL_ADC_ERROR_DMA |
| 轮询成功 | 无其他活动序列时为 READY,否则为 BUSY | 清除目标序列 | 保持 |
| 轮询超时 | TIMEOUT | 目标序列可能仍为活动 | 锁存 HAL_ADC_ERROR_EOC_TIMEOUT |
| 轮询或IRQ检测到硬件错误 | ERROR | 清零 | 锁存对应错误位 |
从 TIMEOUT 调用stop | 无其他活动序列时回到 READY,否则为 BUSY | 清除被停止序列 | 历史错误保持 |
从 ERROR 调用stop | 保持 ERROR | 清除被停止序列 | 历史错误保持 |
hal_adc_deinit() | RESET | 清零 | 清零 |
恢复说明:
TIMEOUT后应停止或重新配置目标序列;此后可以再次启动,但HAL_ADC_ERROR_EOC_TIMEOUT会保留在error_code中。硬件错误进入
ERROR后,当前公开接口没有单独清除错误状态的 API。完整恢复路径为hal_adc_deinit()、hal_adc_handle_init()、重新设置配置并调用hal_adc_init()。hal_adc_start*()当前不会单独拒绝ERROR状态;应用不应依赖start接口完成错误恢复,必须先执行上述恢复流程。hal_adc_error_get()只读取锁存值,不清除错误历史。DMA-enabled sequence 应通过DMA完成回调或相应等待逻辑判断传输结束。
hal_adc_poll_for_conversion()只观察sequence数据就绪状态,不替代DMA停止或完成处理。
4.5 回调与中断上下文
hal_adc_irq_handler()由BSP ISR调用,注册的sequence完成、DMA完成、AWD和error回调可能运行在ADC IRQ 上下文。回调不得阻塞、睡眠、等待互斥锁或执行重日志;耗时处理应转交任务上下文。
DMA完成flag在回调前清除,目标buffer在回调前执行cache invalidate;single DMA完成后HAL清除对应active状态,cyclic DMA保持active直到显式stop。
AWD回调中的
low_flags/high_flags已解码到bit7:0,分别对应通道0~7。调用方需要通过
hadc->user_data传递业务上下文,HAL不会解释该指针。
5. 示例程序与使用方式
5.1 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);5.2 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。
5.3 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。
5.4 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));6. HAL 错误码与错误标志
本节汇总 HAL 错误相关约定。公共返回码含义参考 3.4 HAL 返回状态约定,下表列出 hal_adc_error_get() 读取的锁存标志。
ADC HAL私有错误标志通过 hal_adc_error_get() 读取,字段定义见 hal_adc_error_t。
error_code_t 表示当前API调用的结果;hadc->error_code 是锁存的运行期诊断状态。参数检查失败通常只返回 IM_ERR_INVALID_PARAM,不会自动写入锁存错误。hal_adc_error_get() 不清除历史错误,hal_adc_handle_init()、hal_adc_init() 和 hal_adc_deinit() 会将 error_code 清零。
| 错误标志 | 说明 | 常见触发场景 |
|---|---|---|
HAL_ADC_ERROR_NONE | 无HAL私有错误。 | hal_adc_handle_init()、成功的 hal_adc_init() 或 hal_adc_deinit() 清空错误历史后。 |
HAL_ADC_ERROR_INVALID_PARAM | 非法handle的查询返回哨兵,不是普通参数错误的历史记录。 | hal_adc_error_get() 收到NULL handle或未绑定合法ADC实例的handle。普通参数检查失败应查看当前API返回值。 |
HAL_ADC_ERROR_EOC_TIMEOUT | HAL记录的轮询超时flag。 | hal_adc_poll_for_conversion() 在 timeout_us 内未等到数据准备。 |
HAL_ADC_ERROR_DATA_OVERRUN | HAL记录的数据溢出flag。 | SEQ1/SEQ2数据读取不及时,或FIFO/DMA路径未及时搬运。 |
HAL_ADC_ERROR_EVENT_OVERRUN | HAL记录的事件溢出flag。 | 序列未结束时再次触发,或外部触发事件与当前序列状态冲突。 |
HAL_ADC_ERROR_PHY_EOC | HAL记录的PHY EOC错误flag。 | ADC PHY转换结束状态异常。 |
HAL_ADC_ERROR_DMA | HAL记录的DMA错误flag。 | hal_adc_start() / hal_adc_start_multi() 的统一start路径中,DMA handle打开或传输启动失败。 |