详解AP3216C(三合一sensor: 光照、距离、照射强度)驱动开发

本文主要是介绍详解AP3216C(三合一sensor: 光照、距离、照射强度)驱动开发,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

概述

1 认识AP3216C

1.1 AP3216C特性

1.2 AP3216C内部结构

1.3 AP3216C 硬件电路

1.4 AP3216C工作时序

1.4.1 I2C 写数据协议

1.4.2 I2C 读数据协议

1.5 重要的寄存器

1.5.1 系统配置寄存器

1.5.2 和中断相关寄存器

1.5.3 IR数据寄存器

1.5.4 ALS 数据寄存器

1.5.5 PS 数据寄存器

2 驱动开发

2.1 查看i2c总线下的设备

2.2 编写驱动代码 

 3 编写测试代码

3.1 测试代码实现

3.2 Makefile

4 测试

4.1 编译代码

4.2 运行测试程序


概述

        本文详细介绍AP3216C的特性,内部结构,操作时序和寄存器的参数意义,并使用linux platform tree 下i2c 驱动接口,实现了AP3216C的驱动程序。并且编写了一个测试范例,验证该驱动程序的性能。 其可以正确的读出sensor内部的数据。

源代码下载地址: AP3216Clinux环境下的驱动程序资源-CSDN文库

1 认识AP3216C

1.1 AP3216C特性

AP3216C是敦南科技出品的一款集成sensor, 其中包括 :ALS(数字型环境光线感应 sensor),PS(测距sensor)IR(照射sensor)。这款sensor主要用在手机、平板电脑、电视、显示器、数码相机等产品上。

1)驱动方式: 采用标准的I2C接口,且工作在快速模式(400K Hz)

2)输出模块可选: ALS, PS+IR, ALS+PS+IR, PD,ALS once, SW Reset, PS+IR once and ALS+PS+IR once.

3) 高分辨率:

数字型环境光线感应 sensor ,采用 16-bit 有效数据输出,数据采集范围( 0~65535 )

测距sensor,采用 10-bit 有效数据输出, 数据采集范围( 0~1023 )

1.2 AP3216C内部结构

由下结构图可以看见: ALS和PS分别和ADC模块连接,以采集外部数据 。IR本分隔在一个单独的模块。

1.3 AP3216C 硬件电路

AP3216C采用标准的i2c驱动模式,其和MCU之间通过3个线连接,SDA和SCL是I2C的驱动线,还提供一个中断引脚INT

1.4 AP3216C工作时序

AP3216C采用标准的i2c驱动接口,其slave 设备地址为:0x1e

1.4.1 I2C 写数据协议

1) 写方式一: 写寄存器地址

S: start 信号

Slave address : 7 bit

W: 写数据bit

A: ACK信号

Register Address: 寄存器地址

P: Stop信号

详细时序图:

2) 写方式二: 写寄存器地址 和数据

S: start 信号

Slave address : 7 bit

W: 使能写数据bit

A: ACK信号

Register Address: 寄存器地址

register Command: 写寄存器数据

P: Stop信号

详细时序图:

1.4.2 I2C 读数据协议

1) 读方式一: 读寄存器地址

S: start 信号

Slave address : 7 bit

R: 使能读数据bit

A: ACK信号

Register command: 寄存器数据

N: NACK信号

P: Stop信号

详细时序图:

2) 读方式二: 读寄存器地址的数据

S: start 信号

Slave address : 7 bit

R: 使能读数据bit

W: 使能写数据bit

A: ACK信号

Register command: 寄存器数据

N: NACK信号

P: Stop信号

详细时序图:

1.5 重要的寄存器

AP3216C内部有许多寄存器,其地址空间(0x00 ~ 0x2d ),由于篇幅所限,这里不对每个寄存器做一一介绍。如需了解,可参看文档:AP3216C Rev0.86. pdf。 本文主要介绍系统寄存器部分,地址空间(0x00 ~ 0x0f。各个寄存器的功能,看下表:

1.5.1 系统配置寄存器

该寄存器地址位0x00, 低位3个bit(bit-0 bit-1,bit-2)用于配置系统工作模式

具体模式如下表:

1.5.2 和中断相关寄存器

中断状态寄存器: address = 0x01

BIT-0: ALS-INT 用来表示中断是否发生, B0=1 表示ALS中断被触发, B0 =0 示ALS中断未被被触发

BIT-1: PS-INT 用来表示中断是否发生, B0=1 表示PS中断被触发, B0 =0 示PS中断未被被触发

中断清除寄存器: address = 0x02

当配置CLR_MNR = 0时, 在读取寄存器(0x0C, 0x0D, 0x0E, 0x0F)的值后,芯片会自动清除中断;

当配置CLR_MNR = 1时,需要软件强制把寄存器0x01的对应位置位为1,清除中断;

1.5.3 IR数据寄存器

对应地址: 0x0a 和0x0b

0x0a地址中,bit0和bit1 为数据位,表示低字节位, IR_OF为数据溢出标记,当IR_OF=1, 表明IR值过高,其会影响PS的数据的有效性

0x0b地址中,为IR 数据高字节位

1.5.4 ALS 数据寄存器

对应地址: 0x0c 和0x0d

1.5.5 PS 数据寄存器

对应地址: 0x0E 和0x0F

IR_OF = 1,表示读取的数据有效。IR_OF = 0,表示读取的数据无效。

2 驱动开发

2.1 查看i2c总线下的设备

i2c总线上可以挂载多个device,其要求在同一条总线上,每个设备的地址必须唯一性。如果两个设备的地址一样,会出现时序混乱。 下面通过命令来探测一下i2c总线下的设备情况。

查看i2c-0下设备情况

使用命令

 i2cdetect -a 0

执行该命令后,列出设备地址信息: 该总线下有两个设备,其地址分别为:0x1a和0x1e

2.2 编写驱动代码 

创建drv_ap3216c.c,编写如下代码

/***************************************************************
Copyright  2024-2029. All rights reserved.
文件名     : drv_ap3216c.c
作者       : tangmingfei2013@126.com
版本       : V1.0
描述       : ap3216c 驱动程序
其他       : 无
日志       : 初版V1.0 2024/02/01***************************************************************/
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/types.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <linux/fs.h>
#include <errno.h>
#include <assert.h>
#include <string.h>
#include <time.h>
#include "drv_ap3216.h"#define DEV_FILE               "/dev/i2c-0"static int fd = -1;static void msleep(unsigned int time)
{struct timespec sleeper, temp;sleeper.tv_sec = (time_t)(time/1000);sleeper.tv_nsec = (long)(time%1000)*1000000;nanosleep(&sleeper, &temp);
}static int ap3216c_write_reg( unsigned char reg, unsigned char cmd)
{int              ret = -1;unsigned char    buf[2] = {0};buf[0] = reg;buf[1] = cmd;ret = write(fd, buf, 2);if( ret < 0 ){printf("write cmd to ap3216c register failure.\n");return -1;}return 0;
}static int ap3216c_read_reg( unsigned char reg, unsigned char *val)
{int           ret = -1;unsigned char buf[1] = {0};buf[0] = reg;           //send register address ret = write( fd, buf, 1);if( ret < 0 ){printf("write cmd to ap3216c register failure.\n");return -1;}ret = read(fd, buf, 1);  //read data from the register if( ret < 0 ){printf("get the humidy failure.\n");return -1;}*val = buf[0];return 0;
}void ap3216c_read_datas(ap3216c_data *pdata)
{unsigned char i =0;unsigned char buf[6], val = 0;/* read all sensor‘ data */for( i = 0; i < 6; i++)    {ap3216c_read_reg( AP3216C_IRDATALOW + i, &val); buf[i] = val;}/* IR   */if(buf[0] & 0X80){  /* IR_OF位为1,则数据无效 */pdata->ir = 0;}        else {        pdata->ir = ((unsigned short)buf[1] << 2) | (buf[0] & 0X03); }        /* ALS  */  pdata->als = ((unsigned short)buf[3] << 8) | buf[2]; /* PS */if(buf[4] & 0x40){    /* IR_OF位为1,则数据无效 */pdata->ps = 0; }        else{                pdata->ps = ((unsigned short)(buf[5] & 0X3F) << 4) | (buf[4] & 0X0F); }
}void ap3216c_release( void )
{close( fd );
}int ap3216c_init(void)
{// init i2c fd = open(DEV_FILE, O_RDWR);if( fd < 0 ){close( fd );printf("%s %s i2c device open failure: %s\n", __FILE__, __FUNCTION__, strerror(errno));return -1;}ioctl(fd, I2C_TENBIT, 0);ioctl(fd, I2C_SLAVE, AP3216C_ADDR);// reset sensor ap3216c_write_reg( AP3216C_SYSTEMCONG, 0x04);msleep(2);// enable ALS、PS+IRap3216c_write_reg( AP3216C_SYSTEMCONG, 0X03);msleep(2);return fd;
}

在drv_ap3216c.h中,编写如下代码:

#ifndef __DRV__AP3216_H
#define __DRV__AP3216_H#ifdef __cplusplus
extern "C" {
#endif#define AP3216C_ADDR          0X1E/* AP3316C寄存器 */
#define AP3216C_SYSTEMCONG    0x00    /* 配置寄存器       */
#define AP3216C_INTSTATUS     0X01    /* 中断状态寄存器   */
#define AP3216C_INTCLEAR      0X02    /* 中断清除寄存器   */
#define AP3216C_IRDATALOW     0x0A    /* IR数据低字节     */
#define AP3216C_IRDATAHIGH    0x0B    /* IR数据高字节     */
#define AP3216C_ALSDATALOW    0x0C    /* ALS数据低字节    */
#define AP3216C_ALSDATAHIGH   0X0D    /* ALS数据高字节    */
#define AP3216C_PSDATALOW     0X0E    /* PS数据低字节     */
#define AP3216C_PSDATAHIGH    0X0F    /* PS数据高字节     */typedef struct _ap3216c_data{unsigned short ir; unsigned short als; unsigned short ps;      /* */ 
}ap3216c_data;void ap3216c_read_datas(ap3216c_data *pdata);
int ap3216c_init(void);#ifdef __cplusplus
}
#endif#endif /* __DRV__AP3216_H */

 3 编写测试代码

测试主要实现,调用驱动程序接口,读取ALS,PS,IR数据,并打印出来

3.1 测试代码实现

创建一个test_ap3216.c,编写如下代码:

/***************************************************************
Copyright  2024-2029. All rights reserved.
文件名     : test_ap3216.c
作者       : tangmingfei2013@126.com
版本       : V1.0
描述       : 验证dev_ap3216.c 
其他       : 无
日志       : 初版V1.0 2024/02/1***************************************************************/
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/types.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <linux/fs.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <assert.h>
#include <string.h>
#include <time.h>
#include "drv_ap3216.h"int main(void)
{ap3216c_data stru_data;int count_run = 100;int set;set = ap3216c_init();if( set < 0){printf("initial ap3216c failure.\n");return -1;}while( count_run > 0){ap3216c_read_datas( &stru_data );printf("ir = %d, als = %d, ps = %d \r\n", stru_data.ir, stru_data.als, stru_data.ps);count_run--;sleep(1);}ap3216c_release();return 0;
}

3.2 Makefile

在测试程序的目录下,创建一个makefile文件,编写如下代码

CFLAGS= -Wall -O2
CC=/home/ctools/gcc-linaro-4.9.4-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc
STRIP=/home/ctools/gcc-linaro-4.9.4-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-striptest_ap3216: test_ap3216.o drv_ap3216.o$(CC) $(CFLAGS) -o test_ap3216 test_ap3216.o drv_ap3216.o$(STRIP) -s test_ap3216clean:rm -f test_ap3216 test_ap3216.o drv_ap3216.o

4 测试

4.1 编译代码

使用Make命令编译代码,然后将生成的可执行文件copy到NFS的共享目录下,方便在板卡中运行程序。

4.2 运行测试程序

 运行测试程序,可以看见在终端上打印出来sensor的数据

这篇关于详解AP3216C(三合一sensor: 光照、距离、照射强度)驱动开发的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

【区块链 + 人才服务】区块链集成开发平台 | FISCO BCOS应用案例

随着区块链技术的快速发展,越来越多的企业开始将其应用于实际业务中。然而,区块链技术的专业性使得其集成开发成为一项挑战。针对此,广东中创智慧科技有限公司基于国产开源联盟链 FISCO BCOS 推出了区块链集成开发平台。该平台基于区块链技术,提供一套全面的区块链开发工具和开发环境,支持开发者快速开发和部署区块链应用。此外,该平台还可以提供一套全面的区块链开发教程和文档,帮助开发者快速上手区块链开发。

Vue3项目开发——新闻发布管理系统(六)

文章目录 八、首页设计开发1、页面设计2、登录访问拦截实现3、用户基本信息显示①封装用户基本信息获取接口②用户基本信息存储③用户基本信息调用④用户基本信息动态渲染 4、退出功能实现①注册点击事件②添加退出功能③数据清理 5、代码下载 八、首页设计开发 登录成功后,系统就进入了首页。接下来,也就进行首页的开发了。 1、页面设计 系统页面主要分为三部分,左侧为系统的菜单栏,右侧