《RV1126 —— 配置adc并读取adc通道上传感器数值》

摘要:
然后在rv1126-evb-v10.dtsi中启用sardc并配置参考电压。

1.adc设备树配置

  一般来说,rk中已经封装好了标准adc的dts参数属性,我们要做的就是添加自己的adc通道,并引用标准接口即可,不同平台,标准dts中的adc节点名有所不同,其配置属性基本一样。

  例如:
   1)adc: adc@ff100000 {
        compatible = "rockchip,saradc";
        ......
        };
   2)saradc: saradc@ff100000 {
        compatible = "rockchip,saradc";
        ......
        };

  添加自己的dts通道:(在系统对应的dts中添加)

adc_name{                                     //自定义节点名
      compatible = "adc_name";            //匹配驱动的属性字符串,可以与节点名不同
      io-channels = <&saradc(&adc) 2>;   //设定我们需要读取的adc通道,参考硬件原理图,其中&表示应用系统封装的标准dts配置,需要系统标准的adc节点名,保证与本系统的一致,这里我们设定的为adc通道2
      io-channel-names = "adc2"           //自己取的名字,后续iio_channel_get的第二个参数会使用到这个参数
      status = "okay";                    //设备节点状态
      };

  

  由于我使用的是RV1109板卡,使用的是rv1126.dtsi。

《RV1126 —— 配置adc并读取adc通道上传感器数值》第1张

   可以看到已经配置好了。

《RV1126 —— 配置adc并读取adc通道上传感器数值》第2张

  再rv1126-evb-v10.dtsi中使能saradc,并配置基准电压(这个根据自身硬件决定)。

 2.adc内核配置

  直接在kernel中make ARCH=arm menuconfig,查找saradc。

《RV1126 —— 配置adc并读取adc通道上传感器数值》第3张

  然后编译下载到板卡上。

《RV1126 —— 配置adc并读取adc通道上传感器数值》第4张

3.编写光敏驱动

3.1 查看光敏在adc的通道几

《RV1126 —— 配置adc并读取adc通道上传感器数值》第5张

   可以看到lightsensor是在通道2。

3.2 配置设备树

《RV1126 —— 配置adc并读取adc通道上传感器数值》第6张

 3.3 编写light sensor驱动

  其中主要注意iio_channel_get(&(pdev->dev), "adc2")和iio_read_channel_raw(chan, &raw),作用分别是获取adc通道以及获取adc原始数据。

#include <linux/kernel.h>
#include <linux/gpio.h>
#include <linux/moduleparam.h>
#include <linux/stat.h>
 
#include <linux/init.h>
#include <linux/module.h> 
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/of_platform.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/adc.h>
 
#include <linux/version.h>
 
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <asm/io.h>
 
#include <linux/iio/iio.h>
#include <linux/iio/machine.h>
#include <linux/iio/driver.h>
#include <linux/iio/consumer.h>

#include <linux/uaccess.h>

#define GPIO_LOW 0
#define GPIO_HIGH 1
int major;
int count;
 
static struct class *cls;
struct iio_channel *chan;

static int light_sensor_open(struct inode *inode, struct file *file)
{
	printk(KERN_EMERG "%s-%d: enter
",__FUNCTION__,__LINE__);
	return 0;	
}
 
static ssize_t light_sensor_read(struct file *filp,char *buf,size_t len,loff_t *off)
{
	int raw;
	int ret = -1;
	int result = 20;

	ret = iio_read_channel_raw(chan, &raw); 
	if (ret < 0) 
	{
		printk("read hook adc channel() error: %d
", ret);
		return 0;
	}

	result = (1800*raw)/1023;
	ret = copy_to_user(buf, &result, len);	
	
	return 1;
}

static struct file_operations adc_fops = {
    .owner  =   THIS_MODULE,   
    .open   =   light_sensor_open,  
	.read   =  light_sensor_read,   	   
};
 
static int adc_probe(struct platform_device *pdev)
{
	printk(KERN_EMERG "%s-%d: enter
",__FUNCTION__,__LINE__);
	
    major = register_chrdev(0, "light_sensor", &adc_fops);
	cls = class_create(THIS_MODULE, "light_sensor");
	device_create(cls, NULL, MKDEV(major, 0), NULL, "light_sensor"); 
	chan = iio_channel_get(&(pdev->dev), "adc2");
	if (IS_ERR(chan))
 	{
		chan = NULL;
		return -1;
	}
	return 0;  
}
 
 
static int adc_remove(struct platform_device *pdev)
{ 
	printk(KERN_INFO "Enter %s
", __FUNCTION__);
	iio_channel_release(chan);
	device_destroy(cls, MKDEV(major, 0));
	class_destroy(cls);
	unregister_chrdev(major, "light_sensor");
    return 0;
}
static const struct of_device_id of_adc_match[] = {
	{ .compatible = "light_sensor" },
	{ /* Sentinel */ }
};
static struct platform_driver adc_driver = {
	.probe		= adc_probe,
	.remove		= adc_remove,
	.driver		= {
		.name	= "light_sensor",
		.owner	= THIS_MODULE,
		.of_match_table	= of_adc_match,
	},
};
 
static int __init adc_init(void)
{
	printk("init light_sensor driver");
    return platform_driver_register(&adc_driver);
    return 0;
}
 
static void __exit adc_exit(void)
{
	platform_driver_unregister(&adc_driver);
    printk(KERN_INFO "Exit light sensor driver
");
}
module_init(adc_init);
module_exit(adc_exit);
MODULE_LICENSE("GPL");

  将以上源码保存为 drivers/iio/adc/light_sensor.c ,并在 drivers/iio/adc/Makefile 后加入

obj-$(CONFIG_LIGHT_SENSOR) += light_sensor.o

  在drivers/iio/adc/Kconfig中添加:

config LIGHT_SENSOR
        tristate "light sensor config"

  最后在make ARCH=arm menuconfig配置选择LIGHT_SENSOR。编译下载到板卡。

《RV1126 —— 配置adc并读取adc通道上传感器数值》第7张

   可以到对应的设备节点。

4.获取光敏的数值

通过用户态接口获取adc值,其中*表示adc第多少通道:

cat /sys/bus/iio/devices/iio:device0/in_voltage*_raw

  由于我们是使用的通道2

《RV1126 —— 配置adc并读取adc通道上传感器数值》第8张

  其中数值就改变了。

5.adc相关api

struct iio_channel *iio_channel_get(struct device *dev, const char *consumer_channel);
  • 功能:获取 iio 通道描述

  • 参数:

    • dev: 使用该通道的设备描述指针

    • consumer_channel: 通道名称

void iio_channel_release(struct iio_channel *chan);
  • 功能:释放 iio_channel_get 函数获取到的通道

  • 参数:

    • chan:要被释放的通道描述指针

int iio_read_channel_raw(struct iio_channel *chan, int *val);
  • 功能:读取 chan 通道 AD 采集的原始数据。

  • 参数:

    • chan:要读取的采集通道指针

    • val:存放读取结果的指针

6.计算采集到的电压

使用标准电压将 AD 转换的值转换为用户所需要的电压值。其计算公式如下:

Vref / (2^n-1) = Vresult / raw

注: Vref 为标准电压 n 为 AD 转换的位数 Vresult 为用户所需要的采集电压 raw 为 AD 采集的原始数据 例如,标准电压为 1.8V,AD 采集位数为 10 位,AD 采集到的原始数据为 568,则:

Vresult = (1800mv * 568) / 1023;

免责声明:文章转载自《《RV1126 —— 配置adc并读取adc通道上传感器数值》》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇drf——drf模型层choice字段使用ios中的UITextField使用大全下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

kettle的job中运行每行

有时,在运行作业中的每一行时,我们需要多次执行作业或转换。假设我们需要导入从开始日期到昨天的所有旧数据。手动执行作业是痛苦和错误的。Kettle可以首先计算正确的日期,然后根据每个日期执行导入作业。在主作业中,返回日期转换首先运行,实际导入数据的作业在转换后运行。它是一个子作业,负责运行每个输入日期。子作业接收每行的“date”日期参数并执行它。在演示示例中...

Uni-app v-on监听事件

使用标记上的v-on监视事件。缩写为@click common click events方法:方法:{Focus(){console.log;},blur(){console.log;},confirm(){console.log;},click(){console.log;},tap(){console.log;},longpress(){console....

MongoDB 查看集合的统计信息

--1查看集合的统计信息srs0:“size”:“ok”:可以理解为集合名称计数:集合中的文档总数大小:连续分配的数据块索引:最近分配的块的大小paddingFactor:所有索引索引的总大小大小:--2显示rs0:db。东西。stats(1024)(KB);{“ns”:“count”:“size”:“indexSize”:...

ios 苹果和百度地图的相关使用

同时由于苹果使用的是高德,不会像谷歌地图一样在国内乌龟一样的访问速度,确实做一些地图相关的东西,非常有吸引力。只是实现了显示一个百度地图的view。百度地图使用的是Objective-C++,这意味这必须要有一个.mm文件。...

5G中的频点计算及实例分析

相关图表:关于∏SSB的频域位置SSREF和GSCN之间的关系,请参见下表:注:SCSspacedchannelrasterisM=3的工作频带的默认值。同步网格是5G的第一个概念,旨在加快终端扫描SSB的频率位置。GSCN通常用于在SA联网模式下加速时频同步,以继续解释MIB和SIB1消息;对于NSA来说,这是不必要的。RRC重配置消息已经携带了NR的SS...

js 浏览器窗口 刷新、关闭事件

当前页面不会直接关闭,可以点击确定按钮关闭或刷新,也可以取消关闭或刷新。...