驱动之路#31:基于 IIO 操作 ADC(RK3576)

描述

  题图:一家英国公司正在推广人体芯片,图中女子使用体内芯片付款。这种芯片原用来为残疾人自动开门,后来推广到正常人。

欢迎关注,每周更新!☞

本合集分享的是,我当初学习Linux驱动的来时路——《《驱动之路》开篇:自序&前言》。

正文

前文已经了解 IIO 与 ADC 的关系,本文就来基于 IIO 框架操作 ADC 采集数据。废话少说,直接开始!

内核配置:开启 IIO 子系统和对应 ADC 驱动("Device Drivers → Industrial I/O support → Analog to digital converters" 选中对应驱动)

驱动

设备树配置:在 RK3576 设备树中,启用 ADC 节点,配置通道、供电、采样速率等。

驱动

IIO 框架加载成功后,会在 /sys/bus/iio/devices/ 下生成 ADC 设备节点(通常为 iio:device0,可通过名称区分),用户空间无需编写驱动,直接操作 sysfs 文件即可读取数据。

确认 ADC 节点加载成功:执行命令检查 IIO 设备节点。

 

# 查看所有 IIO 设备ls /sys/bus/iio/devices/
# 查看 ADC 设备cat /sys/bus/iio/devices/iio:device0/name

 

若输出 2ae00000.adc,说明 ADC 节点加载成功。

驱动

查看 ADC 通道与属性:RK3576 内置 ADC 支持多通道,每个通道对应一个“电压原始值”文件,执行命令查看通道信息。

 

ls /sys/bus/iio/devices/iio:device0/
驱动

 

in_voltage0_raw:通道 0 的 ADC 原始值(12 位,范围 0~4095)。

读取通道 0 原始值:

 

cat /sys/bus/iio/devices/iio:device0/in_voltage0_raw
驱动

 

PS:将通道 0 与 GND 短接,数据应接近 0;与 3.3V 短接,数据应接近 4095。

ADC 电压计算公式

驱动

N:ADC转换精度,当前的ADC转换精度为12位,因此 N=12

例如,将 以上读到的 ADC 数字量 4095 以及 N=12 代入,那么计算出实际输入电压值:Vin= 4095 x 3.3 / (2^12 - 1) = 3.3V

脚本封装:循环采集并打印数据

为方便连续采集,可编写简单 Shell 脚本(adc_read.sh),自动循环读取并换算电压。

 

#!/bin/bash# ADC Sample Value to Actual Voltage Conversion Script# Formula: Vin = D × Vref / (2ⁿ - 1)# ===================== Configuration Parameters (Modify for Your Hardware) ======================VREF=3.3          # ADC reference voltage (Unit: V, common values: 3.3V/5V)BIT_WIDTH=12      # ADC bit width (e.g., 8/10/12/16 bits, 12 bits → 2^12-1=4095)ADC_READ_CMD="cat /sys/bus/iio/devices/iio:device0/in_voltage0_raw"  # Command to read ADC sample valueLOOP_INTERVAL=1   # Loop read interval (Unit: seconds, e.g., 0.5/1/2)# ===============================================================================================# Calculate 2^n - 1 (maximum ADC value)ADC_MAX=$(( (1 << BIT_WIDTH) - 1 ))# Check required commandsif ! command -v bc &> /dev/null; then    echo "Error: bc (floating-point calculation tool) is not installed. Please run: sudo apt install bc"    exit 1fi# Verify ADC read command validityif ! ${ADC_READ_CMD} &> /dev/null; then    echo "Warning: Failed to execute ADC sample read command! Please check if ADC_READ_CMD is configured correctly."    echo "Current read command: ${ADC_READ_CMD}"fi# Print configuration informationecho "==================== ADC Voltage Conversion Script ===================="echo "Reference Voltage (Vref): ${VREF}V"echo "ADC Bit Width (n): ${BIT_WIDTH} bits (Max Value: ${ADC_MAX})"echo "Conversion Formula: Vin = D × ${VREF} / ${ADC_MAX}"echo "Read Interval: ${LOOP_INTERVAL} seconds"echo "======================================================================"echo "Starting loop reading (Press Ctrl+C to exit)..."echo "----------------------------------------------------------------------"# Loop to read and calculatewhile true; do    # Read ADC sample value (D)    ADC_VALUE=$(${ADC_READ_CMD})    # Check if sample value is a valid number    if ! [[ ${ADC_VALUE} =~ ^[0-9]+$ ]]; then        echo "$(date +%Y-%m-%d %H:%M:%S) - Error: Invalid ADC sample value read: ${ADC_VALUE}"        sleep ${LOOP_INTERVAL}        continue    fi    # Calculate actual input voltage (use bc for floating-point calculation, keep 4 decimal places)    # Formula: Vin = D × Vref / (2^n - 1)    VIN=$(echo "scale=4; ${ADC_VALUE} * ${VREF} / ${ADC_MAX}" | bc)    # Print results    echo "$(date +%Y-%m-%d %H:%M:%S) - ADC Sample Value (D): ${ADC_VALUE} --> Actual Voltage (Vin): ${VIN}V"    # Loop interval    sleep ${LOOP_INTERVAL}done
赋予脚本执行权限并运行。

 

 

chmod +x adc_read.sh./adc_read.sh

 

此时可调节外部模拟信号(如电位器),观察电压值变化,验证采集功能是否正常。

驱动

之前我在使用全志平台时,遇到 ADC 数量与 IIO 通道不一致的问题,下期分享~

(完)

审核编辑 黄宇

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分