【裸机开发】I2C 通信接口(二)—— I2C 寄存器解析

2023-10-29

目录

一、硬件原理图分析

二、IO 复用寄存器解析

三、I2C 寄存器解析

3.1 时钟配置

3.2  I2C1_IADR(设置从机地址)

3.3  I2C1_IFDR(设置分频值)

3.4  I2C1_I2CR(I2C使能、中断控制)

3.5  I2C1_I2SR(保存通信状态)

3.6  I2C1_I2DR(数据发送 / 接收)

四、 AP3216C 解析

1、功能选择(0x00 — bit2:0)

2、IR + PS

3、ALS


一、硬件原理图分析

I2C 主要涉及到两个引脚,分别是 SCL 和 SDA,既然是涉及 IO,那就需要知道哪两个引脚可以被复用为 SCL 和 SDA。

首先看底板上的 I2C 模块。我们发现,IMX.6ULL 有两个 I2C 控制器,分别是 I2C1 和 I2C2。假设我们要使用 I2C1 。

然后再看底板上的 I2C 模块连接到了核心板上的哪些引脚。

最后就是找到和 UART4_TXD、UART4_RXD 相关的复用寄存器。

① TXD 相关(复用为SCL)

  • IOMUXC_SW_MUX_CTL_PAD_UART4_TX_DATA
  • IOMUXC_SW_PAD_CTL_PAD_UART4_TX_DATA

② RXD 相关(复用为 SDA)

  • IOMUXC_SW_MUX_CTL_PAD_UART4_RX_DATA
  • IOMUXC_SW_PAD_CTL_PAD_UART4_RX_DATA

二、IO 复用寄存器解析

IO 初始化就涉及到两方面,一个是指定复用为哪个功能,一个是配置复用引脚的电气属性,电气属性的初值和之前一样,设为 0x10B0。

  • IO 复用
    • IOMUXC_SW_MUX_CTL_PAD_UART4_TX_DATA复用为 SCL
    • IOMUXC_SW_MUX_CTL_PAD_UART4_RX_DATA(复用为 SDA)

  • 配置电气属性
    • IOMUXC_SW_PAD_CTL_PAD_UART4_TX_DATA(初值为 0x70B0)
    • IOMUXC_SW_PAD_CTL_PAD_UART4_RX_DATA(初值为 0x70B0)
/*************** SCL复用初始化 ******************/
寄存器(基地址): IOMUXC_SW_MUX_CTL_PAD_UART4_TX_DATA (0x20E00B4)
寄存器(基地址): IOMUXC_SW_PAD_CTL_PAD_UART4_TX_DATA (0x20E0340)
初始化操作:
    IOMUXC_SW_MUX_CTL_PAD_UART4_TX_DATA &=~ (0xF);    // 低4位清零
    IOMUXC_SW_MUX_CTL_PAD_UART4_TX_DATA |= 1;         // 复用为I2C1_SCL

    IOMUXC_SW_PAD_CTL_PAD_UART4_TX_DATA = 0x70B0;

/*************** SDA复用初始化 ******************/
寄存器(基地址): IOMUXC_SW_MUX_CTL_PAD_UART4_RX_DATA (0x20E00B8)
寄存器(基地址): IOMUXC_SW_PAD_CTL_PAD_UART4_RX_DATA (0x20E0344)
初始化操作:
    IOMUXC_SW_MUX_CTL_PAD_UART4_RX_DATA &=~ (0xF);    // 低4位清零
    IOMUXC_SW_MUX_CTL_PAD_UART4_RX_DATA |= 1;         // 复用为I2C1_SDA

    IOMUXC_SW_PAD_CTL_PAD_UART4_RX_DATA = 0x70B0;

三、I2C 寄存器解析

3.1 时钟配置

早在学习 CCM 配置时钟主频的时候,就已经配置过该寄存器了。 CSCMR1[PERCLK_PODF] 配置为 1 分频时,IPG_CLK_ROOT = PERCLK_CLK_ROOT = 66 MHz。

配置方式参考:IPG_CLK 配置

3.2  I2C1_IADR(设置从机地址)

如果当前设备是从机,才需要设置 I2C1_IADR 寄存器。如果当前设备是主机,设置的是I2C1_I2DR 寄存器。

寄存器: I2C1_IADR
基地址: 0x21A0000
地址设置: 
    I2C1_IADR = 0;           // 地址清零
    I2C1_IADR |= address;    // address 表示从机地址

3.3  I2C1_IFDR(设置分频值)

在 I2C 控制器内部还可以再次分频,时钟源就是 PERCLK_CLK_ROOT = IPG_CLK_ROOT = 66 MHz。标准模式下, I2C 传输速度最高可达 100 kbit/s,那么分频数 = 66000000 / 100000 = 660

我们要在下面这个表中找到分频数最接近 660 的,我们发现最接近的就是 640,因此寄存器要设置的值可以是 0x15、0x38

寄存器: I2C1_IFDR
基地址: 0x21A0004
地址设置: 
    I2C1_IFDR = 0x15;    // 分频值为 640    

3.4  I2C1_I2CR(I2C使能、中断控制)

bit 2: 产生一次重复启动。一般是主机用于修改通信方向或通信地址。如果总线已经被占用,却不是被当前设备占用,此时无法发送(0: 不重复启动        1: 产生一次重复启动)

bit 3: 发送应答。(0: 发送一次应答,相当于ACK=0        1: 不发送应答,相当于ACK=1)

bit 4: 设置通信方向。本质是在表明接下来要向 DR 寄存器读数据还是向 DR 寄存器写数据(0: 接收(读)        1: 发送(写) ) 

bit 5: 当前设备是主机还是从机。该位一旦被置1,相当于发出了要占用主线的开始信号。如果有多主机参与总线占用,会发生仲裁,当前设备如果仲裁失败,当前位会被清零(0: 从机        1: 主机)

bit 6: I2C 中断使能(0: 禁用        1: 使能)

bit 7: I2C 使能(0: 禁用        1: 使能)

// 一开始不会初始化所有的位,一些位只有在实际使用才会被设置
寄存器: I2C1_I2CR
基地址: 0x21A0008 
相关操作:
    /* 
     * 发送开始信号(抢占总线,让自己成为主机)
     * bit 4: 1 发送
     * bit 5: 1 主机
     */
    I2C1_I2CR |= ((1 << 4) | (1 << 5));
    
    /* 
     * 发送重复开始信号(总线已经被占用,而且必须是当前设备占用总线,才能发送重复开始信号)
     * bit 2: 1 产生一次重复开始信号
     * bit 4: 1 发送
     */
    I2C1_I2CR |= ((1 << 2) | (1 << 4));

    /* 
     * 产生一个停止信号 
     * bit 3: 0 产生一个ACK
     * bit 4: 0 接收(要产生一个ACK,当前设备必须为接收模式)
     * bit 5: 0 从机
     */
    I2C1_I2CR &= ~((1 << 3) | (1 << 4) | (1 << 5));

3.5  I2C1_I2SR(保存通信状态)

bit 0: 收到了ACK/NACK(0: 收到的是ACK        1: 收到的是NACK)

bit 1: 是否有I2C中断挂起。下面是触发中断的三种情况(0: 无中断挂起        1: 有中断挂起)

  • 一个字节的数据传输完成
  • 从机接收的模式下,与主机发送的地址匹配
  • 仲裁失败,丢失总线占用权

bit 2: 当前通信方向(0: 从机接收,主机发送        1: 从机发送,主机接收)

bit 4: 仲裁是否失败。和上面I2CR 的 bit 5 不一样,这里就是纯粹的获取仲裁结果。

以下三种情况会被判为仲裁失败,该位的状态由硬件控制,软件不可设置(0: 仲裁没有失败        1: 仲裁失败,丢失主线控制权)

  • 总线被占用时,发送开始信号
  • 当前设备为从机,请求重复启动
  • 主机没有发送停止信号,但是却检测到了停止信号

bit 5: I2C 总线是否空闲(0: 总线空闲        1: 总线被占用)

bit 6: 当前设备是否为从机。如果当前设备是从机,需要根据 I2SR 的 bit 2 获取当前的通信方向,并设置 I2CR 寄存器的对应位,即bit 4(0: 当前设备没有被定位        1: 当前设备被指定为从机)

bit 7: 当前数据传输状态。其实就是判断 DR寄存器是否可以用于下一次传输。(0: 数据传输中        1: 传输完成,当时钟的第9个周期的下降沿出现时,才会被置 1)

注意:每一次的传输数据,无论是发送还是接收,在使用 DR 寄存器之前,需要先等待 DR 寄存器可用,类似于一种初始化操作。

  • bit 1:数据是否传递完毕
  • bit 7:DR 寄存器是否可以被用于下一次传输
寄存器: I2C1_I2SR
基地址: 0x21A000C 

3.6  I2C1_I2DR(地址 / 数据传输)

如果当前设备是接收方,该寄存器保存的是接收到的数据;如果当前设备是发送方,该寄存器保存的是要被发送的数据。

寄存器: I2C1_I2DR
基地址: 0x21A0010

四、 AP3216C 解析

AP3216C 是一个三合一的集成模块,集成了 ALS(光传感器)、PS(接近传感器)、IR(红外LED),兼容I2C 接口。

AP3216C 参考手册给出了系统寄存器以及ALS、PS、IR各个模块的详细寄存器配置,系统配置主要是要启用哪些模块,以及不同模块获取到的数据;如果要对某个模块的细微调整,那就要查看各个模块的详细寄存器配置了。

1、功能选择(0x00 — bit2:0)

System Configure 寄存器占一个字节,地址为 0x00

其中bit 2:0 可以控制三个模块的开启与关闭

2、IR + PS

IR一般和PS搭配使用,IR 数据占 10 bit,PS 数据也是占 10 bit。

① IR Data:保存的是当前环境下的红外光强度。0x0A 和 0x0B 所在寄存器大小为一个字节

 ② PS Data:保存物体当前的位置。0x0E 和 0x0F 所在寄存器大小为一个字节

3、ALS

ALS 数据占 16 bit,保存的是环境光强度。0x0C 和 0x0D 所在寄存器大小为一个字节

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【裸机开发】I2C 通信接口(二)—— I2C 寄存器解析 的相关文章

  • 历届试题 高僧斗法  (博弈)

    题目 历届试题 高僧斗法 时间限制 1 0s 内存限制 256 0MB 锦囊1 博弈论 NIM取子游戏 锦囊2 将两个两个看成一组 他们之间的间隔可以看成一个NIM取子游戏 问题描述 古时丧葬活动中经常请高僧做法事 仪式结束后 有时会有 高
  • tomcat加载jar包顺序

    概述 项目使用springMVC serviceImpl注入的一个bean无法找到 究其原因是无法找到日志类 其实在spring的配置文件中配置了bean 而且程序代码在其他人的机子上运行不报错 我这边抱错 类找不到apache commo
  • 华为手机如何固定横屏_华为手机屏幕如何转为横屏?很简单,只需这样设置

    设置华为手机横屏显示 需要打开手机的 自动旋转 功能 在使用时将手机机身横置即可 以华为P20Pro为例 详细操作步骤如下 1 从屏幕顶部向下滑动 调出系统的通知面板 2 向下拖拽通知面板 让面板显示全部快捷功能 3 在通知面板中 找到并打
  • SQLyog快捷键,这一篇就够!!

    我们在使用SQLyog进操作时 如果不使用快捷键 会很麻烦 尤其是多行注释这种骚操作 所以在非常忙碌的工作中 使劲的挤了挤 挤出点时间 来整理一下sqlyog的常用快捷键骚操作 一 连接 Ctrl M 创建一个新的连接 Ctrl N 使用当
  • C# 参数传递(引用类型参数)

    目录 一 引言 二 引用类型参数作为值参数传递 三 引用类型参数作为引用参数传递 一 引言 方法中参数的传递方式主要有值参数传递和引用参数传递 ref out 而参数有可以分为值类型参数和引用类型参数 这里主要讲一讲引用类型参数的值 引用参
  • STM32F407IG单片机读写SD2405ALPI实时时钟程序(包括:读时钟时间、写时间到时钟、时间报警中断、倒计时中断)

    具体的IIC时序图和分析过程请参见下面网友的文章 https blog csdn net ybhuangfugui article details 52151835 本人在STM32F407单片机上亲测读时钟 写时钟 时间中断以及倒计时 秒
  • 简述RecyclerView的fling过程

    我们以RecyclerView为例 研究一下ListView是怎么滑动并且更新view的 首先可以肯定的是以Choreographer为基础实现的 一 fling过程研究 fling动作是由input事件触发的 1 1 RecyclerVi
  • 如何用Idea调试Maven插件

    调试端 maven插件源码端 被调试端 maven项目端 使用maven插件构建 和调试普通程序一样 只是调试命令有区别 过程原理如下 注 原理图片摘自https www cnblogs com turn2i p 11823884 html

随机推荐

  • vue实现一个展开和关闭的动画效果

    前言 用 vue animation 来实现一个展开与关闭的效果 效果图 组件逻辑 1 核心是通过改动他的宽度来实现展开 收缩的效果 2 点击展开 分两步 先用动画显示一个展开的效果 再用定时器来让他的效果保存在最后一帧 3 点击收缩 逻辑
  • 泽众TestOne自动化测试平台,挡板测试(Mock测试)上线了!!

    什么是挡板测试 Mock测试 主要应对与某些不容易构造或者不容易获取的对象以及暂时没有开发完成的对象 设计一个虚拟的对象 配置测试需求的业务数据 完成测试业务 TestOne是泽众软件自主研发的一体化测试系统 基于B S 体系结构 集自动化
  • Redis详解(二)——Redis基本操作

    今天继续给大家介绍Redis的相关知识 本文主要内容是Redis的基本操作 本文旨在为大家介绍Redis的基本操作 属于Redis入门级的介绍 如果想要进一步了解Redis的使用操作 推荐以下网站 https www runoob com
  • 魔改 vue-quill-editor字体及字号

  • Android Studio在vivo手机上调试apk出现解析包出错

    在Android studio开发过程中出现解析包时出现问题 用的是vivo y73 Android 8 1的手机 今年刚新出的手机 在开发的时候一直用着是6 0的系统 突然用到8 1的系统进行适配 发现各种报错 还有一个是手机处理器也是一
  • Android中Acition和Category常量表

    Action Action常量 对应字符串 简单说明 ACTION MAIN android intent action MAIN 应用程序入口 ACTION VIEW android intent action VIEW 显示指定数据 A
  • 基础算法:高精度加法

    高精度加法 代码模拟加法过程 1 lt 整数长度 lt 10 5 长整数的加法 int类型的最大值大概 2 1e9 10位长度 include
  • 【Anaconda】安装软件包时Solving environment卡住很长时间

    多数情况下的原因 安装该库需要考虑各软件包的兼容性 可能导致的无法安装的情况 可能解决方法 方法一 创建一个新的 python 环境 只安装代码中需要的库 conda create n name python version conda a
  • Matlab:筛选满足指定条件的数组元素

    Matlab 筛选满足指定条件的数组元素 在Matlab中 我们可以使用一些函数来筛选满足特定条件的数组元素 这些函数包括 find logical 和 indexing 等 下面以一个简单的实例来说明如何查找符合条件的数组元素 假设有一个
  • 判断应用或Activity是否存在

    一 判断应用是否存在 方法一 通过usb连接的方式 使用adb命令查看已安装的文件列表 adb shell pm list package 然后通过查看列表里是否含有对应的应用名来判断是否安装某应用 列表如下 adb shell pm li
  • Qt 数据类型转换 QString转Quint16

    如使用了QString存储用户输入的数据 数据类型 指的是quint16 qint16 float quint32 qint32等 可供用户自己选择的 而最终要使用的数据类型是quin16 下面是各种类型的转换 一 QString strV
  • Apache commons exec框架的简介说明

    转自 Apache commons exec框架的简介说明 下文笔者讲述Apache commons exec框架的简介说明 如下所示 Apache commmons exec框架的功能 Apache commons exec框架是对 Pr
  • Linux进程间通信——使用匿名管道

    本文介绍另一种进程间通信的方式 匿名管道 通过它进程间可以交换更多有用的数据 一 什么是管道 如果你使用过Linux的命令 那么对于管道这个名词你一定不会感觉到陌生 因为我们通常通过符号 来使用管道 但是管理的真正定义是什么呢 管道是一个进
  • SVG生成页面水印

    svg生成页面水印 灰信网 软件开发博客聚合
  • ElasticSearch基本操作

    文章目录 1 ElasticSearch 简介 2 索引库操作 2 1 mapping 属性 2 2 索引库CRUD 3 文档操作 3 1 新增文档 3 2查询文档 3 3删除文档 3 4修改文档 4 RestClient 4 1准备工作
  • C/C++静态变量static详解

    静态变量作用范围在一个文件内 程序开始时分配空间 结束时释放空间 默认初始化为0 使用时可以改变其值 静态变量或静态函数只有本文件内的代码才能访问它 它的名字在其它文件中不可见 用法1 函数内部声明的static变量 可作为对象间的一种通信
  • 数据挖掘 NO.1 数据挖掘入门

    1 机器学习 代价函数 m是样本数量 直到最后得到的值收敛或者样本使用完 1 定义代价函数 2 对每个参数求偏导数 3 使用梯度下降算法更新 数据集先开始进行划分 解决OVERFITTING 1 在测试集评估模型 2 Regelizatio
  • Hibernate之多对多级联查询、新增、删除

    以书籍与书籍类别为例 一本书可以有多种类型 一种类型也可以对应多本书 书籍和书籍类别的关系是多对多的关系 他们的关系是在中间表里面的 多对多通过一个表找到另一个表的数据的条件为 中间表 中间表对应本表的外键 中间表对应关联表的外键 注 多对
  • 使用picgo配置图床使用

    图床这种东西 做博客是必须要的 这里我记录目前我使用的几种图床 方便以后使用 以后有新的好用的 也会相应的更新 sm ms图床 免费的sm sm ms图床 好用 速度还可以 下面图片是sm图 可以感受一下速度 csdn图床 csdn这个社区
  • 【裸机开发】I2C 通信接口(二)—— I2C 寄存器解析

    目录 一 硬件原理图分析 二 IO 复用寄存器解析 三 I2C 寄存器解析 3 1 时钟配置 3 2 I2C1 IADR 设置从机地址 3 3 I2C1 IFDR 设置分频值 3 4 I2C1 I2CR I2C使能 中断控制 3 5 I2C