IMX6ULL には 2 つの ADC があり、各 ADC には 8 チャンネルがありますが、ADC コントローラーを共有します。
1. デバイスツリー
imx6ull.dtsi ファイルには、adc1 のノード部分情報が定義されています。
adc1: adc@02198000 {
compatible = "fsl,imx6ul-adc", "fsl,vf610-adc";
reg = <0x02198000 0x4000>;
interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_ADC1>;
num-channels = <2>;
clock-names = "adc";
status = "disabled";
};
num-channels = <2>;であることに注意してください。これは、ADC1 の 2 つのチャネル、つまりチャネル 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
>;
};
次に、レギュレータ ノードの下の ADC の基準電圧を 5V に設定します (MQ135 が出力する最大アナログ電圧は5Vであるため)。
/* chenshao ADC vref 5.0V */
reg_vref_adc: regulator@2 {
compatible = "regulator-fixed";
regulator-name = "VREF_5V";
regulator-min-microvolt = <5000000>;
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
ファイルを読み取り、電力スケール値を取得します。2 つと1000で割って電圧値(V単位)を取得します。
PS:ファイルを読み取る前に巻き戻し関数を
使用してカーソルを先頭に移動します。fscanf を使用してファイルを読み取り、atoi および atof ライブラリ関数を使用して型を変換できます。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
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