【车载开发系列】IIC总线协议时序图

news2024/11/19 2:17:24

【车载开发系列】IIC总线协议时序图

【车载开发系列】IIC总线协议时序图

  • 【车载开发系列】IIC总线协议时序图
    • 一、前言
    • 二、IIC硬件软件实现
      • 1)使用I2C控制器实现
      • 2)使用GPIO通过软件模拟实现
    • 三、I2C协议标准代码
      • 1)起始信号
      • 2)停止信号
      • 3)发送一个字节
      • 4)读取一个字节
      • 5)ACK应答
      • 6)NACK应答
      • 7)ACK应答信号
    • 二、向IIC总线写数据
    • 三、向IIC总线读数据
    • 四、总结

一、前言

  • IIC协议是一种具有自动寻址、高低速设备同步和仲裁等功能的高性能串行总线,它是一个真正的多主机总线,支持一对多(一主多从)、多对多传输(多主多从)。
  • 它是各种总线协议中使用信号线最少的,只需要两根线便可以实现功能。
  • 连在IIC总线上的每个器件都有一个唯一的地址识别。其中高四位A7-A4是从机器件的固定编址,出厂时就已给定;A3-A1是从机器件的引脚地址,通过接地接电源来形成地址。
术语描述
发送器发送数据到总线的器件
接收器从总线接收数据的器件
主机初始化总线的数据,传输并产生允许传输的时钟信号和起始终止发送的器件
从机被主机寻址的器件
多主机同时有多于一个主机尝试控制总线,但不破坏报文
仲裁是一个在有多个主机同时尝试控制总线,但只允许其中一个控制总线并使报文不被破坏
同步两个或多个器件同步时钟信号的过程

二、IIC硬件软件实现

  • I2C有两种实现方式:一种是GPIO软件模拟,另一种是直接使用I2C硬件
  • 时钟线完全由主机控制。而从机只有对SDA的(短暂)控制权。通常使用I2C通信,SCL和SDA线上都会接一个上拉电阻,要么是在外设的内部,要么是在外面可以直接通过外设的硬件接线图看到。
  • 硬件连接图如下
    在这里插入图片描述

1)使用I2C控制器实现

就是使用芯片上的I2C外设,也就是硬件I2C,它有相应的I2C驱动电路,有专用的IIC引脚,效率更高,写代码会相对简单,只要调用I2C的控制函数即可,不需要用代码去控制SCL、SDA的各种高低电平变化来实现I2C协议,只需要将I2C协议中的可变部分(如:从设备地址、传输数据等等)通过函数传参给控制器,控制器自动按照I2C协议实现传输,但是如果出现问题,就只能通过示波器看波形找问题。

2)使用GPIO通过软件模拟实现

软件模拟I2C比较重要,因为软件模拟的整个流程比较清晰,哪里出来bug,很快能找到问题,模拟一遍会对I2C通信协议更加熟悉。
如果芯片上没有IIC控制器,或者控制接口不够用了,通过使用任意IO口去模拟实现IIC通信协议,手动写代码去控制IO口的电平变化,模拟IIC协议的时序,实现IIC的信号和数据传输。

三、I2C协议标准代码

1)起始信号

起始信号:当 SCL 线是高电平时,SDA线从高电平向低电平切换。
在这里插入图片描述

void I2C_Start(void){
    // 总线空闲, SCL和SDA输出高
    I2C_SDA_High();     //SDA=1
    I2C_SCL_High();     //SCL=1
    I2C_Delay();
    I2C_SDA_Low();     // SDA由高变低
    I2C_Delay();
    I2C_SCL_Low();     // 拉低SCL开始传输数据
    I2C_Delay();       
}

2)停止信号

终止信号:SCL为高电平时,SDA由低向高跳变。
在这里插入图片描述

 void I2C_Stop(void){
    I2C_SDA_Low();     //SDA=0 把数据线设置为输出模式
    I2C_SCL_High();    // 拉高时钟线
    I2C_Delay();
    I2C_SDA_High();     // SDA由低变高
    I2C_Delay();
}

3)发送一个字节

CPU向I2C总线设备发送一个字节(8bit)数据

uint8 I2C_SendByte(uint8_t Byte){
    uint8_t i;
    /* 先发送高位字节 */
    for(i = 0 ; i < 8 ; i++){
        if(Byte & 0x80){
            I2C_SDA_High();
        }
        else{
            I2C_SDA_Low();
        }
        I2C_Delay();
        I2C_SCL_High();
        I2C_Delay();
        I2C_SCL_Low();
        I2C_Delay();
        if(i == 7){
            I2C_SDA_High();/* 释放SDA总线 */
        }
        Byte <<= 1;/* 左移一位 */
        I2C_Delay();
    }
} 

4)读取一个字节

CPU从I2C总线设备上读取一个字节(8bit数据)

uint8_t I2C_ReadByte(void)
{
    uint8_t i;
    uint8_t value;
 
    /* 先读取最高位即bit7 */
    value = 0;
    for(i = 0 ; i < 8 ; i++)
    {
        value <<= 1;
        I2C_SCL_High();
        I2C_Delay();
        if(I2C_SDA_READ())
        {
            value++;
        }
        I2C_SCL_Low();
        I2C_Delay();
    }
 
    return value;
}

5)ACK应答

CPU产生一个ACK信号
当SDA是低电平为有效应答(ACK),表示对方接收成功;

void I2C_Ack(void)
{
    I2C_SDA_Low();  //SDA=0 当SDA是低电平为有效应答(ACK),表示对方接收成功;
    I2C_Delay();
    I2C_SCL_High();
    I2C_Delay();
    I2C_SCL_Low(); // 拉低SCL开始传输数据
    I2C_Delay(); 
    I2C_SDA_High();  //SCL_Low之后,SDA=0->1
}

6)NACK应答

CPU产生一个非ACK信号
当SDA是高电平为无效应答(NACK),表示对方没有接收成功。

void I2C_NoAck(void)
{
    I2C_SDA_High();  //SDA=1 当SDA是高电平为无效应答(NACK),表示对方没有接收成功。
    I2C_Delay();
    I2C_SCL_High();
    I2C_Delay();
    I2C_SCL_Low();// 拉低SCL开始传输数据
    I2C_Delay();
}

7)ACK应答信号

CPU产生一个时钟,并读取器件的ACK应答信号
发送数据需要等待接收方的应答:

// 等待ACK   1-无效    0-有效
uint8_t I2C_WaitToAck(void)
{
    uint8_t redata;
 
    I2C_SDA_High();// 拉高数据线(设置为输入)
    I2C_Delay();
    I2C_SCL_High();// 拉高时钟线
    I2C_Delay();
 
    if(I2C_SDA_READ())
    {
        redata = 1; //ACK应答无效
    }
    else
    {
        redata = 0; //ACK应答有效
    }
    I2C_SCL_Low(); // 拉低SCL开始传输数据
    I2C_Delay();
 
    return redata;
} 

二、向IIC总线写数据

首先我们先来看一下写数据的时序图,如下图所示:
在这里插入图片描述
将上图中的写数据时序图进行分解,经分解后如下图所示:
在这里插入图片描述

  • 第一步,发送一个起始信号。
  • 第二步,发送7bit从机地址。此处需要注意,发送数据时,无法发送7bit数据,此处发送了7bit地址+1bit读写选择位,即发送7bit+r/w。最低位为1表示读,为0表示写,这里是写。
  • 第三步,产生一个ACK应答信号,此应答信号为从机器件产生的应答。
  • 第四步,发送寄存器地址,8bit数据。
  • 第五步,产生一个ACK应答信号,此应答信号为从机器件产生的应答。
  • 第六步,发送一个数据,8bit数据。
  • 第七步,产生一个ACK应答信号,此应答信号为从机器件产生的应答信号。
  • 第八步,发送一个CRC校验码,此CRC校验值为2、4、6步数据产生的校验码。
  • 第九步,既可以发送一个应答信号,也可以发送一个无应答信号,均有从机器件产生。
  • 第十步,发送一个停止信号。
    在这里插入图片描述
uint8_t I2C_WriteBytes(void)
{
    I2C_Start();                    //1
    I2C_SendByte(Slaver_Addr | 0);  //2
    I2C_WaitToAck();                //3
    I2C_SendByte(Reg_Addr);         //4
    I2C_WaitToAck();                //5
    I2C_SendByte(data);             //6
    I2C_WaitToAck();                //7
    I2C_SendByte(crc);              //8
    I2C_WaitToAck();                //9
    I2C_Stop();                     //10
}

三、向IIC总线读数据

读数据的时序图如下图所示:
在这里插入图片描述
读数据的时序图经分解后如下图所示:
在这里插入图片描述

  • 第一步,发送一个起始信号。
  • 第二步,发送7bit从机地址,此处需要注意,发送数据时,无法发送7bit数据,此处发送了7bit地址+1bit读写选择位,即发送7bit+r/w。最低位为1表示读,为0表示写。
  • 第三步,产生一个ACK应答信号,此应答信号为从机器件产生的应答。
  • 第四步,发送寄存器地址。
  • 第五步,产生一个ACK应答信号,此应答信号为从机器件产生的应答。
  • 第六步,再次发送一个起始信号。
  • 第七步,发送7bit从机地址。此处需要注意,发送数据时,无法发送7bit数据,此处发送了7bit地址+1bit读写选择位,即发送7bit+r/w。最低位为1表示读,为0表示写。
  • 第八步,产生一个ACK应答信号,此应答信号为从机器件产生的应答。
  • 第九步,读取一个字节(8bit)的数据。
  • 第十步,产生一个ACK应答信号,此应答信号为CPU产生。
  • 第十一步,读取一个CRC校验码。
  • 第十二步,产生一个NACK信号。此无应答信号由CPU产生。
  • 第十三步,产生一个停止信号。
    在这里插入图片描述
uint8_t I2C_ReadBytes(void)
{
    uint8_t data;
    uint8_t crc;
 
    I2C_Start();                    //1
    I2C_SendByte(Slaver_Addr | 0);  //2
    I2C_WaitToAck();                //3
    I2C_SendByte(Reg_Addr);         //4
    I2C_WaitToAck();                //5
    I2C_Start();                   //6
    I2C_SendByte(Slaver_Addr | 1);  //7 1-读
    I2C_WaitToAck();                //8
    data=I2C_ReadByte();            //9
    I2C_Ack();                      //10
    crc=I2C_ReadByte();             //11
    I2C_NoAck();                    //12
    I2C_Stop();                     //13
}

四、总结

  • 每次向SDA发送一位数据,都需要在SCL高电平时保持,所以SDA上所传输每一位数据都会占用一个时钟周期。

  • 主机接收到从机的应答信号之后,

    1. 如果第8位读写位是0,即主机向从机写数据,接下来继续由主机占用SDA,向从机传输数据,期间主机每传送8位数据,从机就会产生一个应答信号ACK,由主机接收。
    2. 如果第8位读写位是1 ,即从机向主机写数据,接下来继续由从机占用SDA,向主机传输数据,期间从机每传送8位数据,主机就会产生一个应答信号ACK,由从机接收。
  • 每传输8位数据,都会产生ACK信号,除了以下三种情况外;

    1. 从机不能响应主机发送的从机地址
      例如从机正忙而无法响应IIC总线的操作,或者这个地址没有对应的从机,那么在第9个SCL周期内SDA线就没有被拉低,即没有ACK信号。
      这时,由主机发送一个停止信号终止传输,或者重新发送一个START信号开始新的传输。
    2. 从机无法接收更多数据
      如果从机无法接收更多的数据,即主机发送的数据超过从机的数据接收能力时,从机不会发出ACK信号,这时,由主机发出一个停止信号终止传输或者重新发送一个START信号开始新的传输。
    3. 主机接收最后一个字节
      主机接收器接收到最后一个字节后,也不会发出ACK信号。于是从机发送器释放SDA线,以允许主机发出停止信号结束传输。

在这里插入图片描述

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

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

相关文章

判断对称二叉树/判断相同的数-二叉树

都利用递归&#xff0c;思路相似&#xff1b; 对称二叉树就是两个相同的二叉树&#xff0c;但是子节点是right left因为对称&#xff1b; 101. 对称二叉树 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:bool isSymmetric(TreeNode* root) {TreeNode* rt…

【C语言】解决C语言报错:Null Pointer Dereference

文章目录 简介什么是Null Pointer DereferenceNull Pointer Dereference的常见原因如何检测和调试Null Pointer Dereference解决Null Pointer Dereference的最佳实践详细实例解析示例1&#xff1a;未初始化的指针示例2&#xff1a;释放内存后未将指针置为NULL示例3&#xff1a;…

市值飙升!超微软、苹果,英伟达成为全球市值最高上市公司

KlipC报道&#xff1a;当地时间6月18日&#xff0c;英伟达股价再度大涨&#xff0c;盘后股价上涨3.51%&#xff0c;总市值达3.335万亿美元&#xff0c;报135.58美元再刷历史新高&#xff0c;超微软、苹果成为全球市值最高的上市公司。 值得一提的是&#xff0c;在本月初&#x…

hackbar插件安装教程

目录 HackBar 插件简介 下载 Firefox浏览器&#xff08;火狐&#xff09;安装 2.1.3版本 2.5.3版本 使用 chrome浏览器&#xff08;谷歌&#xff09;安装 方法1&#xff1a;开发者模式拖安装包 激活方式&#xff1a; 方法2&#xff1a;从 Chrome 应用商店 HackBar 插件…

【推荐100个unity插件之22】基于UGUI的功能强大的简单易用的Unity数据可视化图表插件——XCharts3.0插件的使用

效果 文章目录 效果前言特性截图基础介绍插件信息5分钟上手 XCharts 3.0实例创建一个默认的折线图代码修改显示的值 推荐完结 前言 unity怎么绘制图表&#xff1f;这是最近最常听到的问题。这次就介绍一款基于UGUI的功能强大的简单易用的Unity数据可视化图表插件——XCharts3.…

LuxTrust、契约锁联合启动中欧两地跨境电子签服务

6月18日&#xff0c;欧洲领先的数字身份和电子签名厂商-LuxTrust、全球领先的数字化技术和服务的提供商-浩鲸科技一行莅临契约锁上海总部&#xff0c;并于当日下午联合举行“跨境签战略合作”现场签约仪式。 三方将以此次合作为契机&#xff0c;发挥各自领域专业优势&#xff…

在同一个 Blazor 应用中结合 SQL-DB 和 MongoDB

介绍 传统上&#xff0c;在单应用程序中&#xff0c;我们对整个应用程序使用单个数据库服务器。但是&#xff0c;我将 SQL 数据库和 MongoDB 结合在同一个应用程序中。此应用程序将是 RDBMS 和 No SQL 数据库的组合。我们将从头开始创建一个 Blazor 应用程序&#xff0c;并使用…

微信小程序开发模式--第三方代开发

研发小程序功能&#xff0c;还是必须要学习了一下小程序开发文档的谋篇布局&#xff0c;这样能快速定位且解决自己业务问题。 如何布局&#xff1f; 1、指南微信开放文档 2、框架微信开放文档 3、组件视图容器 | 微信开放文档 4、API基础 | 微信开放文档 5、平台能力平台…

LeetCode - 415 字符串相加(Java JS Python C C++)

题目来源 415. 字符串相加 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给定两个字符串形式的非负整数 num1 和 num2 &#xff0c;计算它们的和并同样以字符串形式返回。 你不能使用任何內建的用于处理大整数的库&#xff08;比如 BigInteger&#xff09;&#xff0c;…

刷代码随想录有感(108):动态规划——目标和

题干&#xff1a; 代码&#xff1a; class Solution { public:int findTargetSumWays(vector<int>& nums, int target) {int sum 0;for(int i : nums) sum i;if(abs(target) > sum)return 0;if((sum target) % 2 ! 0)return 0;int bagweight (sum target) /…

高考志愿填报选专业,你是听父母还是自己选?

在就业环境如此激烈的今天&#xff0c;就读好的专业意味着在竞争中占据一定的优势&#xff0c;而在拿到高考分数后&#xff0c;如何进行专业选择让不少人伤透了脑筋。很多学生愿意遵从自身意愿&#xff0c;就读自己喜欢的专业&#xff0c;但是当他提出想要就读哪个专业的想法后…

Python爬虫小白入门(二)BeautifulSoup库

一、前言 上一篇演示了如何使用requests模块向网站发送http请求&#xff0c;获取到网页的HTML数据。这篇来演示如何使用BeautifulSoup模块来从HTML文本中提取我们想要的数据。 二、运行环境 我的运行环境如下&#xff1a; 系统版本 Windows10。 Python版本 Python3.5&#xf…

为什么人们对即将推出的 Go 1.23 迭代器感到愤怒

原文&#xff1a;gingerBill - 2024.06.17 TL;DR 它让 Go 变得太“函数式”&#xff0c;而不再是不折不扣的命令式语言。 最近&#xff0c;我在 Twitter 上看到一篇帖子&#xff0c;展示了 Go 1.23&#xff08;2024 年 8 月&#xff09;即将推出的 Go 迭代器设计。据我所知&a…

「动态规划」如何求乘积为正数的最长子数组长度?

1567. 乘积为正数的最长子数组长度https://leetcode.cn/problems/maximum-length-of-subarray-with-positive-product/description/ 给你一个整数数组nums&#xff0c;请你求出乘积为正数的最长子数组的长度。一个数组的子数组是由原数组中零个或者更多个连续数字组成的数组。…

2024年GIS专业就业现状和解决办法

GIS专业发展历史 我国从20世纪80年代初引进和研究地理信息系统(GIS) 以来&#xff0c;经过30年的飞速发展&#xff0c;地理信息已成为信息时代重要的组成部分之一&#xff0c;被广泛应用于多个领域的建模和决策支持。 在国家数字化政策的加持下&#xff0c;GIS更成为新基建下…

敏感信息加密操作,让开发的系统更加的安全可靠!!

敏感信息加密操作&#xff0c;让开发的系统更加的安全可靠&#xff01;&#xff01;Jasypt&#xff08;Java Simplified Encryption&#xff09;是一个开源的Java库&#xff0c;用于简化加密操作。https://mp.weixin.qq.com/s/sPBV8Ej46YJsElImodRjAQ

反射的原理和操作

反射是框架设计的灵魂 &#xff08;使用的前提条件&#xff1a;必须先得到代表的字节码的Class&#xff0c;Class类用于表示.class文件&#xff08;字节码&#xff09;&#xff09; 在Java中&#xff0c;反射是指在运行时动态地获取、检查和操作类、对象、方法和属性的能力。J…

第2章 Rust初体验3/8:使用Result进行错误处理:编译时错误检查增强代码安全性:猜骰子冷热游戏

讲动人的故事,写懂人的代码 2.3.9 类型的关联函数:简化对象创建和初始化 席双嘉:“那个String::new(),毫无疑问,它确实像C++中的静态成员函数。” 贾克强:“哈哈!是的,两个冒号确实让人联想到一些东西,对吧?” “这其实是Rust中的关联函数(associated function,详…

第四集《唯识与净土》

请大家打开讲义第十面。 我们讲到念佛的功德有两个&#xff1a;第一个是“现世的安乐”&#xff0c;第二个是“来世究竟的解脱”。 这个净土法门的特色&#xff0c;是一种本尊相应法。 也就是说&#xff0c;我们在整个修行破恶生善的过程当中&#xff0c;主要是要仰仗本尊的…

设计师必看|精选免费icon生成网站推荐

在平面设计过程中&#xff0c;如何收集icon素材&#xff1f;(opens in a new tab or window)&#xff1f; 在这里我们为您准备了三个免费、易用的icon生成网站&#xff0c;需要icon材料的同学&#xff0c;记得点赞收藏。 01∣即时设计 作为国内领先的在线设计平台&#xff0…