ADC 驱动
概述
ADC(Analog-to-Digital Converter)模数转换器是将模拟信号转换为数字信号的关键外设。BK7239N 内置高精度 ADC,支持多通道采样,广泛应用于传感器数据采集、电压监测等场景。
功能描述
多通道支持:支持多个 ADC 通道同时工作
高精度转换:提供高精度的模数转换能力
多种采样模式:支持单次采样、连续采样等模式
中断支持:支持转换完成中断,提高系统响应效率
时钟配置:支持多种时钟源和采样率配置
滤波器:内置数字滤波器,提高转换精度
校准功能:支持 ADC 校准,提高转换精度
低功耗:支持低功耗模式,节省功耗
开发指引
初始化流程 - 调用 bk_adc_driver_init() 初始化 ADC 驱动 - 调用 bk_adc_init() 初始化具体 ADC 通道 - 配置采样参数(采样率、滤波器等) - 根据需要注册中断回调
基本使用 - 使用 bk_adc_single_read() 进行单次采样 - 使用 bk_adc_read_raw() 读取原始数据 - 使用 bk_adc_read_average() 读取平均值 - 使用 bk_adc_data_calculate() 计算实际电压值
中断处理 - 注册转换完成中断回调 - 在中断中处理转换结果 - 根据需要启用/禁用中断
校准使用 - 调用 bk_adc_bypass_calibration() 绕过校准 - 使用 bk_adc_data_calculate() 进行数据换算
注意事项
确保在调用其他 ADC API 前先调用 bk_adc_driver_init()
ADC 通道需要与硬件连接正确
采样率设置需要根据信号特性选择
使用中断模式时注意中断优先级设置
低功耗模式下 ADC 可能被关闭,需要重新初始化
注意 ADC 参考电压和输入范围
API 说明
主要 API 函数:
bk_adc_driver_init() - 初始化 ADC 驱动
bk_adc_driver_deinit() - 反初始化 ADC 驱动
bk_adc_init() - 初始化 ADC 通道
bk_adc_deinit() - 反初始化 ADC 通道
bk_adc_acquire() - 锁定 ADC 通道
bk_adc_release() - 释放 ADC 通道
bk_adc_single_read() - 单次采样
bk_adc_read_raw() - 读取原始数据
bk_adc_read_average() - 读取平均值
bk_adc_start() - 开始转换
bk_adc_stop() - 停止转换
bk_adc_register_isr() - 注册中断服务函数
bk_adc_set_clock() - 设置时钟
bk_adc_set_sample_rate() - 设置采样率
bk_adc_set_filter() - 设置滤波器
bk_adc_set_steady_time() - 设置稳定时间
bk_adc_set_sample_count() - 设置采样次数
bk_adc_set_saturate_mode() - 设置饱和模式
bk_adc_bypass_calibration() - 绕过校准
bk_adc_config() - 配置 ADC
bk_adc_set_mode() - 设置模式
bk_adc_data_calculate() - 数据换算
示例代码
基本使用示例:
#include <driver/adc.h>
void adc_example(void)
{
// 初始化 ADC 驱动
bk_adc_driver_init();
// 初始化 ADC 通道
bk_adc_init(ADC_CHAN_0, 64);
// 单次采样
uint16_t value;
bk_adc_single_read(&value);
// 计算实际电压值
float voltage = bk_adc_data_calculate(value, ADC_CHAN_0);
printf("ADC Value: %d, Voltage: %.2fV\n", value, voltage);
}
连续采样示例:
void adc_continuous_example(void)
{
uint16_t buffer[64];
// 设置连续采样模式
bk_adc_set_mode(ADC_CONTINUOUS_MODE);
// 开始转换
bk_adc_start();
// 读取数据
int len = bk_adc_read_raw(buffer, 64, 1000);
if (len > 0) {
// 处理采样数据
for (int i = 0; i < len; i++) {
float voltage = bk_adc_data_calculate(buffer[i], ADC_CHAN_0);
printf("Sample %d: %d -> %.2fV\n", i, buffer[i], voltage);
}
}
// 停止转换
bk_adc_stop();
}
中断采样示例:
static void adc_isr_callback(adc_chan_t chan, void *param)
{
uint16_t value;
if (bk_adc_single_read(&value) == BK_OK) {
float voltage = bk_adc_data_calculate(value, chan);
printf("ADC Interrupt: %d -> %.2fV\n", value, voltage);
}
}
void adc_interrupt_example(void)
{
// 注册中断回调
bk_adc_register_isr(ADC_CHAN_0, adc_isr_callback, NULL);
// 设置中断模式
bk_adc_set_mode(ADC_INTERRUPT_MODE);
// 开始转换
bk_adc_start();
}
常见问题
转换精度不够:检查参考电压、采样率设置,考虑使用校准功能
采样值不稳定:检查信号源稳定性、滤波器设置、稳定时间配置
中断未触发:确认中断注册和启用,检查中断优先级设置
数据换算错误:确认 ADC 参考电压和输入范围设置正确
实战示例
单次转换读取并换算为电压
uint16_t raw = 0;
bk_adc_init(ADC_CHAN_X);
bk_adc_set_mode(ADC_SINGLE_MODE);
bk_adc_single_read(&raw);
float mv = bk_adc_data_calculate(raw, ADC_CHAN_X);
常见错误码说明
BK_ERR_ADC_NOT_INIT:未调用 bk_adc_driver_init() 或通道未 bk_adc_init()
BK_ERR_ADC_INVALID_MODE:不支持的 ADC 模式
BK_ERR_ADC_SIZE_TOO_BIG:读取长度超过内部缓冲限制