IIC总线

2023-05-16

1.概念

        IIC总线是PHLIPS公司在八十年代初推出的一种串行的半双工同步总线,主要用于连接整体电路。

        同一块板子两个芯片之间的通信是通过IIC总线进行的(stm32mp157a <-----IIC----->SI7006

        IIC总线为两线制,只有双跟双向信号线,一根是数据线SDA,另一根是时钟线SCL。

        IIC硬件结构简单,接口连接方便,成本较低,因此在各个领域得到了广泛的应用。

        IIC总线传输速率 ,低速:100k,中速:400k,全速:3.4M。

        IIC总线需要接两个上拉电阻,这两个上拉电阻作用在IIC总线为空闲状态时保持高电平。

        

 2.IIC总线硬件连接

         IIC总线支持多主机多从机模式,同一时刻,只能有一个主机和一个从机进行通信。

        在实际开发中,大多数使用单片机多从机模式进行通信。

        挂接到每一个IIC总线上所有的设备,每一个从机都有自己唯一的七位从机地址。

        在总线上,发送数据的叫做发送器,接收数据的叫做接收器

        主动发起数据通信的叫做主机,只能被动接收数据的叫做从机。

        时钟信号是由主机产生的,作用给从机,,保证总线上传输数据同步。

3.IIC硬件电路图

 

 4.IIC时序

        a.起始信号

        

         备注:起始信号和终止信号都是由主机产生的,起始信号产生之后,总线处于占用状态, 终止信号产生之后,总线处于空闲状态 起始信号:在SCL为高电平期间,SDA(数据线)从高电平到低电平的变化(下降沿)

        b.停止信号

        停止信号:在SCL为高电平期间,SDA(数据线)从低电平到高电平的变化(上升沿)

        c.数据传输

        

         1>IIC总线传输时,时钟信号在高电平期间,数据线上的数据必须保持稳定(接收器可以从总线上读取数据), 2>时钟信号在低电平期间,数据线上的数据允许发生变化(发送器可以向数据线上写数据)

        d.应答信号和非应答信号

        

         1.每一个字节必须保证是8位的长度,数据传送时,先发送高位,在发送低位,一帧数据=8位数据位+1位应答位=9位 2.发送器在发送完8位的数据位之后,接收器必须在第9个时钟周期,返回一个应答信号(0),或者非应答信号(1) 在第9个时钟低电平期间,接收器向数据线上写入数据 在第9个时钟高电平期间,发送器从数据线上读取数据 如果读到的是高电平,代表是非应答信号 如果读到的是低电平,代表是应答信号

        e.寻址

        

         1.IIC总线上传输数据是广义的,既可以是地址信号,也可以是数据信号 2.主机在起始信号产生之后,必须要传送一个7位的从机地址,第8位是数据传输的方向位 3.用0表示主机发送数据(写),用1表示主机接收数据(读)

5.框图

         

6.IIC协议

        a.主机给从机发送一个字节

        

        b.主句给从机发送多个连续字节

         

        c.从机给主机发送一个字节

         

        d.从机给主机发送多个连续字节

         

7.GPIO模拟IIC协议

         

8. 分析si7006

        通过框图可知,分析si7006芯片手册需要做以下几个步骤: 1.si7006从机地址 2.找到采集温度湿度命令码 3.初始化si7006芯片,初始化的值,写到哪一个寄存器中 4.读取温湿度芯片IIC协议 5.采集温湿度数字量转换为模拟量公式

        a.从机地址

        

         从机地址 + 写 : 0x40 << 1 | 0, 从机地址 + 读 : 0x40 << 1 | 1

        b.温度湿度命令码

        

         c.温度湿度转换公式

        

         d.si7006寄存器初始化

        ​​​​​​​ 

代码

IIC.c文件

#include "iic.h"

extern void printf(const char* fmt, ...);
/*
 * 函数名 : delay_us
 * 函数功能:延时函数
 * 函数参数:无
 * 函数返回值:无
 * */
void delay_us(void)
{
unsigned int i = 2000;
while(i--);
}
/*
 * 函数名 : i2c_init
 * 函数功能: i2C总线引脚的初始化, 通用输出,推挽输出,输出速度,
 * 函数参数:无
 * 函数返回值:无
 * */
void i2c_init(void)
{
 // 使能GPIOF端口的时钟
RCC->MP_AHB4ENSETR |= (0x1 << 5);
// 设置PF14,PF15引脚为通用的输出功能
GPIOF->MODER &= (~(0xF << 28));
GPIOF->MODER |= (0x5 << 28);
// 设置PF14, PF15引脚为推挽输出
GPIOF->OTYPER &= (~(0x3 << 14));
// 设置PF14, PF15引脚为高速输出
GPIOF->OSPEEDR |= (0xF << 28);
// 设置PF14, PF15引脚的禁止上拉和下拉
GPIOF->PUPDR &= (~(0xF << 28));
// 空闲状态SDA和SCL拉高 
I2C_SCL_H;
I2C_SDA_H;
}

/*
 * 函数名:i2c_start
 * 函数功能:模拟i2c开始信号的时序
 * 函数参数:无
 * 函数返回值:无
 * */
void i2c_start(void)
{
/*
 * 开始信号:时钟在高电平期间,数据线从高到低的变化
 *     --------
 * SCL         \
 *              --------
 *     ----
 * SDA     \
 *          --------
 * */
//1.设置数据线为输出模式
SET_SDA_OUT;
//2.时钟线拉高
I2C_SCL_H;
//3.数据线拉高
I2C_SDA_H;
//4.延时函数
delay_us();
//5.数据线拉低
I2C_SDA_L;
delay_us();
I2C_SCL_L; //保持总线处于占用状态
}

/*
 * 函数名:i2c_stop
 * 函数功能:模拟i2c停止信号的时序
 * 函数参数:无
 * 函数返回值:无
 * */

void i2c_stop(void)
{
/*
 * 停止信号 : 时钟在高电平期间,数据线从低到高的变化 
 *             ----------
 * SCL        /
 *    --------
 *    ---         -------
 * SDA   X       /
 *    --- -------
 * */
SET_SDA_OUT; //确保SDA为输出模式
I2C_SCL_L;
delay_us();
I2C_SDA_L; //数据线拉低
delay_us();

I2C_SCL_H;
delay_us();
I2C_SDA_H;
delay_us();
}

/*
 * 函数名: i2c_write_byte
 * 函数功能:主机向i2c总线上的从设备写8bits数据
 * 函数参数:dat : 等待发送的字节数据
 * 函数返回值: 无
 * */

void i2c_write_byte(unsigned char dat)
{
/*
 * 数据信号:时钟在低电平期间,发送器向数据线上写入数据
 * 时钟在高电平期间,接收器从数据线上读取数据 
 *      ----          --------
 * SCL     \        /        \
 *           --------          --------
 *      -------- ------------------ ---
 * SDA         X                  X
 *      -------- ------------------ ---
 *
 *      先发送高位在发送低位 
 * */
unsigned int i;
SET_SDA_OUT;  //设置数据线为输出模式
for(i=0;i<8;i++)
{
I2C_SCL_L; //时钟线拉低,可以向数据线上写数据
delay_us();
if(dat & 0x80) //写高位
{
I2C_SDA_H; //向数据线上写高电平
}
else
{
I2C_SDA_L; //向数据线上写低电平
}
delay_us();
I2C_SCL_H;  //时钟线拉高
delay_us();
delay_us();
dat <<= 1; //移位
}
}

/*
 * 函数名:i2c_read_byte
 * 函数功能: 主机从i2c总线上的从设备读8bits数据, 
 *          主机发送一个应答或者非应答信号
 * 函数参数: 0 : 应答信号   1 : 非应答信号
 * 函数返回值:读到的有效数据
 *
 * */
unsigned char i2c_read_byte(unsigned char ack)
{
/*
 * 数据信号:时钟在低电平期间,发送器向数据线上写入数据
 * 时钟在高电平期间,接收器从数据线上读取数据 
 *      ----          --------
 * SCL     \        /        \
 *           --------          --------
 *      -------- ------------------ ---
 * SDA         X                  X
 *      -------- ------------------ ---
 *
 *      先接收高位, 在接收低位 
 * */
unsigned int i;
unsigned char dat; //返回读到的数据
SET_SDA_IN; //确保总线输入模式
for(i=0;i<8;i++)
{
I2C_SCL_L; //时钟线拉低
delay_us();
delay_us();//保证数据写完整

I2C_SCL_H; //时钟线拉高
delay_us();
dat <<= 1;
if(I2C_SDA_READ) //读取数据
{
dat |= 1;
}
else
{
dat |= 0;
}
delay_us();
}
if(!ack)
i2c_ack(); 
else
i2c_nack();
return dat;
}

/*
 * 函数名: i2c_wait_ack
 * 函数功能: 主机作为发送器时,等待接收器返回的应答信号
 * 函数参数:无
 * 函数返回值:
 *0:接收到的应答信号
 *                  1:接收到的非应答信号
 * */
unsigned char i2c_wait_ack(void)
{ 
/*
 * 主机发送一个字节之后,从机给主机返回一个应答信号
 *
 *                   -----------
 * SCL              /   M:读    \
 *     -------------             --------
 *     --- ---- --------------------
 * SDA    X    X
 *     ---      --------------------
 *     主  释   从机    主机
 *     机  放   向数据  读数据线
 *         总   线写    上的数据
 *         线   数据
 * */
I2C_SCL_L;
I2C_SDA_H; //释放总线
delay_us();
SET_SDA_IN; //变换总线方向

I2C_SCL_H;
delay_us();
if(I2C_SDA_READ)
return 1; //非应答信号
I2C_SCL_L;
return 0; //应答信号
} 
/*
 * 函数名: iic_ack
 * 函数功能: 主机作为接收器时,给发送器发送应答信号
 * 函数参数:无
 * 函数返回值:无
 * */
void i2c_ack(void)
{
/*            --------
 * SCL       /        \
 *    -------          ------
 *    ---
 * SDA   X 
 *    --- -------------
 * */
SET_SDA_OUT; //确保总线输出模式
I2C_SCL_L; //时钟线拉低
delay_us();
I2C_SDA_L; //数据线拉低 应答信号
delay_us();
I2C_SCL_H; //时钟线拉高 读取数据
delay_us();
delay_us();
I2C_SCL_L; //时钟线拉低,总线处于占用状态
}
/*
 * 函数名: iic_nack
 * 函数功能: 主机作为接收器时,给发送器发送非应答信号
 * 函数参数:无
 * 函数返回值:无
 * */
void i2c_nack(void)
{
/*            --------
 * SCL       /        \
 *    -------          ------
 *    --- ---------------
 * SDA   X 
 *    --- 
 * */
SET_SDA_OUT; //确保总线输出模式
I2C_SCL_L; //时钟线拉低
delay_us();
I2C_SDA_H; //数据线拉高 非应答信号
delay_us();
I2C_SCL_H; //时钟线拉高 读取数据
delay_us();
delay_us();
I2C_SCL_L; //时钟线拉低,总线处于占用状态
}

main.c文件

#include "iic.h"
#include "si7006.h"

extern void printf(const char *fmt, ...);
void delay_ms(int ms)
{
int i,j;
for(i = 0; i < ms;i++)
for (j = 0; j < 1800; j++);
}


int main()
{
unsigned short hum;
unsigned short temp;
si7006_init();
while(1)
{
hum = si7006_read_data(SI7006_SLAVE,0xE5);
temp = si7006_read_data(SI7006_SLAVE,0xE3);
printf("hum = %d\n",125*hum/65536-6);
printf("temp = %d\n",175*temp/65536-46);

}
return 0;
}

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

IIC总线 的相关文章

  • 对IIC总线时序的一点理解以及ACK和NACK(NAK)

    参考自 xff1a http blog chinaunix net uid 16100003 id 3059814 html 关于IIC的响应问题 xff1a 对于每一个接收设备 xff08 从设备 xff0c slaver xff09 x
  • IIC总线的时钟同步和总线仲裁

    IIC简介 xff1a IIC 即Inter Integrated Circuit 集成电路总线 xff09 xff0c 这种总线类型是由飞利浦半导体公司在八十年代初设计出来的 xff0c 主要是用来连接整体电路 ICS xff0c IIC
  • 试想面试官让你讲讲UART IIC SPI你能讲多少。

    试想面试官让你讲讲UART IIC SPI你能讲多少
  • IIC通讯详解笔记

    IIC概述 IIC总线是一种串行半双工两线总线 一根是双向的数据线SDA xff0c 另一根是时钟线SCL 所有接到IIC总线设备上的串行数据SDA都接到总线的SDA上 xff0c 各设备的时钟线SCL接到总线的SCL上 硬件拓扑如下图所示
  • IIC总线

    1 概念 IIC总线是PHLIPS公司在八十年代初推出的一种串行的半双工同步总线 xff0c 主要用于连接整体电路 同一块板子两个芯片之间的通信是通过IIC总线进行的 xff08 stm32mp157a lt IIC gt SI7006 I
  • IIC上拉电阻的选择

    上周项目评审的时候 xff0c 评审部门问了我一个问题 xff1a 为什么单片机内部有上拉电阻 xff0c 你们还要用外部的上拉电阻 xff1f 我的答复如下 xff1a 上拉电阻的选取要考虑上限值和下限值这两点 xff1a 上限值的最大限
  • iic片选PCA9548A芯片

    PCA9548A数据表 产品信息和支持 TI com iic片选深入 从上图中我们可以看到通过iic的iic 例如 iic0 扩展出8路iic来访问slave 例如8个口的光模块 那么里面的原理是什么呢 我们先来看PCA9548A 文档 需
  • IIC总线基础知识

    IIC总线基础知识 一 简介 IIC xff08 Inter Integrated Circuit xff09 是一个多主从的串行总线 xff0c 又叫I2C xff0c 是由飞利浦公司发明的通讯总线 xff0c 属于半双工同步传输类型总线
  • IIC的地址

    7位寻址 在7位寻址过程中 xff0c 从机地址在启动信号后的第一个字节开始传输 xff0c 该字节的前7位为从机地址 xff0c 第8位为读写位 xff0c 其中0表示写 xff0c 1表示读 图1 xff1a 7位寻址 I2C总线规范规
  • Arduino--LCD1602(IIC)

    xff08 1 xff09 简介 前篇文章介绍了LCD1602的四位数据线控制方法 xff1a https blog csdn net u011816009 article details 106573622 但是该方法还是需要较多的IO口
  • DHT12温湿度传感器IIC,I2C接口调试心得和代码说明

    来源 xff1a http www fuhome net bbs forum php mod 61 viewthread amp tid 61 2141 DHT11那个单总线的温湿度传感器用的很多了 xff0c aosong推出了DHT12
  • SYD8821 IIC模块使用说明

    SYD8821是具有全球领先低功耗 RX 2 4mA 64 94 5dBm灵敏度 xff0c TX 4 3mA 64 0dBm输出功率 的蓝牙低功耗SOC芯片 xff0c 在极低电流下实现了优异的射频性能 xff0c 搭配176kB SRA
  • IIC 驱动OLED

    IIC总线可以驱动很多器件 xff0c 比较常见的有OLED EEPROM存储器 xff08 AT24C02 xff09 温度传感器 xff08 LM75A xff09 温湿度传感器 xff08 DHT11 xff09 等 有关IIC总线协
  • STM32 IIC详解

    目录 1 IIC定义 2 IIC协议规范 2 1 SDA和SCL信号 2 2 数据有效性 2 3 开始和结束信号 2 4 字节格式 2 5 从机地址和读写位 3 计算IIC的频率 4 PCF8536 4 1 Acknowledge 4 2
  • UART, IIC, SCI, SPI, 232, 485, 422, CAN, SDIO, GPIO, MODBUS, TCP/IP汇总简介

    UART IIC SCI SPI 232 485 422 CAN SDIO GPIO MODBUS TCP IP汇总简介 UART xff1a Universal Asynchronous Receiver Transmitter xff1
  • UART,SPI,IIC,RS232通信时序和规则

    一 UART 1 串口通信方式 2 串口通信步骤 注意 xff1a 串口协议规定 xff0c 闲置时必须是高电平 校验位 xff1a 是使用奇偶校验 停止位必须高电平 一个0和多个0区分是靠掐时间 异步通信 xff1a 时钟各不一样 二 I
  • 12.RTT-IIC设备-AHT10温湿度传感器

    本系列博客更新结束啦 xff01 完结啦 xff01 xff01 xff01 撒花 xff01 xff01 xff01 关于RTT的设备和驱动专题更新完毕啦 xff0c 本期是最后一期 一段学习旅途的结束意味着下一段学习冒险的开始 虽然本系
  • AT24C02的使用说明和完整代码-51单片机

    AT24C02的使用说明和完整代码 51单片机 简述 at24c02为存储器芯片 可以使用单片机将数据存入其中 同时也可以任意读取 at24c02的原理及使用方法在其说明资料中已有充分的讲述 本篇仅对其使用的关键步骤进行罗列 以及说明一下具
  • I2C走线技巧、及上拉电阻、电源电压、总线电容三者间的函数关系

    目录 I2C总线PCB布线注意事项 博客其他文档可以学习 https www cnblogs com zhiqiang zhang I2C总线线路的走线方式 I2C器件与I2C总线的接线方式 I2C总线连接规范 I2C总线中上拉电阻 电源电
  • 基于STM32 的IIC 模拟主机编写

    最近在学习STM32 的IIC IO 模拟主机方式 好像失败了 include myiic h include delay h MCU VERSION DATA 作者 other Function IIC

随机推荐

  • ERROR:Session/line number was not unique in database. History logging moved to new session.

    摘要 xff1a 遇到此类错误 xff0c 可以通过分段调试的方法找到引发错误的位置 引发错误的原因不详 xff0c 可能很基础 Distribution of the peak number file 61 pd read excel 3
  • ubuntu xfce4和vncserver

    安装xfce4 sudo apt get install xfce4 如果你想创建一个新的用户 xff0c 而不是将桌面使用root权限登录 xff0c 可以执行下面的代码 xff1a 安装vncserver sudo apt instal
  • harmonyOS hdc配置以及自动签名

    hdc是sdk tools中自带的命令 xff0c 你没有配置系统环境变量指定它所在的目录 xff0c 肯定不能直接到处任意调用啊 xff0c 你需要进入到hdc exe所在路径的当前路径下才能去调用它 xff0c 或者你把它的路径加入到系
  • Vue脚手架(Vue-cli)安装

    脚手架是Vue官方提供的标准化开发工具 开发平台 官方文档开始 vue cli cli c command l line 行 interface 命令行接口工具 第一步 仅第一次执行 全局安装 64 vue cli npm install
  • 使用vscode开发配置uni-app(小程序)

    这个文件是用VsCode写uniapp小程序的步骤笔记 安装Vue脚手架 vue cli npm install g 64 vue cli 通过脚手架创建uni app项目 vue create p dcloudio uni preset
  • uniapp image组件的基本使用

    image组件的基本使用 就是用来显示图片的 src 来设置我们图像的路径 属性名类型默认值说明平台差异说明srcString图片资源地址 lt template gt lt div gt lt view gt lt image src 6
  • 将本机做成虚拟镜像文件(使用VMware vCenter Converter收取镜像)

    下载地址 xff08 需要账号 xff09 xff1a https customerconnect vmware com downloads info slug infrastructure operations management vm
  • uniapp 网络请求 get请求

    网络请求 在uni中可以调用uni request方法进行请求网络请求 需要注意的是 xff1a 在小程序中网络相关的API在使用需要配置域名白名单 官方文档 如果发起请求就调用我们这个uni request OBJECT 发送get请求
  • electron之旅(二)react使用

    首先使用react模板 我们这里使用的是vite和yarn span class token function yarn span create vite span class token comment 创建vite的react js模板
  • flutter学习之旅(二)

    如果不知道怎么安装编写可以查看这篇 创建项目 另一个创建方法 flutter create 项目名 热部署 vscode 热部署 vscode很简单 xff1a 可以通过Debug进行调试 使用flutter查看设备 flutter dev
  • Flutter学习之旅 - Scaffold属性Drawer侧边栏

    span class token class name Scaffold span span class token punctuation span appBar span class token punctuation span spa
  • Flutter学习之旅 - AppBar、TabBar、TabBarView实现头部顶部滑动导航

    文章目录 AppBar自定义顶部按钮图标 颜色取消debug图标TabBar TabBarView来实现顶部导航PreferredSize组件改变TabBar导航样式自定义KeepAliveWrapper缓存页面如何获取tab下的索引值销毁
  • Flutter学习之旅 - 路由

    文章目录 Flutter路由介绍普通路由普通路由传值 命名路由将 96 routes 96 的配置提到外面 使用的是Map 命名路由传值 路由跳转返回上一级路由替换路由返回到根路由返回Tabs后到指定页面 Flutter路由介绍 flutt
  • Ubuntu 和 Debian 的关系

    转自 xff1a http people ubuntu com happyaron udc cn lucid html ch11s09 html Debian 于 1993年8月16日 由一名美国普渡大学学生 Ian Murdock 首次发
  • Makefile学习笔记

    主要参考文档 xff1a 跟我一起写makefile xff0c 这里 有一篇 谈谈职业规划 CSDN对陈皓的采访 xff0c 被采访的大牛就是这个文档的作者 xff0c 他的CSDN专栏 本文的示例工程及Makefile 在这里 一 关于
  • 运行的docker增加端口映射

    1 运行了一个centos7的容器 xff0c 22端口映射给宿主机5002端口 xff1a docker span class token function ps span span class token operator span s
  • 23.易混淆命令(apt-get、wget、git clone、pip与pip3区别、apt-get和pip区别)

    摘要 xff1a 本文详细介绍了Ubuntu系统下apt get wget git clone pip与pip3 apt get和pip几组概念的区别 1 apt get 参考文献 xff1a apt get 是AdvancedPackag
  • ssh实现免密登录(文中附上脚本)

    1 为什么要互信 很多时候 xff0c 我们经常需要登录同一个服务器或者客户端 xff0c 但是输入密码很繁琐 xff0c 此时我们就需要能免密登录某些服务器或客户端 下面我们就来看怎么简单实现免密登录 有时候我们在shell脚本中会不断去
  • MapReduce概述及工作流程

    内容 mapreduce原语 xff08 独创 xff09 mapreduce工作流程 xff08 重点 xff09 MR作业提交流程 xff08 重点 xff09 YARN RM HA搭建 xff08 熟练 xff09 运行自带的word
  • IIC总线

    1 概念 IIC总线是PHLIPS公司在八十年代初推出的一种串行的半双工同步总线 xff0c 主要用于连接整体电路 同一块板子两个芯片之间的通信是通过IIC总线进行的 xff08 stm32mp157a lt IIC gt SI7006 I