6.1物联网RK3399项目开发实录-驱动开发之ADC驱动(wulianjishu666)

2024-03-30 05:52

本文主要是介绍6.1物联网RK3399项目开发实录-驱动开发之ADC驱动(wulianjishu666),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

物联网嵌入式开发源码例程:

链接:https://pan.baidu.com/s/1B3oqq5QBhN-VmTFt9CI-7A?pwd=2ihg 

*******************************************************************************************

ADC 使用

简介

AIO-3399J 开发板上的 AD 接口有两种,分别为:温度传感器 (Temperature Sensor)、逐次逼近ADC (Successive Approximation Register)。其中:

  • TS-ADC(Temperature Sensor):支持两通道,时钟频率必须低于800KHZ

  • SAR-ADC(Successive Approximation Register):支持六通道单端10位的SAR-ADC,时钟频率必须小于13MHZ。

内核采用工业 I/O 子系统来控制 ADC,该子系统主要为 AD 转换或者 DA 转换的传感器设计。 下面以 SAR-ADC 为例子,介绍 ADC 的基本配置方法。

DTS配置

配置DTS节点

AIO-3399J SAR-ADC 的 DTS 节点在 kernel/arch/arm64/boot/dts/rockchip/rk3399.dtsi 文件中定义,如下所示:

saradc: saradc@ff100000 {compatible = "rockchip,rk3399-saradc";reg = <0x0 0xff100000 0x0 0x100>;interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH 0>;#io-channel-cells = <1>;clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;clock-names = "saradc", "apb_pclk";status = "disabled";};

用户首先需在 DTS 文件中添加 ADC 的资源描述:

kernel/arch/arm64/boot/dts/rockchip/rk3399-firefly-demo.dtsi :adc_demo: adc_demo{status = "disabled";compatible = "firefly,rk3399-adc";io-channels = <&saradc 3>;};

这里申请的是 SARADC 通道3。

在驱动文件中匹配 DTS 节点

用户驱动可参考 Firefly adc demo:

Android7.1 Industry 与 Android10.0 路径为 kernel/drivers/iio/adc/adc-firefly-demo.c

Android8.1 box 与 Android7.1 box 路径为 kernel/drivers/adc/adc-firefly-demo.c

demo是一个侦测 AIO-3399J 风扇状态的驱动。首先在驱动文件中定义 of_device_id 结构体数组:

static const struct of_device_id firefly_adc_match[] = {{ .compatible = "firefly,rk3399-adc" },{},
};

然后将该结构体数组填充到要使用 ADC 的 platform_driver 中:

static struct platform_driver firefly_adc_driver = {.probe      = firefly_adc_probe,.remove     = firefly_adc_remove,.driver     = {.name   = "firefly_adc",.owner  = THIS_MODULE,.of_match_table = firefly_adc_match,},
};

接着在 firefly_adc_probe 中对 DTS 所添加的资源进行解析:

static int firefly_adc_probe(struct platform_device *pdev)
{printk("firefly_adc_probe!\n");chan = iio_channel_get(&(pdev->dev), NULL);if (IS_ERR(chan)){chan = NULL;printk("%s() have not set adc chan\n", __FUNCTION__);return -1;}fan_insert = false;if (chan) {INIT_DELAYED_WORK(&adc_poll_work, firefly_demo_adc_poll);schedule_delayed_work(&adc_poll_work,1000);}return 0;
}

驱动说明

获取 AD 通道

struct iio_channel *chan;					#定义 IIO 通道结构体
chan = iio_channel_get(&pdev->dev, NULL);   #获取 IIO 通道结构体

注意: iio_channel_get 通过 probe 函数传进来的参数 pdev 获取 IIO 通道结构体,probe 函数如下:

static int XXX_probe(struct platform_device *pdev);

读取 AD 采集到的原始数据

int val,ret;
ret = iio_read_channel_raw(chan, &val);

调用 iio_read_channel_raw 函数读取 AD 采集的原始数据并存入 val 中。

计算采集到的电压

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

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

注意:

  • Vref 为标准电压

  • n 为 AD 转换的位数

  • Vresult 为用户所需要的采集电压

  • raw 为 AD 采集的原始数据

例如,标准电压为 1.8V,AD 采集位数为 10 位,AD 采集到的原始数据为 568,则:

Vresult = (1800mv * 568) / 1023;

接口说明

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

  • 参数:

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

    • consumer_channel: 该设备所使用的 IIO 通道描述指针

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:存放读取结果的指针

调试方法

Demo 程序使用

在 kernel/arch/arm64/boot/dts/rockchip/rk3399-firefly-demo.dtsi 中使能 adc_demo ,将 disabled 改为 okay:

adc_demo: adc_demo{status = "okay";compatible = "firefly,rk3399-adc";io-channels = <&saradc 3>;};

编译内核,烧录内核到 AIO-3399J 开发板上,然后插拔风扇时,会打印内核 log 信息如下:

[   85.158104] Fan insert! raw= 135 Voltage= 237mV
[   88.422124] Fan out! raw= 709 Voltage=1247mV

获取所有 ADC 值

有个便捷的方法可以查询到每个 SARADC 的值:

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

FAQs

为何按上面的步骤申请 SARADC,会出现申请报错的情况?

驱动需要获取ADC通道来使用时,需要对驱动的加载时间进行控制,必须要在saradc初始化之后。saradc是使用module_platform_driver()进行平台设备驱动注册,最终调用的是module_init()。所以用户的驱动加载函数只需使用比module_init()优先级低的,例如:late_initcall(),就能保证驱动的加载的时间比saradc初始化时间晚,可避免出错。

这篇关于6.1物联网RK3399项目开发实录-驱动开发之ADC驱动(wulianjishu666)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/860652

相关文章

部署Vue项目到服务器后404错误的原因及解决方案

《部署Vue项目到服务器后404错误的原因及解决方案》文章介绍了Vue项目部署步骤以及404错误的解决方案,部署步骤包括构建项目、上传文件、配置Web服务器、重启Nginx和访问域名,404错误通常是... 目录一、vue项目部署步骤二、404错误原因及解决方案错误场景原因分析解决方案一、Vue项目部署步骤

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

golang内存对齐的项目实践

《golang内存对齐的项目实践》本文主要介绍了golang内存对齐的项目实践,内存对齐不仅有助于提高内存访问效率,还确保了与硬件接口的兼容性,是Go语言编程中不可忽视的重要优化手段,下面就来介绍一下... 目录一、结构体中的字段顺序与内存对齐二、内存对齐的原理与规则三、调整结构体字段顺序优化内存对齐四、内

配置springboot项目动静分离打包分离lib方式

《配置springboot项目动静分离打包分离lib方式》本文介绍了如何将SpringBoot工程中的静态资源和配置文件分离出来,以减少jar包大小,方便修改配置文件,通过在jar包同级目录创建co... 目录前言1、分离配置文件原理2、pom文件配置3、使用package命令打包4、总结前言默认情况下,

python实现简易SSL的项目实践

《python实现简易SSL的项目实践》本文主要介绍了python实现简易SSL的项目实践,包括CA.py、server.py和client.py三个模块,文中通过示例代码介绍的非常详细,对大家的学习... 目录运行环境运行前准备程序实现与流程说明运行截图代码CA.pyclient.pyserver.py参

基于Python开发PPTX压缩工具

《基于Python开发PPTX压缩工具》在日常办公中,PPT文件往往因为图片过大而导致文件体积过大,不便于传输和存储,所以本文将使用Python开发一个PPTX压缩工具,需要的可以了解下... 目录引言全部代码环境准备代码结构代码实现运行结果引言在日常办公中,PPT文件往往因为图片过大而导致文件体积过大,

使用DeepSeek API 结合VSCode提升开发效率

《使用DeepSeekAPI结合VSCode提升开发效率》:本文主要介绍DeepSeekAPI与VisualStudioCode(VSCode)结合使用,以提升软件开发效率,具有一定的参考价值... 目录引言准备工作安装必要的 VSCode 扩展配置 DeepSeek API1. 创建 API 请求文件2.

IDEA运行spring项目时,控制台未出现的解决方案

《IDEA运行spring项目时,控制台未出现的解决方案》文章总结了在使用IDEA运行代码时,控制台未出现的问题和解决方案,问题可能是由于点击图标或重启IDEA后控制台仍未显示,解决方案提供了解决方法... 目录问题分析解决方案总结问题js使用IDEA,点击运行按钮,运行结束,但控制台未出现http://

解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题

《解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题》文章详细描述了在使用lombok的@Data注解标注实体类时遇到编译无误但运行时报错的问题,分析... 目录问题分析问题解决方案步骤一步骤二步骤三总结问题使用lombok注解@Data标注实体类,编译时

C语言小项目实战之通讯录功能

《C语言小项目实战之通讯录功能》:本文主要介绍如何设计和实现一个简单的通讯录管理系统,包括联系人信息的存储、增加、删除、查找、修改和排序等功能,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录功能介绍:添加联系人模块显示联系人模块删除联系人模块查找联系人模块修改联系人模块排序联系人模块源代码如下