高精度 ADC(HADC)
HADC(High-precision ADC)是 AC82N 芯片内置的高精度 Sigma-Delta 模数转换器,配合可编程增益放大器(PGA)、运算放大器(OPA)、功率放大器(PA)、体脂测量通道(VBIM)以及多级电源域(AVDDCP/AVDDR/AVBG/AVCM),用于采集微弱模拟信号(如体脂秤电桥信号、温度传感器信号、电池电压等),并通过两级 CIC 抽取滤波器输出可配置采样率的数字结果。
Purpose and Scope
本页面向应用开发者与驱动维护者,完整说明 HADC 外设驱动(sdk/cpu/cd09/hadc/)的:
- 电源域初始化链(AVDDCP → AVDDR → AVBG → AVCM)的先后顺序与设计意图;
- 模拟前端(PGA/OPA/PA/VBIM/温度传感器)的通道选择与增益配置;
- 数字信号链(时钟、CIC0/CIC1 抽取滤波器、过采样率与输出频率计算);
- 数据采集机制(DMA 点数、ISR 回调、启动/停止/关闭生命周期);
- 对外 API 的完整签名、参数语义与调用约束;
- 运行期切换输出频率、快速启动等进阶用法。
页面边界:本页只覆盖 HADC 外设本身。芯片通用 GPIO、中断控制器(interrupt)、DMA 控制器、电源管理(软关机/唤醒)等基础设施属于其他外设页面,本页仅在其与 HADC 交互的边界处提及。HADC 通常与定时器(timer)、音频 codec 等协同的整机应用流程也不在本页展开。
Overview
HADC 采用 Sigma-Delta 过采样架构:模拟前端先把微弱差分信号通过 PGA(1~128 倍可编程增益)放大,再经过 Sigma-Delta 调制器以远高于奈奎斯特频率的速率进行 1-bit 量化,最后由数字端的 CIC(Cascaded Integrator-Comb)抽取滤波器完成降采样与滤波,得到高分辨率、低噪声的采样结果。这种架构的优势在于:
- 高分辨率:配合抽取滤波,有效分辨率远高于普通 SAR ADC;
- 抗混叠:过采样 + CIC 滤波天然抑制带外噪声,简化模拟抗混叠电路;
- 可配置输出频率:通过调整 CIC0/CIC1 的抽取因子,输出频率可在约 15 Hz ~ 7.7 kHz 范围内灵活选择,兼顾分辨率与刷新率。
驱动对外暴露一组分层 API:
- 电源域 API(
hadc_avddcp_config/hadc_avddr_config/hadc_avbg_config/hadc_avcm_config):按固定顺序建立模拟电源; - 模拟前端 API(
hadc_pga_config/hadc_opa_config/hadc_pa_config/hadc_vbim_config/hadc_temp_sensor_config):选择输入通道与增益; - 数字核心 API(
hadc_open/hadc_start/hadc_stop/hadc_close/hadc_set_out_freq):控制采样生命周期与输出频率。
标准使用流程见 hadc_demo.c:先开电源,再配 PGA 通道,然后 hadc_open 装载平台参数、hadc_start 启动采集,数据经 ISR 回调上送;停止时按相反顺序关闭。
Architecture
flowchart TD
subgraph sg_ANALOG["模拟前端 Analog Frontend"]
AIN["AIN0~AIN7 模拟输入"] --> PGA["PGA<br/>增益 X1~X128"]
OPA["OPA 运算放大器<br/>体脂通道 MUXI/MUXO"]
PA["PA 功率放大器<br/>增益 -14db~0db"]
VBIM["VBIM 体脂测量通道"]
TEMP["内部温度传感器"]
PGA --> MUXP["MUX P/N 通道选择<br/>hadc_muxp_sel / hadc_muxn_sel"]
OPA --> MUXP
PA --> MUXP
VBIM --> MUXP
TEMP --> MUXP
end
subgraph sg_POWER["电源域 Power Domain"]
AVDDCP["AVDDCP<br/>3.40V~3.75V 升压"]
AVDDR["AVDDR<br/>2.7V~3.4V"]
AVBG["AVBG 带隙基准<br/>faston_en / with_cap"]
AVCM["AVCM 共模电压<br/>with_cap"]
AVDDCP --> AVDDR --> AVBG --> AVCM
end
subgraph sg_DIGITAL["数字后端 Digital Backend"]
MUXP --> SD["Sigma-Delta 调制器<br/>clock ≤ 1MHz"]
SD --> CIC0["CIC0 抽取滤波器<br/>dsr0 8~254, order 3/4/5"]
CIC0 --> CIC1["CIC1 抽取滤波器<br/>dsr1 2~64, order 2/3/4"]
CIC1 --> DMA["DMA 搬运<br/>points × 4 bytes"]
DMA --> ISR["hadc_isr 中断<br/>isr_cb 回调"]
end
ISR --> APP["应用层<br/>printf / 数据处理"]
style sg_ANALOG fill:#e8f0fe,stroke:#4285f4
style sg_POWER fill:#fef7e0,stroke:#f9ab00
style sg_DIGITAL fill:#e6f4ea,stroke:#188038
架构说明:
- 电源域(黄色) 是 HADC 正常工作的前提,必须按
avddcp → avddr → avbg → avcm顺序依次上电(hadc.h 电源初始化顺序注释)。AVDDCP 提供最高电压轨,AVDDR 供模拟电路,AVBG 是带隙基准(正常上电稳定时间约 800ms),AVCM 提供共模电平。 - 模拟前端(蓝色) 提供多种信号调理路径:PGA 用于通用高精度放大;OPA/PA/VBIM 组合专为体脂测量等大电流、差分激励场景设计;内部温度传感器可接入 MUX 通道
HADC_MUXP_SEL_TEMP/HADC_MUXN_SEL_TEMP。 - 数字后端(绿色) 完成调制→抽取→搬运→回调的完整链路。CIC 滤波器级联后,输出频率
Fo = clock / ((dsr0*4 + ivld_clk) * dsr1)(输出频率计算方法),DMA 按points个点搬运,每点 4 字节,触发中断后调用isr_cb(buffer, points*4)。
电源域初始化链
HADC 的模拟电路需要多级电源支撑,驱动在 hadc_analog.c 中实现各电源域的配置,并通过软件标志结构体 hadc_soft_flag_info(全局实例 hadc_soft_info,定义于 hadc_analog.c#L11)记录档位、延时、快速模式等状态,供后续启停与快速启动流程复用。
上电顺序(不可颠倒): hadc_avddcp_config → hadc_avddr_config → hadc_avbg_config → hadc_avcm_config。
| 电源域 | 配置函数 | 关键参数 | 说明 |
|---|---|---|---|
| AVDDCP | hadc_avddcp_config | mode: AVDDCP_MODE_SEL_NORMAL / AVDDCP_MODE_SEL_VPWR;vol: 3.40V~3.75V(默认 3.60V) | 升压电源,最先初始化;切换模式时须先关闭再切换 |
| AVDDR | hadc_avddr_config | vol: 2.7V~3.4V(默认 3.0V) | 在 AVDDCP 之后初始化;内部 hadc_avddr_trim 做电压微调,AVDDR_RISE_TIME_US(500us)控制上升时间,外挂电容大于 105uF 时需调节 |
| AVBG | hadc_avbg_config | faston_en: 快速上电;with_cap: 是否外挂电容 | 带隙基准,在 AVDDR 之后初始化;正常上电稳定时间约 800ms |
| AVCM | hadc_avcm_config | with_cap: 是否外挂电容 | 共模电压,在 AVBG 之后初始化 |
hadc_soft_flag_info 结构体的位域布局(hadc.h#L235-L245):
struct hadc_soft_flag_info {
u8 avddcp_short_en: 1; //AVDDCP 短路保护使能
u8 avddcp_vol_sel: 3; //AVDDCP 电压档位
u8 avddcp_delay_sel: 2; //AVDDCP 延时选择
u8 fast_adc: 1; //快速 ADC 标志
u8 avddcp_hadc_sel: 1; //AVDDCP 供 HADC 选择
u8 avddcp_clktune_sel: 4; //AVDDCP 时钟微调
u8 avddcp_clkdiv_sel: 1; //AVDDCP 时钟分频
u8 avddr_vol_sel: 3; //AVDDR 电压档位
u8 avddr_ref_sel: 4; //AVDDR 基准选择
};
Source: hadc.h
该结构体采用位域紧凑布局,使驱动可以在一次读改写中同步更新多项电源配置,避免多次寄存器访问引入中间态;fast_adc 位则配合快速启动函数使用。
模拟前端配置
PGA(可编程增益放大器)
通用采集路径,P 端/N 端各有 14 个可选输入(hadc_muxp_sel / hadc_muxn_sel),增益从 X1 到 X128 共 7 档(增益枚举):
enum hadc_gain_sel {
HADC_GAIN_SEL_X1,
HADC_GAIN_SEL_X4,
HADC_GAIN_SEL_X8 = 3,
HADC_GAIN_SEL_X16 = 5,
HADC_GAIN_SEL_X32 = 7,
HADC_GAIN_SEL_X64 = 9,
HADC_GAIN_SEL_X128 = 11,
};
Source: hadc.h
注意枚举值不连续(X8=3、X16=5…),这是为了与硬件寄存器位编码一一对应,调用者必须使用枚举符号而非连续数值。切换通道或增益时,应先关闭 PGA 再切换,避免模拟链路瞬间短路或毛刺。
OPA(运算放大器)/ PA(功率放大器)/ VBIM(体脂测量)
这三者组合服务于体脂秤等需要差分激励/大电流驱动的测量场景:
hadc_opa_config:配置 OPA 正/负端输入(hadc_opa_muxp_sel/hadc_opa_muxn_sel)、体脂信号输入通道(hadc_opa_muxi_sel,可选 AIN2/AIN6/AIN7_DACPA)、输出通道(hadc_opa_muxo_sel),并支持cmp_en比较器模式;hadc_pa_config:PA 正端输入可选 AVBG/AIN2/DACO_BIAS,负端可断开(HADC_PA_MUXN_SEL_DISABLE),增益 -14dB~0dB 每 2dB 一档;做比较器时增益无效;hadc_vbim_config:VBIM 模块通道选择(HADC_VBIM_CHL_SEL_R250/R1K/EXTERN,EXTERN 使用 AIN6 & AIN3 外部通路)。
这些模块共享同一个设计原则:配置寄存器前先关断使能,防止在通道切换瞬间产生直通电流或错误电平耦合进 ADC 输入。
内部温度传感器
hadc_temp_sensor_config 使能内部温度传感器后,MUX 即可选择 HADC_MUXP_SEL_TEMP / HADC_MUXN_SEL_TEMP 通道采集芯片温度,无需外部电路。
数字信号链
时钟与过采样率
struct hadc_platform_data.clock 指定调制器工作时钟,常设 500kHz,最大 1MHz。输出频率由抽取路径决定(计算方法):
ivld_clk = (WORK_MODE == 0) ? 5 : 0;
OSR = (dsr0 * 4 + ivld_clk) * dsr1;
Fo = clock / OSR;
例如 clock=500K, dsr0=155, dsr1=16 时 Fo = 500K / ((155*4+5)*16) = 50Hz;clock=600K 同参数则为 60Hz,可直接对齐电网工频抑制(50/60Hz 干扰)。
CIC 滤波器参数
struct cic_data {
u8 en; //cic滤波器使能
u8 dsr; //cic滤波器抽取因子选择 dsr0(8~254) dsr1(2~64)
u8 order; //order越大,需要的稳定时间越久
u8 gain; //cic滤波器输出增益 64@0db (0~127)
};
Source: hadc.h
设计意图:dsr 决定抽取比(直接影响输出频率),order 决定滤波阶数与稳定时间(阶数越高阻带衰减越好,但阶跃响应稳定越慢),gain 用于补偿 CIC 通带衰减、归一化输出幅度。头文件给出官方推荐 CIC 表(hadc.h#L204-L218):
| WORK_MODE | CLK(kHz) | EN0 | DSR0 | ORDER0 | EN1 | DSR1 | ORDER1 | OSR | Fo(Hz) |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 500 | 1 | 15 | 4 | 0 | 2 | 2 | 65 | 7692 |
| 0 | 500 | 1 | 254 | 4 | 1 | 4 | 2 | 4084 | 122 |
| 0 | 500 | 1 | 254 | 4 | 1 | 16 | 2 | 16336 | 30.6 |
| 0 | 600 | 1 | 155 | 4 | 1 | 16 | 2 | 10000 | 60 |
| 0 | 500 | 1 | 155 | 4 | 1 | 16 | 2 | 10000 | 50 |
Source: hadc.h
模式 0 对应 ivld_clk=5。CIC0 承担主要抽取(DSR0 可到 254),CIC1 承担精细抽取(DSR1 2~64),两级级联使总 OSR 在几十到三万以上连续可调——OSR 越大,等效分辨率越高但刷新率越低,开发者需按应用在两者间权衡。
生命周期管理与核心流程
状态机
stateDiagram-v2
[*] --> CLOSED: 上电复位
CLOSED --> CONFIGURED: hadc_open(data)
CONFIGURED --> RUNNING: hadc_start()
RUNNING --> PAUSED: hadc_stop()
PAUSED --> RUNNING: hadc_start()
PAUSED --> CONFIGURED: hadc_set_out_freq(cic0, cic1)
RUNNING --> CONFIGURED: hadc_close()
CONFIGURED --> CLOSED: hadc_close()
RUNNING --> [*]: hadc_analog_all_off() 省电
状态语义(来自 hadc.h API 注释):
hadc_open:初始化 HADC 模块,装载hadc_platform_data;初始化后需hadc_start才开始采样;hadc_start:启动数字逻辑,每次 open 后必须先调用;hadc_stop:仅暂停数字逻辑(模拟电路保持上电),可随时hadc_start恢复;hadc_close:彻底关闭模块,再次使用需重新hadc_open;hadc_analog_all_off:关闭全部模拟信号通路,用于省功耗场景。
hadc_stop 与 hadc_close 的区别是设计关键:暂停(stop)保留模拟电源与配置状态,恢复成本低,适合频繁启停的间歇采样;关闭(close)释放全部资源,适合长时间休眠。 快速启动路径(hadc_avbg_init_for_fast_boot / hadc_avddcp_init_for_fast_boot,实现于 hadc_analog.c#L16、L28)即为软关机快速上电场景准备,跳过 AVBG 正常 800ms 稳定等待,直接复用此前保存的电源配置。
典型启动时序
sequenceDiagram
participant APP as 应用层
participant PWR as 电源域 (hadc_analog.c)
participant AFE as 模拟前端 (PGA/OPA/PA)
participant DGT as 数字核心 (hadc_digital.c)
participant ISR as hadc_isr + isr_cb
APP->>PWR: hadc_avddcp_config(1, NORMAL, 3P60)
APP->>PWR: hadc_avddr_config(1, 3P0)
APP->>PWR: hadc_avbg_config(1, 1, 1)
APP->>PWR: hadc_avcm_config(1, 1)
Note over PWR: 顺序不可颠倒<br/>avddcp→avddr→avbg→avcm
APP->>AFE: hadc_pga_config(1, MUXP_AIN0, MUXN_AIN1, GAIN_X1)
APP->>DGT: hadc_open(&hadc_platform_data)
Note over DGT: 配置时钟/两级CIC/DMA点数<br/>注册 isr_cb
APP->>DGT: hadc_start()
loop 持续采样
DGT->>DGT: Sigma-Delta 调制 + CIC0/CIC1 抽取
DGT->>ISR: DMA 搬满 points 点 (points*4 字节)
ISR->>APP: isr_cb(buffer, points*4)
APP->>APP: 处理数据 (如 printf 打印)
end
APP->>DGT: hadc_stop() / hadc_close()
数据采集与 ISR 回调
数字核心 hadc_digital.c 中,中断服务函数 hadc_isr(hadc_digital.c#L196,带 __attribute__((interrupt(""))) 声明)负责在 DMA 搬运完成时被触发;时钟初始化 hadc_clk_init(L208)与 CIC 初始化 hadc_cic_init(L229)是 hadc_open 内部的两个核心步骤。
回调语义(hadc.h#L231):
void (*isr_cb)(int *adc_buffer, u32 adc_len); // adc_buffer为数据指针, adc_len为数据长度(points*4)
- 每个采样点是有符号
int(4 字节),一次中断交付points个点,故adc_len = points * 4; - 满幅值约 ±2^29(头文件明确警告,hadc.h#L227),应用层换算物理量时需以该量程为基准,而非 2^31;
- 常规 DMA 点数常量
HADC_NORMAL_DMA_POINTS = 20(hadc.h#L6),hadc_platform_data.points可自行调整——点数越大,中断频率越低、CPU 开销越小,但缓冲区与数据延迟越大。
运行中切换输出频率
hadc_set_out_freq(struct cic_data *cic0, struct cic_data *cic1) 用于运行期改变采样率,官方推荐流程(hadc.h#L279-L288):
hadc_stop(); //1. 暂停数字逻辑
hadc_set_out_freq(cic0, cic1); //2. 改写两级CIC参数
hadc_start(); //3. 重新启动
先停后切的原因:CIC 参数在运行中直接改写会导致滤波器状态不一致,输出出现瞬态毛刺;暂停后再配置可保证新参数在干净的状态下生效。
使用示例
平台参数与回调定义
以下摘自官方 demo,展示 hadc_platform_data 的典型配置(500kHz 时钟、CIC0 抽取 155、CIC1 抽取 16,对应 50Hz 输出):
static void hadc_isr_callback(int *buffer, u32 buffer_len)
{
for (u32 i = 0; i < buffer_len; i++) {
printf("hdac res : %d\n", buffer[i]);
}
}
static const struct hadc_platform_data hadc_test_data = {
.clock = 500000L,
.cic[0].en = 1,
.cic[0].dsr = 155,
.cic[0].order = CIC0_4ORDER,
.cic[1].en = 1,
.cic[1].dsr = 16,
.cic[1].order = CIC1_2ORDER,
.isr_cb = hadc_isr_callback,
.points = 1,
};
Source: hadc_demo.c
启动与停止完整流程
void hadc_demo_test_start(void)
{
hadc_avddcp_config(1, AVDDCP_MODE_SEL_NORMAL, AVDDCP_VOL_SEL_3P60);
hadc_avddr_config(1, AVDDR_VOL_SEL_3P0);
hadc_avbg_config(1, 1, 1);
hadc_avcm_config(1, 1);
hadc_pga_config(1, HADC_MUXP_SEL_AIN0, HADC_MUXN_SEL_AIN1, HADC_GAIN_SEL_X1);
hadc_open((struct hadc_platform_data *)(&hadc_test_data));
hadc_start();
}
void hadc_demo_test_stop(void)
{
hadc_avddcp_config(0, AVDDCP_MODE_SEL_NORMAL, AVDDCP_VOL_SEL_3P60);
hadc_avddr_config(0, AVDDR_VOL_SEL_3P0);
hadc_avbg_config(0, 0, 0);
hadc_avcm_config(0, 0);
hadc_pga_config(0, HADC_MUXP_SEL_AIN0, HADC_MUXN_SEL_AIN1, HADC_GAIN_SEL_X1);
hadc_close();
}
Source: hadc_demo.c
要点解读:
- 启动顺序严格遵循
avddcp → avddr → avbg → avcm → PGA → open → start; - 停止顺序与启动完全相反(先关电源链,再关 PGA,最后
hadc_close),保证任意时刻不会出现"电源已断但前端仍使能"的悬空状态; hadc_test_data声明为const,调用时强转为非 const 指针——说明hadc_open的形参设计为可写(hadc_soft_info等运行时状态需要写入),但平台参数本身应保持只读;- demo 中
points = 1表示每次中断只交付 1 个点,适合调试逐点打印;量产场景建议用HADC_NORMAL_DMA_POINTS(20)批量搬运以降低中断频率。
配置选项
struct hadc_platform_data(hadc_open 入参)
| 字段 | 类型 | 默认/建议值 | 说明 |
|---|---|---|---|
clock | u32 | 500000(≤1M) | HADC 调制器工作频率,Hz |
cic[0] | struct cic_data | en=1, dsr=155, order=4 | CIC0 抽取滤波器(第一级,DSR0 范围 8~254) |
cic[1] | struct cic_data | en=1, dsr=16, order=2 | CIC1 抽取滤波器(第二级,DSR1 范围 2~64) |
isr_cb | 函数指针 | 必填 | 采样回调 (int *buffer, u32 len),len = points×4 |
points | u32 | 1(demo)/ 20(常规) | 一次中断采集的点数 |
struct cic_data
| 字段 | 类型 | 范围 | 说明 |
|---|---|---|---|
en | u8 | 0/1 | CIC 滤波器使能 |
dsr | u8 | dsr0: 8~254;dsr1: 2~64 | 抽取因子 |
order | u8 | CIC0: 3/4/5 阶;CIC1: 2/3/4 阶 | 阶数越大稳定时间越久 |
gain | u8 | 0~127(64@0dB) | 输出增益补偿 |
电源/通道枚举速查
| 枚举 | 取值要点 |
|---|---|
avddcp_mode_sel | NORMAL(正常升压)/ VPWR(VPWR 直通) |
avddcp_vol_sel | 3P40~3P75,默认 3P60 |
avddr_vol_sel | 2P7~3P4,默认 3P0 |
hadc_gain_sel | X1, X4, X8(=3), X16(=5), X32(=7), X64(=9), X128(=11),值不连续 |
hadc_muxp_sel / hadc_muxn_sel | AIN0~AIN7, TEMP, VCM, VBGBUF, VBIMN, VBIMP, AVSS |
cic0_order / cic1_order | CIC0: 3/4/5 阶;CIC1: 2/3/4 阶 |
API Reference
生命周期
void hadc_open(struct hadc_platform_data *data)
初始化 HADC 模块(内部完成 hadc_clk_init 与 hadc_cic_init)。初始化后必须调用 hadc_start 才开始采集。
参数: data — 平台参数结构体指针(时钟、CIC、回调、点数)。 注意: 模块被 hadc_close 后需重新 hadc_open。
void hadc_close(void)
彻底关闭 HADC 模块,释放数字逻辑资源。
void hadc_start(void)
启动 HADC 数字逻辑;hadc_open 后或 hadc_stop 暂停后调用。
void hadc_stop(void)
暂停 HADC 数字逻辑(模拟电源与配置保留),可随时 hadc_start 恢复。
void hadc_set_out_freq(struct cic_data *cic0, struct cic_data *cic1)
运行期切换输出频率。标准流程:hadc_stop() → hadc_set_out_freq(cic0, cic1) → hadc_start()。
电源域
void hadc_avddcp_config(u8 en, enum avddcp_mode_sel mode, enum avddcp_vol_sel avddcp_vol)
AVDDCP 电源配置。最先初始化;切换 mode 时须先关闭再切换。avddcp_vol 仅在 AVDDCP_MODE_SEL_NORMAL 下有效。
void hadc_avddr_config(u8 en, enum avddr_vol_sel avddr_vol)
AVDDR 电源配置,在 AVDDCP 之后调用。内部执行 hadc_avddr_trim 微调电压。
void hadc_avbg_config(u8 en, u8 faston_en, u8 with_cap)
AVBG 带隙基准配置,在 AVDDR 之后调用。正常上电稳定时间约 800ms;faston_en 开启快速上电,with_cap 指示外挂电容。
void hadc_avcm_config(u8 en, u8 with_cap)
AVCM 共模电压配置,在 AVBG 之后调用。
void hadc_avbg_init_for_fast_boot(void) / void hadc_avddcp_init_for_fast_boot(void)
快速启动专用:软关机快速上电时切换 AVBG/AVDDCP 电源时钟与模式,跳过正常稳定等待。
模拟前端
void hadc_pga_config(u8 en, enum hadc_muxp_sel muxp, enum hadc_muxn_sel muxn, enum hadc_gain_sel gain)
PGA 配置。切换通道时先关闭再切。
void hadc_opa_config(u8 en, u8 cmp_en, enum hadc_opa_muxp_sel muxp, enum hadc_opa_muxn_sel muxn, enum hadc_opa_muxi_sel muxi, enum hadc_opa_muxo_sel muxo)
OPA 配置,支持比较器模式(cmp_en),MUXI/MUXO 为体脂信号输入/输出通道。
void hadc_pa_config(u8 en, u8 cmp_en, enum hadc_pa_muxp_sel muxp, enum hadc_pa_muxn_sel muxn, enum hadc_pa_gain_sel gain)
PA 配置。做比较器时 gain 无效;HADC_PA_MUXN_SEL_DISABLE 可断开 N 端。
void hadc_vbim_config(u8 en, enum hadc_vbim_chl_sel chl)
VBIM 体脂测量通道配置(R250/R1K/EXTERN)。
void hadc_temp_sensor_config(u8 en)
内部温度传感器使能,使能后 MUX 可选 TEMP 通道。
void hadc_analog_all_off(void)
关闭 HADC 全部模拟信号通路,省功耗场景调用。
void hadc_debug(void)
开启 HADC 调试信号输出(配合 ass_debug_clk_sel / ass_debug_dato_sel 枚举,测试使用)。
全局状态
extern struct hadc_soft_flag_info hadc_soft_info; — 软件标志位集合(位域),记录电源档位、快速启动标志等运行时状态,驱动内部维护,一般无需应用直接修改。
故障模式、边界情况与并发注意事项
量程与溢出
- HADC 满幅值约 ±2^29(hadc.h#L227 显式警告),并非满 32 位。换算物理量(电压、温度)时必须以 ±2^29 为满量程,否则换算结果偏差约 8 倍。超过量程的输入会被调制器饱和,输出不再线性。
- 输入信号接近量程时,叠加 PGA 增益后极易饱和:增益越大,允许的输入摆幅越小。例如 X128 增益下,满量程输入仅约 ±2^29/128。配置高增益前应先确认输入信号幅度。
配置顺序违规
- 电源域顺序颠倒(如 AVBG 先于 AVDDR)会导致基准建立异常,表现为采样值漂移或噪声增大;驱动不会校验顺序,顺序保证依赖调用方。
- 切换 PGA/OPA/PA/VBIM 通道、切换 AVDDCP 模式时未先关闭,可能产生模拟链路瞬态毛刺。官方 API 注释反复强调"切换通道时,应先关闭再切通道"(如 hadc_pga_config 注释)。
稳定时间
- AVBG 正常上电稳定时间约 800ms(hadc_avbg_config 注释),快速上电模式(
faston_en)可缩短,但精度可能下降;需要最高精度的应用应在稳定后开始采样。 - CIC 滤波器阶数越高,阶跃稳定时间越久(
order越大,需要的稳定时间越久)。切换通道或输出频率后,前若干个采样点应丢弃或标记无效。
中断回调上下文
isr_cb运行在中断上下文(hadc_isr,__attribute__((interrupt(""))))。回调内禁止阻塞、延时、调用不可重入的系统服务;demo 中仅printf打印。数据消费应尽快完成,或将数据拷贝到环形缓冲后由任务上下文处理。hadc_isr与hadc_digital.c内的hadc_clk_init/hadc_cic_init等配置函数在不同时机运行(ISR 在采样路径,配置在 open 路径),应用层应保证hadc_stop/hadc_close后再改配置,避免配置与中断并发。
DMA 与点数
points决定一次中断交付的数据量(adc_len = points * 4字节);HADC_NORMAL_DMA_POINTS = 20为常规值。points过小会抬高中断频率、增加 CPU 占用;过大则延迟增大、内存占用上升。- 输出频率与点数共同决定中断频率:
中断频率 = Fo / points。例如 50Hz 输出、20 点/次时约 2.5 次/秒中断,开销极低。
性能与运维注意事项
- 输出频率公式:
Fo = clock / ((dsr0*4 + ivld_clk) * dsr1)(WORK_MODE=0 时ivld_clk=5)。选择 CIC 参数时优先参考头文件推荐表(hadc.h#L204-L218),表中组合经过验证,兼顾了 OSR 与频率。 - 50/60Hz 工频抑制:
clock=500K配(155,16)得 50Hz,clock=600K同参数得 60Hz——采集市电供电设备信号时,可让输出频率对齐工频或其整数分频,利用抽取滤波的陷波特性抑制工频干扰。 - 省电:长时间不采集时调用
hadc_analog_all_off关闭模拟通路;短期间歇采样用hadc_stop而非hadc_close,避免重建电源链的 800ms 稳定代价。 - 快速启动:软关机快速上电路径使用
hadc_avbg_init_for_fast_boot/hadc_avddcp_init_for_fast_boot,配合hadc_soft_info.fast_adc标志复用电源配置,适用于功耗敏感且需要快速恢复采样的场景。
扩展点
- 数据消费扩展:通过
hadc_platform_data.isr_cb定制采样数据的消费方式(打印、环形缓冲、DMA 到外部存储、跑算法等)。回调签名(int *adc_buffer, u32 adc_len)是唯一的数据出口,框架不限制回调内部逻辑,但须遵守中断上下文约束。 - 采样率定制:通过
cic[0]/cic[1]的en/dsr/order/gain自由组合输出频率与滤波特性;运行期用hadc_set_out_freq动态切换(先 stop 再切)。 - 测量场景定制:PGA 适用于通用电压/电阻测量;OPA/PA/VBIM 组合适用于体脂秤等差分激励测量;温度传感器通道适用于芯片温度监控——同一 HADC 硬件通过不同前端配置复用,无需更换外设。
- 调试扩展:
hadc_debug+ass_debug_clk_sel/ass_debug_dato_sel枚举可将内部时钟(HADC_CLK、CIC 时钟、斩波时钟等)与数据(DSMO、PAP、HADC 原始数据)引出到调试引脚,用于验证信号链各节点。
相关链接
- HADC 头文件(API 定义与枚举)
- HADC 模拟实现(电源域/前端配置)
- HADC 数字实现(时钟/CIC/ISR)
- HADC 官方示例(启动/停止全流程)
- 关联外设页:定时器(Timer)、中断控制器(Interrupt)、DMA、电源管理(软关机/唤醒)——如需整机低功耗采集方案,请参考对应外设页面。