ADC
Warning
Rockchip 平台 SARADC 最大采集电压 1.8V,严禁过压使用! Allwinner 平台 GPADC 最大采集电压 1.8 V,LRADC 最大采集电压 1.266V,严禁过压使用!
Rockchip 平台拓展引脚 ADC 引脚信息如下:
| 主板 | SOC | 平台 | 拓展引脚 |
|---|---|---|---|
| K1 | RK3568 | Rockchip | SARADC X1 |
| K1B | RK3568 | Rockchip | SARADC X1 |
| K3 | RK3562 | Rockchip | SARADC X1 |
| K7 | RK3576 | Rockchip | SARADC X3 |
| K7C | RK3576 | Rockchip | SARADC X3 |
| K8 | RK3588 | Rockchip | SARADC X1 |
Allwinner 平台拓展引脚 ADC 引脚信息如下:
| 主板 | SOC | 平台 | 拓展引脚 |
|---|---|---|---|
| K2B | H618 | Allwinner | 无 |
| K2C | H618 | Allwinner | 无 |
| K4B | T113 | Allwinner | GRADC X1 |
| K5C | A133 | Allwinner | LRADC X1 |
术语说明
| 术语 | 说明 |
|---|---|
| ADC | Analog-to-Digital Converter |
| SARADC | Successive approximation ADC |
| GPADC | General Purpose ADC |
| LRADC | Low Rate ADC |
规格
| ADC | 分辨率 | 最大采样率 | 检测电压范围 |
|---|---|---|---|
| SARADC | 12-bit | 1MHz | 0~1.8V |
| GPADC | 12-bit | 1MHz | 0~1.8V |
| LRADC | 6-bit | 2KHz | 0~1.266 V |
DTS 配置
不同平台 DTS 配置不相同,请根据主板对应平台查看对应的 DTS 节点配置。
Rockchip 平台 SARADC 的节点配置示例如下:
saradc: adc@ff280000 {
compatible = "rockchip,saradc";
reg = <0xff280000 0x1000>;
clocks = <&cru SCLK_SARADC>;
clock-names = "saradc";
resets = <&cru SRST_SARADC>;
reset-names = "saradc";
#io-channel-cells = <1>;
status = "okay";
};
Allwinner 平台 GPADC 的节点配置示例如下:
/*
* channel_num: Maxinum number of channels supported on the platform.
* channel_select: channel enable slection. channel0:0x01 channel1:0x02 channel2:0x04 channel3:0x08
* channel_data_select: channel data enable. channel0:0x01 channel1:0x02 channel2:0x04 channel3:0x08.
* channel_compare_select: compare function enable channel0:0x01 channel1:0x02 channel2:0x04 channel3:0x08.
* channel_cld_select: compare function low data enable setection: channel0:0x01 channel1:0x02 channel2:0x04 channel3:0x08.
* channel_chd_select: compare function hig data enable setection: channel0:0x01 channel1:0x02 channel2:0x04 channel3:0x08.
*/
gpadc:gpadc{
compatible = "allwinner,sunxi-gpadc"; //表征具体的设备,用于驱动和设备的绑定;
reg = <0x0 0x05070000 0x0 0x400>; //设备使用的寄存器地址;
interrupts = <GIC_SPI 0 IRQ_TYPE_NONE>; //设备使用的中断配置;
clocks = <&clk_gpadc>; //设备使用的时钟配置
channel_num = <2>; //使用的通道
channel_select = <0x05>; //通道选择
channel_data_select = <0>; //使能通道数据
channel_compare_select = <0x05>; //使用通道比较功能
channel_cld_select = <0x05>; //使用数据小于比较功能
channel_chd_select = <0>; //使用数据大于比较功能
channel0_compare_lowdata = <1700000>; //数据小于该值触发中断
channel0_compare_higdata = <1200000>; //数据大于该值触发中断
channel1_compare_lowdata = <460000>;
channel1_compare_higdata = <1200000>;
channel0_compare_lowdata = <1500000>; //数据小于该值触发中断
channel0_compare_higdata = <1200000>; //数据大于该值触发中断
key_cnt = <5>; //按键数量,注:以下部分只有GPADC0用于按键会用到
key0_vol = <210>; //按键电压
key0_val = <115>; //按键上报的值
key1_vol = <410>;
key1_val = <114>;
key2_vol = <590>;
key2_val = <139>;
key3_vol = <750>;
key3_val = <28>;
key4_vol = <880>;
key4_val = <102>;
status = "okay";
};
Allwinner 平台 LRADC 的节点配置示例如下:
sunxi_keyboard:keyboard{
compatible = "allwinner,keyboard";
reg = <0x0 0x01c21800 0x0 0x400>; /* 寄存器地址 */
interrupts = <GIC_SPI 30 IRQ_TYPE_NONE>; /* 中断 */
status = "okay"; /* 使能该节点 */
key_cnt = <5>;
key0 = <115 115>; /*根据实际情况,左边115是电压,单位为mV,右边115为该电压对应的键值*/
key1 = <235 114>;
key2 = <330 139>;
key3 = <420 28>;
key4 = <520 102>;
};
驱动路径
Rockchip 平台 saradc 驱动位于 IIO(Industrial I/O)子系统框架下,负责将模拟信号转换为数字信号,供用户空间或应用程序读取。
Allwinner 平台 GPADC 和 LRADC 驱动位于 Input 子系统框架下,负责将模拟信号转换为数字信号后,通过 Input 子系统上报,供用户空间或应用程序读取。
ADC 引脚定位
- ADC 引脚
Note
主板拓展引脚标注 △ 符号对应引脚图 1 号引脚,结合引脚数字丝印,确认实际引脚序号。
K7 引脚示意图:K7 主板配备 3 路 ADC,对应引脚 36(SARADC_VIN4)、38(SARADC_VIN5)、40(SARADC_VIN6)。

GPADC/LRADC 测试
查看 ADC 模块的 event 节点:
hexdump 读取输入设备0数据:
getevent 是 Android 系统中用于查看输入设备事件命令:
evtest 是 Linux 系统下开源的输入设备事件测试工具:
SARADC 测试
Rockchip 平台 SARADC 是注册为 iio 子系统设备,可以通过下面的方式进行读取 ADC 数据。
IIO 读取
列举系统中已注册的 IIO 设备:
查看目标 IIO 设备 0 的所有可操作接口:
Note
接口下的关键节点 in_voltageX_raw: X 为 ADC 通道编号(如 0、6 等),存储对应通道的 ADC 原始采样数值。 in_voltage_scale: 电压换算比例系数(单位:V/LSB),用于将原始采样值转换为实际电压。
电压计算公式:
读取电压比例系数(用于计算实际电压):
读取 IN6 通道的 ADC 原始采样值:
Shell 脚本
通过脚本读取 IN6 通道电压,运行脚本后每秒输出 ADC 原始采样值,电压比例系数以及电压值。
#!/bin/bash
echo "Press Ctrl+C to quit"
VOL_RAW="/sys/bus/iio/devices/iio:device0/in_voltage6_raw"
VOL_SCALE="/sys/bus/iio/devices/iio:device0/in_voltage_scale"
# Check required files accessibility
for file in "$VOL_RAW" "$VOL_SCALE"; do
[ ! -f "$file" ] || [ ! -r "$file" ] && { echo "Error: Cannot access $file" >&2; exit 1; }
done
while true; do
raw=$(cat "$VOL_RAW" | tr -d '\n\r ')
scale=$(cat "$VOL_SCALE" | tr -d '\n\r ')
voltage=$(awk -v r="$raw" -v s="$scale" 'BEGIN { printf "%.4f", (r * s) / 1000 }')
echo "vol_raw:$raw, vol_scale:$scale, vol:$voltage V"
sleep 1
done
执行方式:
C 程序
通过 C 程序读取 IN6 通道电压:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#define VOL_RAW "/sys/bus/iio/devices/iio:device0/in_voltage6_raw"
#define VOL_SCALE "/sys/bus/iio/devices/iio:device0/in_voltage_scale"
// Handle Ctrl+C exit
void sigint_handler(int sig) {
(void)sig;
printf("\nExiting...\n");
exit(EXIT_SUCCESS);
}
// Read int from file
static int read_int(const char *path) {
FILE *fp = fopen(path, "r");
int val;
if (!fp || fscanf(fp, "%d", &val) != 1) {
perror("Read int failed");
exit(EXIT_FAILURE);
}
fclose(fp);
return val;
}
// Read float from file
static float read_float(const char *path) {
FILE *fp = fopen(path, "r");
float val;
if (!fp || fscanf(fp, "%f", &val) != 1) {
perror("Read float failed");
exit(EXIT_FAILURE);
}
fclose(fp);
return val;
}
int main() {
signal(SIGINT, sigint_handler);
printf("Press Ctrl+C to quit\n");
while (1) {
int raw = read_int(VOL_RAW);
float scale = read_float(VOL_SCALE);
printf("vol_raw:%d, vol_scale:%.6f, vol:%.4f V\n",
raw, scale, (raw * scale) / 1000.0f);
sleep(1);
}
}
执行方式: