Linux学习笔记7-IIC的应用和AP3216C

接下来进入其他两种串行通信方式:SPII2C的学习,因为以后的项目中会用到这些通信方式,而且正点原子的开发板里面也有用I2C和SPI通信的传感器来做实例,分别是一个距离传感器和六轴陀螺仪,这样就可以很好的通过实例来学习了。这两个通信方式最大的区别就是速度,I2C的最高通信速度是400KHz,而SPI最高可以到几百MHz,所以在低速应用时I2C即可,到了高速的场合就必须用SPI了。
先学习I2C的应用,这里还是和以前一样,重点放在应用上,然后研究距离传感器的datasheet来尝试编写传感芯片的驱动!
I.MX6UL有4路I2C,正点原子写的I2C驱动包含了一系列的函数,这些函数其实就是对I2C相关的寄存器做一些置1或者0的操作,所以我们可以学习下常用的对寄存器按位逻辑操作的方法:

  1. 使某一位置0,其他位不变
base->I2CR &= ~(1 << 7);  //第7位置0,使用按位与
base->I2CR &= ~((1 << 5) | (1 << 4) | (1 << 3));   //[5:3]位同时清零
  1. 使某一位置1,其他位不变
base->I2CR |= ( 1 << 7);  //第7位置1,按位或
base->I2CR |=  (1 << 4) | (1 << 2);  //同时把第4位和第1位置1
  1. 检测某一位是否为0或者1
if(base->I2SR & (1 << 5)) == 1  //即I2SR的第五位是否为1,如果为1则逻辑与的结果是1
if((base->I2CR) & (1 << 5)) == 0)  即I2SR的第五位是否为0

这里不会深入研究正点原子的I2C驱动,只需要知道如何调用函数进行I2C数据的读写即可,把重点放在开发板上的传感器芯片AP3216C上。研究它的datasheet先。

The AP3216C is an integrated ALS & PS module that includes a digital ambient light sensor [ALS], a proximity sensor [PS], and an IR LED in a single package.
所以它包含了3个模块,光传感器ALS、距离传感器PS和红外线LEDIR,最常用在手机和平板上用来检测耳朵是否接触听筒,或者光传感器来检测光照强度调节屏幕亮度。

在datasheet里查到这个芯片的地址是0x1E,再研究datasheet第12页的表格,传感器的设置、数据读取和写入都是从不同的寄存器地址,所以我们先用一些宏来把寄存器地址在头文件中定义好,方便后面调用。宏的名字一定要一眼就看出意思来

#define AP3216C_ADDR    	0X1E	/* AP3216C器件地址 */#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数据高字节 			*/

先编写读写数据的函数ap3216c_write(...),其实就是配置i2c_transfer结构体的各个参数,这个函数的参数是设备地址、要写入的寄存器、写入的数据,返回值可以扩展,可以是0-4,对应未写入(0),I2C14写入(返回值14)

unsigned char ap3216c_write(unsigned char addr, unsigned char reg, unsigned char data)  
{unsigned char status = 0;   unsigned char writedata = data;struct i2c_transfer masterXfer;  			/* 定义masterXfer结构体并配置 */masterXfer.slaveAddress = addr; 			/* 设备地址 */masterXfer.direction = kI2C_Write;			/* 方向为写入 */masterXfer.subaddress = reg;				/* 要写入的寄存器地址 */masterXfer.subaddressSize = 1;				/* 地址长度一个字节  */masterXfer.data = &writedata;				/* 要写入的数据 */masterXfer.dataSize = 1;  					/* 写入数据长度1个字节 */if(i2c_master_transfer(I2C1, &masterXfer))status=1;return status;}

同样的可以编写读函数ap3216c_read(...),参数是设备地址、要读的寄存器、返回值就是读取的数据。

unsigned char ap3216c_read(unsigned char addr,unsigned char reg)
{unsigned char val=0;struct i2c_transfer masterXfer;	masterXfer.slaveAddress = addr;				/* 设备地址 */masterXfer.direction = kI2C_Read;			/* 读取数据 */masterXfer.subaddress = reg;				/* 要读取的寄存器地址 */masterXfer.subaddressSize = 1;				/* 地址长度一个字节	*/masterXfer.data = &val;						/* 接收数据缓冲区 */masterXfer.dataSize = 1;					/* 读取数据长度1个字节 */i2c_master_transfer(I2C1, &masterXfer);return val;
}

根据读写的基础函数,我们可以编写读写IRPSALS几个模块数据的函数ap3216c_readdata(...)

void ap3216c_readdata(unsigned short *ir, unsigned short *ps, unsigned short *als)
{unsigned char buf[6];unsigned char i;/* 循环读取所有传感器数据 */for(i = 0; i < 6; i++)	{buf[i] = ap3216c_read(AP3216C_ADDR, AP3216C_IRDATALOW + i);	 /* 从0X0A到0X0F */}if(buf[0] & 0X80) 	/* IR_OF位为1,则数据无效 */*ir = 0;					else 				/* 读取IR传感器的数据  */*ir = ((unsigned short)buf[1] << 2) | (buf[0] & 0X03); 	/* 只保留buf[0]即IR低字节,并把高字节左移两位,获取IR完整数据 */		*als = ((unsigned short)buf[3] << 8) | buf[2];	/* 读取ALS传感器的数据 	*/  if(buf[4] & 0x40)	/* IR_OF位为1,则数据无效 */*ps = 0;    													else 				/* 读取PS传感器的数据  */*ps = ((unsigned short)(buf[5] & 0X3F) << 4) | (buf[4] & 0X0F); 	
}

至此AP3216C这个芯片的驱动就基本完成了。开发板的硬件上是通过I.MX6UL的I2C1通道和传感器连接,所以一开始需要初始化I2C1,这里就不赘述。
在main.c里的while(1)循环中读取这3个模块的数据并通过串口打印出来:

while(1)
{ap3216c_readdata(&ir, &ps, &als);printf("\r\n Data of IR, PS, ALS is: %d, %d, %d\r\n\r\n", ir, ps, als);delayms(200);
}

Makefile后烧写,在测试时用手去靠近开发板上的芯片,观察输出结果,也可以用光照,看看输出结果是否和预想一致。
在这里插入图片描述

I2C的学习到此结束,接下去进入SPI外设的学习。
未完待续

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/208295.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GRE与顺丰圆通快递盒子

1. DNS污染 随想&#xff1a; 在输入一串网址后&#xff0c;会发生如下变化如果你在系统中配置了 Hosts 文件&#xff0c;那么电脑会先查询 Hosts 文件如果 Hosts 里面没有这个别名&#xff0c;就通过域名服务器查询域名服务器回应了&#xff0c;那么你的电脑就可以根据域名服…

【LeetCode:1466. 重新规划路线 | DFS + 图 + 树】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

Vue 子路由页面发消息给主路由页面 ,实现主页面显示子页面的信息

需求 子页面进入后&#xff0c;能在主页面显示子页的相关信息&#xff0c;比如说主页面的菜单激活的是哪个子页面的菜单项 如上图&#xff0c;当刷新浏览器页面时&#xff0c;让菜单的激活项仍保持在【最近浏览】。 实现方式&#xff1a; 在子页面的create事件中增加&#xff…

Vue:绘制图例

本文记录使用Vue框架绘制图例的代码片段。 可以嵌入到cesium视图中,也可以直接绘制到自己的原生系统中。 一、绘制图例Vue组件 <div v-for="(color, index) in colors" :key="index" class="legend-item"><div class="color-…

深度学习还可以从如下方面进行创新!!

文章目录 一、我认为可以从如下5个方向进行创新总结 一、我认为可以从如下5个方向进行创新 新的模型结构&#xff1a;尽管现在的深度学习模型已经非常强大&#xff0c;但是还有很多未被探索的模型结构。探索新的模型结构可以带来更好的性能和更低的计算成本。 新的优化算法&a…

一个简单的postman设置断言,为何会难住一个工作5年的测试?

postman设置断言 作为一款接口测试工 具&#xff0c;postman需要对发送请求后返回的结果是否正确做验证&#xff0c;在postman中通过 tests页签做请求的验证&#xff0c;也称为断言。 postman设置断言的流程 1、在tests页签截取要对比的实际响应信息&#xff08;响应头、响应…

眼花缭乱的ADN/ADX/DSP/DMP/SSP和他们的关系链

做过互联网广告尤其是程序化广告的同学都遇到过以下这些名词&#xff0c;或许正被他们折磨的焦头烂额&#xff0c;这篇文章&#xff0c;我们就来说说这些概念的含义及他们之间的关系链。 ADN&#xff1a;AD Network——广告网络或广告联盟。连接广告主和媒体的中间商。 ADX&…

stm32串口编程实例-实现数据的收发功能

大家好&#xff0c;今天给大家介绍stm32串口编程实例&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 串口是USART(通用同步/异步收发器)的俗称。 实际上&#xff0c;串行总线并不…

2023年8月8日 Go生态洞察:Go 1.21 版本发布探索

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

中小企业都在用哪些开源项目管理工具?分享15款

推荐15个优秀的开源项目管理工具&#xff0c;比如&#xff1a;ProjectLibre、OpenProject、ERPNext、Redmine、禅道、Tuleap、Restyaboard等。 项目经理面临各种复杂任务&#xff0c;包括追踪任务的进度、评估交付风险和管理整体工作量。为了顺利达成目标&#xff0c;一款靠谱的…

学习IO的第四天

作业 : 使用两个子进程完成两个文件的拷贝&#xff0c;子进程1拷贝前一半内容&#xff0c;子进程2拷贝后一般内容&#xff0c;父进程用于回收两个子进程的资源 #include <head.h>int main(int argc, const char *argv[]) {int rd -1;if((rdopen("./01_test.c&quo…

零基础如何入门HarmonyOS开发?

HarmonyOS鸿蒙应用开发是当前非常热门的一个领域&#xff0c;许多人都想入门学习这个技术。但是&#xff0c;对于零基础的人来说&#xff0c;如何入门确实是一个问题。下面&#xff0c;我将从以下几个方面来介绍如何零基础入门HarmonyOS鸿蒙应用开发学习。 一、了解HarmonyOS鸿…

[JSMSA_CTF] 2023年12月练习题 pwn

一开始没给附件&#xff0c;还以为是3个盲pwn结果&#xff0c;pwn了一晚上没出来&#xff0c;今天看已经有附件了。 pwn1 在init_0里使用mallopt(1,0) 设置global_max_fast0 任何块释放都会进入unsort在free函数里没有清理指针&#xff0c;有UAF将v6:0x100清0&#xff0c;便于…

甘草书店:#10 2023年11月24日 星期五 「麦田创业分享2—世界奇奇怪怪,请保持可可爱爱」

今日继续分享麦田创业经验。 如果你问我&#xff0c;创业过程中是否想过放弃。那么答案是&#xff0c;有那么一次。 那时想要放弃的原因并不是辛苦没有回报&#xff0c;或是资金短缺&#xff0c;而是没能理解“异见者”。 其实事情非常简单&#xff0c;现在反观那时的自己&a…

实例解析关于兔鲜登录tab栏切换案例详细讲解!

文章目录 文章目录 效果图展示 整体制作的一个思路 代码展示 技术细节 小结 效果图展示 点击账户登录显示登录的模块&#xff0c;点击二维码登录显示二维码的模块 整体制作的一个思路 点击哪个模块哪个显示&#xff0c;另外一个模块让它隐藏即可&#xff01; 代码展示 <!…

好莱坞明星识别

一、前期工作 1. 设置GPU from tensorflow import keras from tensorflow.keras import layers,models import os, PIL, pathlib import matplotlib.pyplot as plt import tensorflow as tfgpus tf.config.list_physical_devices("GPU")if gpus:gpu0 …

动态规划——完全背包问题(公式推导,组合、排列)

本文章是对于完全背包 一些题型(如题目所示&#xff0c;组合、排列和最小值类型)的总结和理解&#xff0c;依次记录一下&#xff0c;方便回顾与复习。 本文章是基于个人所总结 实现的&#xff0c;但在其中遇到了一些疑惑与困难&#xff0c;所以总结一篇与完全背包相关的问题。 …

Spring基于注解开发

Component的使用 基本Bean注解&#xff0c;主要是使用注解的方式替代原有的xml的<bean>标签及其标签属性的配置&#xff0c;使用Component注解替代<bean>标签中的id以及class属性&#xff0c;而对于是否延迟加载或是Bean的作用域&#xff0c;则是其他注解 xml配置…

四招打造完美分层自动化测试框架,让测试更高效!

写在前面 我们刚开始做自动化测试&#xff0c;可能写的代码都是基于原生写的代码&#xff0c;看起来特别不美观&#xff0c;而且感觉特别生硬。 来看下面一段代码&#xff1a; 具体表现如下&#xff1a; driver对象在测试类中显示 定位元素的value值在测试类中显示 定位元素…

Navicat 技术指引 | 适用于 GaussDB 分布式的用户/权限功能

Navicat Premium&#xff08;16.3.3 Windows 版或以上&#xff09;正式支持 GaussDB 分布式数据库。GaussDB 分布式模式更适合对系统可用性和数据处理能力要求较高的场景。Navicat 工具不仅提供可视化数据查看和编辑功能&#xff0c;还提供强大的高阶功能&#xff08;如模型、结…