ADC(模拟-数字转换器)是把连续变化的模拟信号(如声音、温度等)转换成数字信号的电子设备。它在传感器、音频设备、图像处理、通信系统等场景中被广泛应用。下面用更易懂的方式重新整理相关内容:
一、ADC 的核心指标
分辨率 决定 ADC 能识别的最小信号差异。用 "位数" 表示,位数越高精度越高。例如:
- 8 位 ADC 能分辨 256 种电压值
- 12 位 ADC 能分辨 4096 种电压值 常见的有 8 位、10 位、12 位等。
采样率 单位时间内能采集的信号次数(如每秒多少次)。数值越高,捕捉快速变化信号的能力越强。
- 音频常用 44.1kHz(每秒 44100 次)
- 高频信号可能需要百万级采样率。
信噪比(SNR) 衡量信号纯净度的指标。数值越高,说明信号中混入的杂音越少。
转换速度 完成一次模数转换所需的时间。实时系统(如监控设备)需要更快的速度。
输入范围 ADC 能接受的模拟信号电压范围。例如:
- 温度传感器可能只需 0-5V
- 工业设备可能需要 -10V 到 +10V 的宽范围。
二、ADC 的应用场景
音频处理 将麦克风的模拟声音信号转为数字信号,用于录音、语音助手、音乐播放等。
传感器数据采集 将温度、压力、光线等传感器的模拟信号转为数字,用于智能家居、工业控制、医疗设备等。
图像与视频处理 将摄像头的模拟图像信号转为数字格式,供手机、监控摄像头等设备处理。
数据监测系统 在工厂、实验室等场景中,实时采集并分析各种物理信号(如振动、电流等)。
通信系统 将接收的射频信号(如手机信号)转为数字信号,以便解码和传输。
三、瑞芯微的 ADC 配置
该开发板有两种 ADC 接口:
温度传感器 ADC(TS-ADC)
- 支持 2 个测量通道
- 工作时钟不能超过 800 千赫兹(kHz)
- 专门用于温度检测。
逐次逼近型 ADC(SAR-ADC)
- 提供 6 个独立输入通道
- 10 位分辨率(可分辨 1024 种电压值)
- 工作时钟需低于 13 兆赫兹(MHz)
- 适用于多传感器信号采集(如压力、光线等)。
INFO
使用时需注意:
根据传感器类型选择对应的 ADC 接口(温度用 TS-ADC,其他信号用 SAR-ADC)
设置合适的采样频率(不超过硬件限制)
确保输入信号在 ADC 支持的电压范围内。
四、ADC 配置指南
1 配置 ADC 的 DTS 节点
在 RK3568 芯片中,ADC 的硬件信息定义在 kernel/arch/arm64/boot/dts/rockchip/rk3568.dtsi 文件中,代码如下:
saradc: saradc@fe720000 {
compatible = "rockchip,rk3568-saradc", "rockchip,rk3399-saradc";
reg = <0x0 0xfe720000 0x0 0x100>;
interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
#io-channel-cells = <1>;
clocks = <&cru CLK_SARADC>, <&cru PCLK_SARADC>;
clock-names = "saradc", "apb_pclk";
resets = <&cru SRST_P_SARADC>;
reset-names = "saradc-apb";
status = "disabled";
};2
3
4
5
6
7
8
9
10
11
你需要在自己的 DTS 文件(如 tspi-rk3566-core-v10.dtsi)中添加 ADC 的按键配置:
adc_keys: adc-keys {
compatible = "adc-keys"; // 匹配驱动的设备类型
io-channels = <&saradc 2>; // 使用ADC通道2(原示例可能有误,此处按注释修改为通道2)
io-channel-names = "buttons";// 给通道起别名,方便驱动识别
keyup-threshold-microvolt = <1800000>;// 松开按键时的电压阈值(单位微伏)
poll-interval = <100>; // 检测ADC的间隔时间(单位毫秒)
restart-key { // 定义一个按键节点
label = "restart"; // 按键名称
linux,code = <KEY_RESTART>; // 按键对应的系统代码(如复位键)
press-threshold-microvolt = <108>;// 按下时的电压阈值
};
};2
3
4
5
6
7
8
9
10
11
12
13
2 驱动与 DTS 节点的匹配
驱动代码参考 input/keyboard/adc-keys.c,具体步骤如下:
步骤 1:定义设备匹配表
在驱动代码中,声明一个结构体数组,用于匹配 DTS 中的 compatible 属性:
#ifdef CONFIG_OF
static const struct of_device_id adc_keys_of_match[ ] = {
{ .compatible = "adc-keys", }, // 匹配DTS中的compatible值
{ }
};
MODULE_DEVICE_TABLE(of, adc_keys_of_match); // 注册匹配表
#endif2
3
4
5
6
7
8
9
步骤 2:将匹配表绑定到驱动
将上述匹配表关联到驱动的 platform_driver 结构体中:
static struct platform_driver adc_keys_driver = {
.driver = {
.name = "adc_keys", // 驱动名称
.of_match_table = of_match_ptr(adc_keys_of_match), // 绑定匹配表
},
.probe = adc_keys_probe, // 设备初始化函数
};
module_platform_driver(adc_keys_driver); // 注册驱动2
3
4
5
6
7
8
步骤 3:解析 DTS 参数(在 probe 函数中)
在驱动的 adc_keys_probe 函数中,通过以下步骤读取 DTS 配置:
static int adc_keys_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct adc_keys_state *st;
// 1. 分配内存
st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);
if (!st) return -ENOMEM;
// 2. 获取ADC通道(通过DTS中的io-channel-names "buttons")
st->channel = devm_iio_channel_get(dev, "buttons");
if (IS_ERR(st->channel)) return PTR_ERR(st->channel);
// 3. 验证通道类型是否为电压型
if (iio_get_channel_type(st->channel) != IIO_VOLTAGE)
return -EINVAL;
// 4. 读取DTS参数
device_property_read_u32(dev, "keyup-threshold-microvolt", &st->keyup_voltage);
st->keyup_voltage /= 1000; // 单位转换(微伏转毫伏)
// 5. 加载按键映射(如restart-key的配置)
error = adc_keys_load_keymap(dev, st);
if (error) return error;
// 6. 初始化输入设备(如注册按键事件)
input = devm_input_allocate_device(dev);
if (!input) return -ENOMEM;
// 设置输入设备属性(名称、ID、事件类型等)
input->name = "ADC按键";
__set_bit(EV_KEY, input->evbit); // 支持按键事件
// ... 其他配置
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
关键点说明:
DTS 配置:通过
io-channels = <&saradc 2>指定使用 ADC 通道 2,press-threshold和keyup-threshold定义按键按压和释放的电压阈值。驱动匹配:驱动通过
compatible = "adc-keys"与 DTS 节点绑定,确保驱动能正确识别硬件。参数解析:驱动在
probe函数中通过设备属性(如keyup-threshold-microvolt)读取配置,并初始化输入设备以处理按键事件。
以上步骤确保了硬件(ADC 通道)与驱动的正确关联,并通过 DTS 参数动态配置按键行为。