Linux 驱动编写之ADC驱动编写配置

简介

纯粹的 ADC 驱动也是 IIO 驱动框架,如果需要自己编写ADC驱动,其实就是按照IIO的驱动框架进行相关实现。

IMX6ULL 的ADC驱动设备树配置

I.MX6ULL 有 2 个 ADC,但是对应一个 ADC 控制器。目前使用
GPIO1_IO01 这个ADC1 的通道 1 引脚来进行配置。

关 于 I.MX6ULL 的 ADC 节 点 更 为 详 细 的 信 息 请 参 考 对 应 的 绑 定 文 档 :Documentation/devicetree/bindings/iio/adc/vf610-adc.txt。接下来我们简单分析一下绑定文档,后面我们需要根据绑定文档修改设备树,使能 ADC 对应的通道。
ADC 相关属性有:

  • compatible: 兼容性属性,必须的,可以设置为“fsl,vf610-adc”。
  • reg: ADC 控制器寄存器信息。
  • interrupts: 中断属性, ADC1 和 ADC2 各对应一个中断信息。
  • clocks: 时钟属性。
  • clock-names: 时钟名字,可选“adc”。
  • vref-supply: 此属性对应 vref 参考电压句柄。
    可以看出, ADC 节点的属性还是比较少的。

1.设备树 adc1 io模式配置

&iomuxc {
	pinctrl_adc1: adc1grp {
		fsl,pins = <
			MX6UL_PAD_GPIO1_IO01__GPIO1_IO01   0xb0
		>;
	};
};

2.设备树adc1电源字节点配置

regulators {

	 reg_vref_adc: regulator@2 {
		 compatible = "regulator-fixed";
		 regulator-name = "VREF_3V3";
		 regulator-min-microvolt = <3300000>;
		 regulator-max-microvolt = <3300000>;
	 };
	 
 }

3.设备树ADC补充adc1节点配置

/{

};

 &adc1 {
	 pinctrl-names = "default";
	 pinctrl-0 = <&pinctrl_adc1>;
	 num-channels = <2>;
	 vref-supply = <&reg_vref_adc>;
	 status = "okay";
 };

4. 内核编译使能ADC

使能内核里面自带的 I.MX6ULL ADC 驱动,打开 Linux 内核配置界面,配置ADC的驱动路径如下:

-> Device Drivers
  -> Industrial I/O support
     -> Analog to digital converters
       -> <*> Freescale vf610 ADC driver //选中

配置界面如下:
在这里插入图片描述

adc驱动使用

编译修改后的设备树,然后使用新的设备树启动系统。进入/sys/bus/iio/devices 目录下,此目录下就有 ADC 对应的 iio 设备: iio:deviceX。
在这里插入图片描述

以上是标准的 IIO 设备文件目录,但只关心 iio:deviceX中的三个文件:
in_voltage1_raw: ADC1 通道 1 原始值文件。
in_voltage_scale: ADC1 比例文件(分辨率),单位为 mV。实际电压值(mV)=in_voltage1_raw*in_voltage_scale

查看ADC原始值和转化的电压值:
在这里插入图片描述

Linux应用程序实现对ADC数据的读取

#include "stdio.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "sys/ioctl.h"
#include "fcntl.h"
#include "stdlib.h"
#include "string.h"
#include <poll.h>
#include <sys/select.h>
#include <sys/time.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>

/* 字符串转数字,将浮点小数字符串转换为浮点数数值 */
#define SENSOR_FLOAT_DATA_GET(ret, index, str, member)\
	ret = file_data_read(file_path[index], str);\
	dev->member = atof(str);\
	
/* 字符串转数字,将整数字符串转换为整数数值 */
#define SENSOR_INT_DATA_GET(ret, index, str, member)\
	ret = file_data_read(file_path[index], str);\
	dev->member = atoi(str);\


/* adc iio框架对应的文件路径 */
static char *file_path[] = {
	"/sys/bus/iio/devices/iio:device0/in_voltage_scale",
	"/sys/bus/iio/devices/iio:device0/in_voltage1_raw",
};

/* 文件路径索引,要和file_path里面的文件顺序对应 */
enum path_index {
	IN_VOLTAGE_SCALE = 0,
	IN_VOLTAGE_RAW,
};

/*
 * ADC数据设备结构体
 */
struct adc_dev{
	int raw;
	float scale;
	float act;
};

struct adc_dev imx6ulladc;

 /*
 * @description			: 读取指定文件内容
 * @param - filename 	: 要读取的文件路径
 * @param - str 		: 读取到的文件字符串
 * @return 				: 0 成功;其他 失败
 */
static int file_data_read(char *filename, char *str)
{
	int ret = 0;
	FILE *data_stream;

    data_stream = fopen(filename, "r"); /* 只读打开 */
    if(data_stream == NULL) {
		printf("can't open file %s\r\n", filename);
		return -1;
	}

	ret = fscanf(data_stream, "%s", str);
    if(!ret) {
        printf("file read error!\r\n");
    } else if(ret == EOF) {
        /* 读到文件末尾的话将文件指针重新调整到文件头 */
        fseek(data_stream, 0, SEEK_SET);  
    }
	fclose(data_stream);	/* 关闭文件 */	
	return 0;
}

 /*
 * @description	: 获取ADC数据
 * @param - dev : 设备结构体
 * @return 		: 0 成功;其他 失败
 */
static int adc_read(struct adc_dev *dev)
{
	int ret = 0;
	char str[50];

	SENSOR_FLOAT_DATA_GET(ret, IN_VOLTAGE_SCALE, str, scale);
	SENSOR_INT_DATA_GET(ret, IN_VOLTAGE_RAW, str, raw);

	/* 转换得到实际电压值mV */
	dev->act = (dev->scale * dev->raw)/1000.f;
	return ret;
}

/*
 * @description		: main主程序
 * @param - argc 	: argv数组元素个数
 * @param - argv 	: 具体参数
 * @return 			: 0 成功;其他 失败
 */
int main(int argc, char *argv[])
{
	int ret = 0;

	if (argc != 1) {
		printf("Error Usage!\r\n");
		return -1;
	}

	while (1) {
		ret = adc_read(&imx6ulladc);
		if(ret == 0) { 			/* 数据读取成功 */
			printf("ADC原始值:%d,电压值:%.3fV\r\n", imx6ulladc.raw, imx6ulladc.act);
		}
		usleep(100000); /*100ms */
	}
	return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路过的小熊~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值