文章目录
- 一、电路图
- 二、将ADC标准驱动选配到内核
- 三、修改设备树文件
- 四、实验现象
一、电路图
由电路图可知,两个电路测量分别通过ANA0和ANA1两个ADC通道完成
查看芯片手册可知,ANA0可作为ADC1的通道0和通道1,或者ADC2的通道0和通道1.
ANA1可作为ADC1的通道1和ADC2的通道1
本次ANA0选用ADC1的通道0,ANA1选用ADC1的通道1
二、将ADC标准驱动选配到内核
执行 make menuconfig,将ADC标准驱动选配到内核中
Device Drivers --->
<*> Industrial I/O support --->
Analog to digital converters --->
<*> STMicroelectronics STM32 adc core
<*> STMicroelectronics STM32 adc
保存配置后,重新编译内核
三、修改设备树文件
参考帮助文档:
linux-5.10.61/Documentation/devicetree/bindings/iio/adc
// Example 2: with stm32mp157c to setup ADC1 with:
471 // - channels 0 & 1 as single-ended 通道0和1被配置为单端模式
472 // - channels 2 & 3 as differential (with resp. 6 & 7 negative inputs) 通道2和3被配置为差分模式
473 #include <dt-bindings/interrupt-controller/arm-gic.h>
474 #include <dt-bindings/clock/stm32mp1-clks.h>
475 adc12: adc@48003000 {
476 compatible = "st,stm32mp1-adc-core";
477 reg = <0x48003000 0x400>;
478 interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
479 <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
480 clocks = <&rcc ADC12>, <&rcc ADC12_K>;
481 clock-names = "bus", "adc";
482 booster-supply = <&booster>;
483 vdd-supply = <&vdd>;
484 vdda-supply = <&vdda>;
485 vref-supply = <&vref>;
486 st,syscfg = <&syscfg>;
487 interrupt-controller;
488 #interrupt-cells = <1>;
489 #address-cells = <1>;
490 #size-cells = <0>;
491 adc@0 {
492 compatible = "st,stm32mp1-adc";
493 #io-channel-cells = <1>;
494 reg = <0x0>;
495 interrupt-parent = <&adc12>;
496 interrupts = <0>;
497 st,adc-channels = <0 1>;
498 st,adc-diff-channels = <2 6>, <3 7>;
499 st,min-sample-time-nsecs = <5000>;
500 dmas = <&dmamux1 9 0x400 0x05>;
501 dma-names = "rx";
502 };
503 // ...
504 // other adc child node follow...
505 };
在stm32mp151.dtsi文件中找到adc1节点
adc: adc@48003000 {
compatible = "st,stm32mp1-adc-core";
reg = <0x48003000 0x400>;
interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc ADC12>, <&rcc ADC12_K>;
clock-names = "bus", "adc";
interrupt-controller;
st,syscfg = <&syscfg>;
#interrupt-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
adc1: adc@0 {
compatible = "st,stm32mp1-adc";
#io-channel-cells = <1>;
reg = <0x0>;
interrupt-parent = <&adc>;
interrupts = <0>;
dmas = <&dmamux1 9 0x400 0x80000001>;
dma-names = "rx";
status = "disabled";
};
将帮助手册中的实例与当前设备树进行对比后,发现需要配置以下键
&adc{
booster-supply = <&booster>;
vdd-supply = <&vdd>;
vdda-supply = <&vdda>;
vref-supply = <&vref>;
status = "okay";
&adc1{
st,adc-channels = <0 1>;
st,adc-diff-channels = <>;
st,min-sample-time-nsecs = <>;
status = "okay";
};
};
继续查看帮助手册,查明相应键值的含义
首先是st,adc-channels 代表单端通道模式下的通道标号
stm32mp1板子具有20个通道,取值范围为0-19
写值范围:
st,adc-diff-channels 用于配置差分输入模式,此次使用的单端通道模式,因此不配置该属性
st,min-sample-time-nsecs 用于配置ADC的最小采用时间
根据上述信息,得到设备树节点
&adc {
vdd-supply = <&vdd>;
vdda-supply = <&vdd>;
vref-supply = <&vdd>;
status = "okay";
adc1: adc@0 {
st,adc-channels = <0 1>;
st,min-sample-time-nsecs = <10000>;
status = "okay";
};
};
修改完设备树,重新编译设备树文件。
将重新编译的设备树文件以及内核镜像文件放到tftp目录下,重启开发板
四、实验现象
- 系统启动后可以查看目录/sys/bus/iio/devices/
所有的iio设备目录都在该路径下
- 注:IIO设备,全称是Industrial I/O(工业I/O)设备,是专用于模数转换器(ADC)和数模转换器(DAC)的内核子系统中的设备
- 通过/sys/bus/iio/devices/iio:device*/name来确定是哪个设备节点
- in_voltage0_raw/in_voltage1_raw 文件读到的数据是当前采集到的数据
- in_voltage0_type/ in_voltage1_type 文件读到的数据是当前 ADC 通道的精度
- 在应用层通过读取文件的内容来获取相应的电流值以及电压值
- 读取到的数值需要进行计算
相应电阻的数值在电路图中有体现
R50 = 1k
R49 = 100k
R53 = 10R
R54 = 0.1R
实现现象