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外设的学习。
未完待续

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

TCP通讯

第二十一章 网络通信 本章节主要讲解的是TCP和UDP两种通信方式它们都有着自己的优点和缺点 这两种通讯方式不通的地方就是TCP是一对一通信 UDP是一对多的通信方式 接下来会一一讲解 TCP通信 TCP通信方式呢 主要的通讯方式是一对一的通讯方式&#xff0c;也有着优点和缺点…

maven-assembly-plugin 自定义打包

我想把input文件夹给打包进去 pom文件 <build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><executions><execution><!-- 配置执行器 --><i…

黑苹果之主板篇

一、什么是主板 主板&#xff0c;又叫主机板&#xff08;mainboard&#xff09;、系统板&#xff08;systemboard&#xff09;、或母板&#xff08;motherboard&#xff09;&#xff0c;是计算机最基本的同时也是最重要的部件之一。主板一般为矩形电路板&#xff0c;上面安装了…

如何使用HadSky搭配内网穿透工具搭建个人论坛并发布至公网随时随地可访问

文章目录 前言1. 网站搭建1.1 网页下载和安装1.2 网页测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;2.3 Cpolar稳定隧道&#xff08;本地设置&#xff09;2.4 公网访问测试 总结 前言 经过多年的基础…

ubuntu18.04 vscode 安装 vue.volar Vue Language Features (Volar) , vue3 必备插件

直接在vscode 里面下载老是失败&#xff0c;不是网络问题&#xff0c;而是vue.volar插件配置的vscode版本与vscode版本不一致导致出现安装失败 官网下载最新的 vue.volar插件 https://marketplace.visualstudio.com/ 官网搜索 vue.volar 然后打开 Vue Language Features (Vol…

基于互一致性学习的半监督医学图像分割

Mutual consistency learning for semi-supervised medical image segmentation 基于互一致性学习的半监督医学图像分割背景贡献半监督学习 其它缓解过拟合的方法实验方法损失函数Thinking 基于互一致性学习的半监督医学图像分割 Medical Image Analysis 81 (2022) 102530 背…

排序:直接选择排序

直接选择排序&#xff1a; 本质&#xff1a; 直接选择排序的本质就是在数组中进行遍历挑选出最大的元素&#xff0c;讲最大的元素放到对应的位置后&#xff0c;再次选出次大的位置&#xff0c;而后又放到对应的位置..........................直到数组成为一个有序序列。 优…

编程应用实例,养生馆会员管理系统软件统计查询教程

一、前言 编程应用实例&#xff0c;养生馆会员管理系统软件&#xff0c; 导航栏菜单有 系统设置&#xff1a;可以设置操作员的权限以及打印机参数设置。 会员信息登记&#xff1a;可以直接用手机号登记电子会员卡 会员卡充值&#xff1a;可以直接报手机号充值&#xff0c;…

蓝牙挂耳式耳机什么牌子好?推荐几款自用不错的蓝牙耳机

"放弃纠结&#xff0c;挑选蓝牙挂耳耳机从此不再头疼&#xff01;面对市面上琳琅满目的选择&#xff0c;到底哪个蓝牙耳机好用&#xff0c;成了一个谜&#xff0c;我这里有几款个人亲测过的蓝牙挂耳式耳机&#xff0c;让你在自用的道路上不再盲目&#xff0c;无论是办公、…

【项目日记(一)】高并发内存池项目介绍

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:项目日记-高并发内存池⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习C   &#x1f51d;&#x1f51d; 项目日记 1. 前言2. 什么是高并发内存池…

【动态规划】02斐波那契数列模型_三步问题(easy)

题目链接&#xff1a;leetcode三步问题 目录 题目解析&#xff1a; 算法原理: 1.状态表示 2.状态转移方程 3.初始化 4.填表顺序 5.返回值 编写代码: 题目解析&#xff1a; 题目让我们求小孩到达n阶台阶的时候&#xff0c;可以有多少上楼梯方式&#xff1b; 由题可得&a…

作业12.7

1.实现一个登录窗口界面 源文件&#xff1a; #include "mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent) {//设置界面大小&#xff0c;名称与图标this->setFixedSize(1280,720);this->setWindowTitle("泰坦陨落");thi…

Adobe系列软件:创意之旅的得力助手

在数字创意领域&#xff0c;Adobe系列软件一直以其卓越的性能和广泛的应用而备受瞩目。从图像处理、视频编辑到音频编辑&#xff0c;从网页开发到排版设计&#xff0c;这些软件都提供了强大的功能和工具&#xff0c;帮助用户实现他们的创意。 让我们详细介绍这些软件的作用&…

使用python操作excel文档

导入xlsxwriter包 python轻量化的语言&#xff0c;用来操作文档简直易如反掌&#xff0c;首先你需要导入的是import xlsxwriter包&#xff0c;他包括了操作文档所需要的全部工具方法&#xff0c;你只需要调用就好了。 操作excel指南 首先你需要创建一个文件xlsxwriter.Workb…

1.10 C语言之外部变量与作用域

1.10 C语言之外部变量与作用域 一、外部变量概述二、练习 一、外部变量概述 我们说&#xff0c;函数&#xff08;不管是main函数还是其他函数&#xff09;内部定义的变量&#xff0c;其作用范围都只在函数内部&#xff0c;我们把这些变量叫做自动变量或者局部变量。除了局部变…

从文字到使用,一文读懂Kafka服务使用

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

【UE5】瞬移+马赛克过渡效果

效果 步骤 1. 新建一个工程&#xff0c;创建一个Basic关卡 2. 添加第三人称游戏资源到内容浏览器 3. 新建一个材质&#xff0c;这里命名为“M_Pixel” 打开“M_Pixel”&#xff0c;设置材质域为“后期处理” 在材质图表中添加如下节点 此时效果如下&#xff0c;已经有马赛克的…

Textual Inversion

参考博客1:https://www.bilibili.com/read/cv25430752/

数据结构和算法-栈

数据结构和算法-栈 1. 栈的介绍 栈的介绍&#xff1a; 栈的英文为(stack)栈是一个先入后出的有序列表栈是限制线性表中元素的插入和删除只能在线性表的同一端进行的一种特殊线性表。允许插入和删除的一端&#xff0c;为变化的一端&#xff0c;称为栈顶&#xff0c;另一端为固…

2024 年前端技术发展大趋势一览

随着技术的不断演进&#xff0c;前端开发领域也在不断变化和发展。AI、Vue、Web3等都是当前前端开发的新趋势&#xff0c;它们为开发者提供了更多的机会和挑战。今天这篇文章&#xff0c;咱们就来聊一聊&#xff0c;最新前端技术趋势。 1.AI 年初的 ChatGPT 火爆全网&#xff0…