IIC协议超详细解释(适合小白入门)

IIC协议超详细解释(适合小白入门)以下内容 将解释以下几个问题 1 IIC 协议是什么 2 IIC 协议用来干什么 3 IIC 协议的通信过程 1 IIC 协议是什么 IIC 即 I C 全称 Inter IntegratedCi 字面上的意思是集成电路之间 它其实是 I CBus 简称 所以中文应

3 .IIC协议的通信过程( 此处重点

既然IIC是双向通信的,那主机肯定也是需要从外设读取数据的,那这个读取的过程又是怎么实现的呢?毕竟外设对于我们而言是不能直接操作的,我们能操作的只有stm32。我们知道,一个IIC总线上,可以挂载多个设备,那么stm32如何确定是哪个外设正在跟我进行通信呢。对于此,那些生产外设模块的厂商们就约定,要是这个设备使用IIC协议进行通信,那么就要给这个设备指定一个器件地址,以供芯片访问。这个器件地址会在你购买其模块的时候在使用手册上注明。所以,要跟哪个模块通信,就一定要通过查阅其使用手册,找到它的器件地址。
所以,在上文所述的最开始的一个字节的数据传输过程中,这一个数据往往是器件地址。这样,对应的外设才知道,是要跟我进行通信。读取数据,也是同理,要想从外设中读取到数据,主机要明确三点:从哪个外设中的哪个地方读取数据,读取到的数据要存到哪里。
所以主机,在开始读数据之前,主机必须要先给外设发器件地址,数据所在的地址,外设才会知道你要从该地址读取数据,从而把数据通过SDA线传出来。至于具体的每个字节的传输过程,和上面所讲的从主机到外设的过程差不多,只不过反了一个反向而已,并且主机的等待应答变成了主动应答。




以下是IIC协议代码

 /* 设置SDA总线为输出模式 参数值:NULL 返回值:NULL */ void IIC_setSDAMode_Out() { 
    GPIO_InitTypeDef GPIO_IIC; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); GPIO_IIC.GPIO_Mode = GPIO_Mode_OUT; //输出 GPIO_IIC.GPIO_OType = GPIO_OType_PP; //推挽 GPIO_IIC.GPIO_Pin = GPIO_Pin_15; //引脚 GPIO_IIC.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_IIC.GPIO_Speed = GPIO_Speed_25MHz; //输出 GPIO_Init(GPIOE, &GPIO_IIC); } /* 设置SDA总线为输入模式 参数值:NULL 返回值:NULL */ void IIC_setSDAMode_In() { 
    GPIO_InitTypeDef GPIO_IIC; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); GPIO_IIC.GPIO_Mode = GPIO_Mode_IN; //输出 GPIO_IIC.GPIO_Pin = GPIO_Pin_15; //引脚 GPIO_IIC.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(GPIOE, &GPIO_IIC); } /* IIC开始信号 参数值:NULL 返回值:NULL */ void IIC_Start() { 
    IIC_setSDAMode_Out(); IIC_SDA_OUT(1); //总线释放状态 IIC_SCL_OUT(1); delay_us(5); IIC_SDA_OUT(0); //SDA跳变为低电平 delay_us(5); IIC_SCL_OUT(0); delay_us(5); } /* IIC停止信号 参数值:NULL 返回值:NULL */ void IIC_Stop() { 
    IIC_setSDAMode_Out(); IIC_SDA_OUT(0); IIC_SCL_OUT(0); delay_us(5); IIC_SCL_OUT(1); //SDA跳变为高电平 delay_us(5); IIC_SDA_OUT(1); delay_us(5); } /* 主机写入数据到外设中 参数值: data 要写入的一个字节 返回值:NULL */ void IIC_writeByte(u8 data) { 
    IIC_setSDAMode_Out(); IIC_SCL_OUT(0); //只有时钟线拉低,SDA上的数据才允许写入 delay_us(5); //将数据一位一位的发出去 for(int i =0;i<8;i++) { 
    if(data&(0x1<<(7-i))) //高位先入 { 
    IIC_SDA_OUT(1); } else { 
    IIC_SDA_OUT(0); } IIC_SCL_OUT(1); //让外设读取数据 delay_us(5); IIC_SCL_OUT(0); //重新拉低,准备写入下一位数据 delay_us(5); } } /* 主机从外设中读取一个字节的数据 参数值:NULL 返回值:NULL */ u8 IIC_readByte() { 
    u8 data = 0; IIC_setSDAMode_In(); IIC_SCL_OUT(0); //先拉低,为读取数据做准备 delay_us(5); for(int i=0;i<8;i++) { 
    IIC_SCL_OUT(1); // SCL为高期间才可以读取数据 delay_us(5); if(IIC_SDA_IN) { 
    data|=(0x01<<(7-i)); }else{ 
    data &= ~(0x1<<(7-i)); } IIC_SCL_OUT(0); delay_us(5); } return data; } /* 主机等待应答 参数值:NULL 返回值:ack 0 应答 1 不应答 */ u8 IIC_waitAck() { 
    u8 ack =0; IIC_setSDAMode_In(); IIC_SCL_OUT(0); //准备时序 delay_us(5); IIC_SCL_OUT(1); delay_us(5); if(IIC_SDA_IN) { 
    ack =1; } else { 
    ack =0; } IIC_SCL_OUT(0); //拉低,表示应答完成 delay_us(5); return ack; } /* 主机主动应答 参数值: ack 0 应答 1 不应答 返回值:NULL */ void IIC_Ack(u8 ack) { 
    IIC_setSDAMode_Out(); IIC_SCL_OUT(0); delay_us(5); if(ack) { 
    IIC_SDA_OUT(1); } else { 
    IIC_SCL_OUT(0); } IIC_SCL_OUT(1); delay_us(5); IIC_SCL_OUT(0); delay_us(5); } 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/201298.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月20日 上午9:39
下一篇 2026年3月20日 上午9:39


相关推荐

  • php 中js跳转页面跳转页面,js跳转代码_PHP页面跳转 Js页面跳转代码[通俗易懂]

    php 中js跳转页面跳转页面,js跳转代码_PHP页面跳转 Js页面跳转代码[通俗易懂]摘要腾兴网为您分享:PHP页面跳转Js页面跳转代码,自动刷宝,中信金通,携程抢票,未来屋等软件知识,以及沃金汇,沃行讯通,securecrt.exe,我的世界变形金刚mod,一票通,农场小分队,手电筒,推币机游戏,善行天下,硬盘mhdd,googlekeep,文件批量更名,明星表情包,服装销售软件,进击的巨人日语等软件it资讯,欢迎关注腾兴网。第一部分:JavaScript跳转方法一:…

    2022年8月13日
    5
  • 无偏估计(Unbiased Estimator)「建议收藏」

    无偏估计(Unbiased Estimator)「建议收藏」无偏估计是参数的样本估计量的期望值等于参数的真实值。一个简单的例子(https://www.zhihu.com/question/22983179/answer/23470969):比如我要对某个

    2022年8月2日
    8
  • Java分布式锁

    Java分布式锁Java分布式锁我的理解应该叫集群锁或者跨实例锁锁的作用是在多线程情况下,控制线程同步访问变量,执行代码块、方法,例如synchronized,在单个jvm进程中,这样是奏效的。但是在分布式环境中,单个服务往往都是要部署多台实例的,在有多个jvm进程的集群里,synchronized就达不到我们的要求了。synchronized只能控制当前jvm进程中的线程,对于其它jvm进程中的线程,它无能为力。也就是说有可能一个jvm中的线程是同步执行的,在此过程中,或许会有集群里其它jvm的线程执行到

    2022年6月10日
    48
  • SpringBoot项目打成war和jar的区别「建议收藏」

    SpringBoot项目打成war和jar的区别「建议收藏」首先给大家来讲一个我们遇到的一个奇怪的问题:1.我的一个springboot项目,用mvninstall打包成jar,换一台有jdk的机器就直接可以用java-jar项目名.jar的方式运行,没任何问题,为什么这里不需要tomcat也可以运行了?2.然后我打包成war放进tomcat运行,发现端口号变成tomcat默认的8080(我在server.port中设置端口8090)项目名称也…

    2022年5月10日
    59
  • 配置ssh免密码登录

    配置ssh免密码登录SSH SecureShell 是建立在 TCP TP 协议的应用层和传输层基础上的安全协议 SSH 保障了远程登录和网络传输服务的安全性 起到了防止信息泄露等作用 通过 SSH 可以对文件进行加密处理 SSH 也可以运行于多平台 一 配置 SSH 无密码登录的步骤如下 以下步骤都是在主节点 master 上操作的 1 使用 ssh keygen 产生公钥与私钥对 输入命令 ssh keygen trsa 接着按三次 Enter 键 生成私有密钥 id rsa 和公有密钥 idrsa pub 两个文件 ss

    2026年3月18日
    2
  • 机器学习之KNN(k近邻)算法详解

    机器学习之KNN(k近邻)算法详解1-1机器学习算法分类一、基本分类:①监督学习(Supervisedlearning)数据集中的每个样本有相应的“正确答案”,根据这些样本做出预测,分有两类:回归问题和分类问题。步骤1:数据集的创建和分类步骤2:训练步骤3:验证步骤4:使用(1)回归问题举例例如:预测房价,根据样本集拟合出一条连续曲线。(2)…

    2022年5月28日
    42

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号