ADC 驱动
基于 lisa_device 框架的 ADC 设备驱动,为 ARCS 平台提供统一的模拟信号采样接口。
功能特性
设备支持: ADC0 控制器,支持多个模拟输入通道
通道支持: 支持通道 0-5 的模拟信号采样,以及 VBAT 和温度传感器特殊通道
按通道配置: 每个通道可独立配置参考电压和分辨率
多种参考电压: 支持 1.2V、3.6V、VDD_IO/2、VDD_IO/3、VDD_IO*3/2、VDD_IO、外部参考电压
线程安全: 内部使用互斥锁保护并发访问
灵活配置: 通过
lisa_adc_channel_setup()运行时配置通道参数
配置选项
在 Kconfig 中启用驱动:
CONFIG_LISA_ADC=y
API 接口
配置 ADC 通道
int lisa_adc_channel_setup(lisa_device_t *dev, uint32_t channel,
const lisa_adc_channel_config_t *config);
配置指定通道的参考电压和分辨率。应在读取通道之前调用。
参数:
dev: ADC 设备指针channel: ADC 通道号(0-5:普通通道,6:VBAT,7:TEMP)config: 通道配置参数,包含:reference: 参考电压类型(枚举)resolution: ADC 分辨率(枚举)
参考电压类型:
LISA_ADC_REF_VDD_1V2: 固定 1.2V 参考电压LISA_ADC_REF_VDD_3V6: 固定 3.6V 参考电压LISA_ADC_REF_VDD_IO_AUTO: VDD_IO 自动分压(硬件自动选择:VDD_IO≤2.4V时分压系数1/2,>2.4V时分压系数1/3)LISA_ADC_REF_VDD_IO_AUTO_MUL3: VDD_IO 自动分压 + 3倍缓冲(测量范围扩大3倍)LISA_ADC_REF_EXTERNAL: 外部参考电压 Vref_ext
分辨率类型:
LISA_ADC_RESOLUTION_10BIT: 10-bit(0-1023)
返回值:
LISA_DEVICE_OK (0): 成功LISA_DEVICE_ERR_INVALID: 参数无效LISA_DEVICE_ERR_RANGE: 通道号超出范围LISA_DEVICE_ERR_NOT_SUPPORT: 不支持的配置
读取 ADC 值
int lisa_adc_read(lisa_device_t *dev, uint32_t channel, uint16_t *value);
读取指定通道的 ADC 原始采样值。如果通道未配置,将使用默认配置(1.2V 参考电压)。
参数:
dev: ADC 设备指针channel: ADC 通道号(0-5:普通通道,6:VBAT,7:TEMP)value: 输出采样值指针
返回值:
LISA_DEVICE_OK (0): 成功LISA_DEVICE_ERR_INVALID: 参数无效LISA_DEVICE_ERR_RANGE: 通道号超出范围LISA_DEVICE_ERR_IO: 硬件 IO 错误
使用方法
基本步骤
获取设备: 通过
lisa_device_get()获取 ADC 设备配置通道: 调用
lisa_adc_channel_setup()配置通道参数读取数据: 调用
lisa_adc_read()读取指定通道的 ADC 值电压转换: 使用
LISA_ADC_RAW_TO_MV宏将原始值转换为电压值
基础使用示例
#include "lisa_adc.h"
// 1. 获取 ADC 设备
lisa_device_t *adc = lisa_device_get("adc0");
if (!lisa_device_ready(adc)) {
return -1;
}
// 2. 配置通道2使用1.2V参考电压
lisa_adc_channel_config_t ch2_config = {
.reference = LISA_ADC_REF_VDD_1V2,
.resolution = LISA_ADC_RESOLUTION_10BIT,
};
lisa_adc_channel_setup(adc, 2, &ch2_config);
// 3. 读取 ADC 通道2的值
uint16_t raw_value;
int ret = lisa_adc_read(adc, 2, &raw_value);
if (ret == LISA_DEVICE_OK) {
// 5. 计算电压值(毫伏)
uint32_t voltage_mv = LISA_ADC_RAW_TO_MV(raw_value, 1200, 10);
printf("Channel 2: %u mV (raw: %u)\n", voltage_mv, raw_value);
}
不同通道使用不同参考电压
#include "lisa_adc.h"
lisa_device_t *adc = lisa_device_get("adc0");
// 通道0: 使用1.2V参考电压测量低电压信号
lisa_adc_channel_config_t ch0_config = {
.reference = LISA_ADC_REF_VDD_1V2,
.resolution = LISA_ADC_RESOLUTION_10BIT,
};
lisa_adc_channel_setup(adc, 0, &ch0_config);
// 通道2: 使用3.6V参考电压测量高电压信号
lisa_adc_channel_config_t ch2_config = {
.reference = LISA_ADC_REF_VDD_3V6,
.resolution = LISA_ADC_RESOLUTION_10BIT,
};
lisa_adc_channel_setup(adc, 2, &ch2_config);
// 读取并转换
uint16_t raw0, raw2;
lisa_adc_read(adc, 0, &raw0);
lisa_adc_read(adc, 2, &raw2);
uint32_t voltage0 = LISA_ADC_RAW_TO_MV(raw0, 1200, 10);
uint32_t voltage2 = LISA_ADC_RAW_TO_MV(raw2, 3600, 10);
printf("CH0: %u mV (1.2V ref)\n", voltage0);
printf("CH2: %u mV (3.6V ref)\n", voltage2);
使用 VDD_IO 自动分压参考电压
#include "lisa_adc.h"
lisa_device_t *adc = lisa_device_get("adc0");
// 配置通道3使用 VDD_IO 自动分压
lisa_adc_channel_config_t ch3_config = {
.reference = LISA_ADC_REF_VDD_IO_AUTO,
.resolution = LISA_ADC_RESOLUTION_10BIT,
};
lisa_adc_channel_setup(adc, 3, &ch3_config);
// 读取 ADC 值
uint16_t raw3;
lisa_adc_read(adc, 3, &raw3);
// 电压转换: 用户需要知道实际的 VDD_IO 电压
// 假设硬件 VDD_IO = 3.3V (>2.4V),硬件自动选择分压系数 1/3
// 则参考电压 = 3.3V / 3 = 1.1V
uint32_t voltage3 = LISA_ADC_RAW_TO_MV(raw3, 1100, 10);
printf("CH3: %u mV (VDD_IO/3 ref)\n", voltage3);
// 如果硬件 VDD_IO = 2.0V (≤2.4V),硬件自动选择分压系数 1/2
// 则参考电压 = 2.0V / 2 = 1.0V
// uint32_t voltage3 = LISA_ADC_RAW_TO_MV(raw3, 1000, 10);
读取特殊通道(VBAT 和温度)
#include "lisa_adc.h"
lisa_device_t *adc = lisa_device_get("adc0");
// 配置 VBAT 通道(通道 6)
lisa_adc_channel_config_t vbat_config = {
.reference = LISA_ADC_REF_VDD_1V2,
.resolution = LISA_ADC_RESOLUTION_10BIT,
};
lisa_adc_channel_setup(adc, 6, &vbat_config);
// 读取 VBAT 通道
uint16_t vbat_raw;
if (lisa_adc_read(adc, 6, &vbat_raw) == LISA_DEVICE_OK) {
// VBAT 通道测量的是实际电池电压的 1/3
uint32_t vbat_sense_mv = LISA_ADC_RAW_TO_MV(vbat_raw, 1200, 10);
uint32_t vbat_actual_mv = vbat_sense_mv * 3;
printf("Battery voltage: %u mV\n", vbat_actual_mv);
}
// 配置温度传感器通道(通道 7)
lisa_adc_channel_config_t temp_config = {
.reference = LISA_ADC_REF_VDD_1V2,
.resolution = LISA_ADC_RESOLUTION_10BIT,
};
lisa_adc_channel_setup(adc, 7, &temp_config);
// 读取温度传感器通道
uint16_t temp_raw;
if (lisa_adc_read(adc, 7, &temp_raw) == LISA_DEVICE_OK) {
printf("Temperature sensor raw value: %u\n", temp_raw);
// 温度计算公式请参考芯片数据手册
}
硬件配置
引脚复用配置
ADC 驱动在初始化时会自动调用板型目录中定义的 lisa_adc_pinmux() 函数,用于配置 ADC 通道的引脚复用。
配置位置:
定义:
boards/<板型名>/pinmux.c中实现lisa_adc_pinmux()函数声明:
boards/<板型名>/pinmux.h中声明void lisa_adc_pinmux()调用时机: ADC0 设备初始化时自动调用
示例 (参考 boards/arcs_evb/pinmux.c):
void lisa_adc_pinmux()
{
// 配置 PB06 为 ADC 功能(功能码 3)
AON_IOMuxManager_PinConfigure(CSK_IOMUX_PAD_B, 6, 3);
}
注意:
该函数由板型相关代码实现,不同板型的引脚配置可能不同
只需配置实际使用的 ADC 通道引脚
内部通道(VBAT、TEMP)无需配置引脚
支持的通道
通道号 |
对应引脚/功能 |
说明 |
|---|---|---|
0 |
PB02 |
ADC 通道 0 |
1 |
PB03 |
ADC 通道 1 |
2 |
PB04 |
ADC 通道 2 |
3 |
PB05 |
ADC 通道 3 |
4 |
PB06 |
ADC 通道 4 |
5 |
PB07 |
ADC 通道 5 |
6 |
内部 VBAT |
电池电压监测通道(VBAT/3) |
7 |
内部 TEMP |
芯片温度传感器通道 |
注意:
通道 0-5 使用前需先通过 GPIO 驱动将对应引脚配置为
LISA_GPIO_MODE_ANALOG模式通道 6 (VBAT) 和通道 7 (TEMP) 为内部通道,无需配置引脚
参考电压选择
驱动支持以下参考电压(通过 lisa_adc_channel_setup() 配置):
参考电压枚举 |
说明 |
电压计算 |
|---|---|---|
|
固定 1.2V |
|
|
固定 3.6V (1.2V × 3) |
|
|
VDD_IO 自动分压 |
VDD_IO/2 (VDD_IO≤2.4V) 或 VDD_IO/3 (VDD_IO>2.4V) |
|
VDD_IO 自动分压 + 3倍缓冲 |
(VDD_IO/2 或 VDD_IO/3) × 3 |
|
外部参考电压 |
依赖外部 Vref_ext 电路 |
重要说明:
固定电压类型 (1.2V, 3.6V): 电压值固定,用户直接使用
VDD_IO 自动分压 (
LISA_ADC_REF_VDD_IO_AUTO):硬件会自动检测外部 VDD_IO 电压并选择内部分压系数
VDD_IO ≤ 2.4V 时,分压系数 1/2,参考电压 = VDD_IO / 2
VDD_IO > 2.4V 时,分压系数 1/3,参考电压 = VDD_IO / 3
用户需要根据实际 VDD_IO 电压计算参考电压值
硬件限制警告: 实际可测量的外部电压不能超过 VDD_IO (默认 3.3V)。 超过此电压可能损坏芯片。请确保输入信号经过适当的分压或限幅处理。
电压转换
使用 LISA_ADC_RAW_TO_MV 宏进行转换:
uint32_t voltage_mv = LISA_ADC_RAW_TO_MV(raw_value, reference_mv, resolution_bits);
参数:
raw_value: ADC 原始采样值reference_mv: 参考电压(毫伏)resolution_bits: 分辨率(位数,如 10)
示例:
// 10-bit ADC, 1.2V 参考电压,原始值 512
uint32_t voltage = LISA_ADC_RAW_TO_MV(512, 1200, 10);
// 结果: (512 × 1200) / 1024 = 600 mV
注意事项
通道配置: 建议在读取通道之前先调用
lisa_adc_channel_setup()配置通道参数引脚配置: 使用通道 0-5 前必须先将对应引脚配置为 ADC 模拟输入模式
特殊通道: 通道 6 (VBAT) 和通道 7 (TEMP) 为内部通道,无需配置引脚
通道范围: 支持通道 0-7(0-5:外部通道,6:VBAT,7:TEMP)
VBAT 分压: VBAT 通道测量的是实际电池电压的 1/3,计算实际电压时需乘以 3
温度转换: 温度传感器的原始值需根据芯片数据手册提供的公式进行温度转换
参考电压计算: 对于依赖硬件的参考电压(VDD_IO 系列、外部参考),用户需要根据实际电路确定电压值用于转换计算
分辨率支持: ARCS 平台目前仅支持 10-bit 分辨率
线程安全: 驱动内部已实现线程保护,可在多线程环境中使用
转换时间: 每次读取会触发一次 ADC 转换,需等待转换完成(通常几微秒到几毫秒)
输入范围: 外部通道输入电压应在 0V 到参考电压之间,超出范围可能损坏硬件或得到错误结果
未配置通道: 如果读取未配置的通道,将自动使用默认配置(1.2V 参考电压,10-bit 分辨率)