IMX6ULL一共有两个ADC,每个ADC都有八个通道,但他们共用一个ADC控制器

1.设备树

在imx6ull.dtsi文件中已经帮我们定义好了adc1的节点部分信息

adc1: adc@02198000 {

compatible = "fsl,imx6ul-adc", "fsl,vf610-adc";

reg = <0x02198000 0x4000>;

interrupts = ;

clocks = <&clks IMX6UL_CLK_ADC1>;

num-channels = <2>;

clock-names = "adc";

status = "disabled";

};

注意 num-channels = <2>;,这个表示指定使用ADC1的两个通道,即通道1和通道2 如果你要使用多个ADC通道,修改这个值即可

配置ADC引脚的 pinctrl,在自己的设备树(.dts)中引用adc1并指定 pinctrl子系统,也就是指定引脚

首先在根节点下定义 pinctrl

/* chenshao ADC1_CH1 GPIO1_IO01 */

pinctrl_adc1: adc1grp {

fsl,pins = <

MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0xb0

>;

};

接着在 regulators 节点下设置ADC的参考电压,设置为5V(因为MQ135输出最大模拟电压是5V)

/* chenshao ADC vref 5.0V */

reg_vref_adc: regulator@2 {

compatible = "regulator-fixed";

regulator-name = "VREF_5V";

regulator-min-microvolt = <0>;

regulator-max-microvolt = <5000000>;

};

最后在根节点之外引用adc1节点,并指定引脚可参考电压节点

/* chenshao ADC1 */

&adc1 {

pinctrl-names = "default";

pinctrl-0 = <&pinctrl_adc1>;

num-channels = <2>; /* 2个通道,gpio1_io0占用一个 */

vref-supply = <®_vref_adc>;

status = "okay";

};

2.直接查看ADC值

1.进入iio总线下的设备目录

cd /sys/bus/iio/devices/iio:device0/

2.ls查看

------------------------

dev of_node

in_voltage0_raw power

in_voltage1_raw sampling_frequency_available

in_voltage_sampling_frequency subsystem

in_voltage_scale uevent

name

3.查看ADC通道1原始值(由于IMX6ULL ADC为12位,所以最小值为0,最大值为4095(2^12),分别对应0V,3.3V或5V)

cat in_voltage1_raw

721

4.查看电压规模

cat in_voltage_scale

1.220703125

5.计算实际电压

in_voltage1_raw * in_voltage_scale 即可,注意单位是毫伏

3.应用程序获取ADC和电压

读取 /sys/bus/iio/devices/iio:device0/in_voltage1_raw 文件得到ADC原始值 读取 /sys/bus/iio/devices/iio:device0/in_voltage_scale 文件得到电源规模值 两者相乘,再除以1000即可得到电压值(单位V)

PS: 读取文件前使用 rewind函数 将光标移到最开头, 可以使用 fscanf 读取文件 利用 atoi 和 atof 库函数转换类型

#include

#include

#include

#include

const char *voltage1_raw = "/sys/bus/iio/devices/iio:device0/in_voltage1_raw";

const char *voltage_scale = "/sys/bus/iio/devices/iio:device0/in_voltage_scale";

int main(int argc, char *argv[])

{

FILE *raw_fd, *scale_fd;

int len1, len2, res;

char data[20];

int raw;

double scale;

while(1){

/* 1.打开文件 */

raw_fd = fopen(voltage1_raw, "r");

if(raw_fd == NULL){

printf("open raw_fd failed!\n");

return -1;

}

scale_fd = fopen(voltage_scale, "r");

if(scale_fd == NULL){

printf("open scale_fd failed!\n");

return -2;

}

/* 2.读取文件 */

rewind(raw_fd); // 将光标移回文件开头

res = fscanf(raw_fd, "%s", data);

raw = atoi(data);

memset(data, 0, sizeof(data));

rewind(scale_fd); // 将光标移回文件开头

res = fscanf(scale_fd, "%s", data);

scale = atof(data);

printf("ADC原始值:%d,电压值:%.3fV\r\n", raw, raw * scale / 1000.f);

fclose(raw_fd);

fclose(scale_fd);

sleep(2);

}

return 0;

}

测试成功

# ./adcApp

ADC原始值:390,电压值:0.476V

ADC原始值:399,电压值:0.487V

ADC原始值:413,电压值:0.504V

ADC原始值:416,电压值:0.508V

ADC原始值:410,电压值:0.500V

ADC原始值:407,电压值:0.497V

推荐阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。