IIC串行总线的基本介绍与代码详解

一. iic的基本介绍 1.1iic的简介       iic是双线(不算地线)半双工的一种通讯方式(可以双向通讯,但不可以在同一时间双向数据传输).
      iic串行总线一般有两根信号线,一根是双向的数据线sda,另一根是时钟线scl,其时钟信号是由主控器件产生。所有接到iic总线设备上的串行数据sda都接到总线的sda上,各设备的时钟线scl接到总线的scl上。对于并联在一条总线上的每个ic都有唯一的地址。
 图1 iic拓扑网络  图2 iic时序图 1.2地址问题 iic设备地址
       协议格式中第一个字节(为slave address)由7位地址和一位r/w读写位组成的,这字节是个器件地址。
常用iic接口通用器件的器件地址是由种类型号,及寻址码组成的,共7位。
如格式如下:
d7 d6 d5 d4 d3 d2 d1 d0
(1)、器件类型:d7-d4 共4位决定的。这是由半导公司生产时就已固定此类型的了,也就是说这4位已是固定的。
(2)、用户自定义地址码:d3-d1共3位。这是由用户自己设置的,通常的作法如eeprom这些器件是由外部ic的3个引脚所组合电平决定的(用常用的名字如a0,a1,a2)。这也就是寻址码。所以为什么同一iic总线上同一型号的ic只能最多共挂8片同种类芯片的原因了。
(3)、最低一位就是r/w位,,“0”表示写,“1”表示读(通常读写信号中写上面有一横线,表示低电平)。所以iic设备通常有两个地址,即读地址和写地址。
iic 设备的7 位地址是就当前iic总线而言的,是“相对地址”。不同的iic总线上的设备可以使用相同的7 位地址,但是它们所在的i2c 总线不同。所以在系统中一个iic设备的“绝对地址”由二元组(iic适配器的id 和设备在该总线上的7 位地址)表示。”,所以这个函数的作用主要是排除同一iic总线上出现多个地址相同的设备。
1.3 iic协议       iic总线在传输数据的过程中一共有三种类型信号,分别为:开始信号、结束信号和应答信号。这些信号中,起始信号是必需的,结束信号和应答信号,都可以不要。同时我们还要介绍其空闲状态、数据的有效性、数据传输。
图2 iic时序图       (1)空闲状态
当iic总线的数据线sda和时钟线scl两条信号线同时处于高电平时,规定为总线的空闲状态。此时各个器件的输出级场效应管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。
      (2)起始信号与停止信号
起始信号:当时钟线scl为高期间,数据线sda由高到低的跳变;启动信号是一种电平跳变时序信号,而不是一个电平信号;
停止信号:当时钟线scl为高期间,数据线sda由低到高的跳变;停止信号也是一种电平跳变时序信号,而不是一个电平信号。
(3) 应答信号
发送器每发送一个字节(8个bit),就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。
应答信号为低电平时,规定为有效应答位(ack,简称应答位),表示接收器已经成功地接收了该字节;
应答信号为高电平时,规定为非应答位(nack),一般表示接收器接收该字节没有成功。
对于反馈有效应答位ack的要求是:接收器在第9个时钟脉冲之前的低电平期间将数据线sda拉低,并且确保在该时钟的高电平期间为稳定的低电平。 如果接收器是主控器,则在它收到最后一个字节后,发送一个nack信号,以通知被控发送器结束数据发送,并释放数据线sda,以便主控接收器发送一个停止信号p。
       (4)数据有效性
iic总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定;只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。即:数据在时钟线scl的上升沿到来之前就需准备好。并在在下降沿到来之前必须稳定。
       (5)数据的传达
在iic总线上传送的每一位数据都有一个时钟脉冲相对应(或同步控制),即在scl串行时钟的配合下,在sda上逐位地串行传送每一位数据。数据位的传输是边沿触发。
二.代码       关于iic代码部分的内容这里主要讲解hal块部分的内容。这里hal初始化的三个部分包括:引脚配置初始化,写数据函数,读数据函数。
      在引脚配置的 iicinit 中对iic的两个 引脚(scl,sda)进行引脚的配置,并对iic相关的库函数进行配置,其中引脚的配置这里不再进行讲解,需要注意的是gpio的模式要配置成gpio_mode_af_od 复用开漏输出或者gpio_mode_out_pp数据寄存器输出。
      关于iic的配置,iic的模式,自身地址,
typedef struct{ uint32_t i2c_clockspeed; /*设置scl时钟频,此值不低于40000*/ uint16_t i2c_mode; /* 指定工作模式,可选i2c模式和smbus模式*/ uint16_t i2c_dutycycle; /*指定时钟占空比,可选 low/high=2:1以及16:9模式*/ uint16_t i2c_ownaddress1; /*指定自身的i2c设备地址 */ uint16_t i2c_ack; /*使能或者关闭响应 (一般都是使能) */ uint16_t i2c_acknowledgedaddress; /*指定地址的长度,可以位7位及10位 */}i2c_inittypedef; • i2c_clockspeed 设置i2c的传输速率,在调用初始化函数时,函数会根据我们输入的数值经过运算后把时钟因子写入到i2c的时钟控制寄存器ccr。而我们写入的这个参数值不得高于400khz。实际上由于ccr寄存器不能写入小数类型的时钟因子,影响到 scl的实际频率可能会低于本成员设置的参数值,这时除了通讯稍慢一点以外,不会对i2c的标准通讯造成其它影响。
• i2c_mode 选择i2c的使用方式,有i2c模式(i2c_mode_i2c )和smbus主、从模式(i2c_mode_smbushost、 i2c_mode_smbusdevice ) 。 i2c不需要在此处区分主从模式,直接设置i2c_mode_i2c即可。
• i2c_dutycycle 设置i 2c的scl线时钟的占空比。该配置有两个选择,分别为低电平时间比高电平时间为2:1 ( i2c_dutycycle_2)和16:9 (i2c_dutycycle_16_9)。其实这两个模式的比例差别并不大,一般要求都不会如此严格,这里随便选就可以了。
• i2c_ownaddress1 配置stm32的i2c设备自己的地址,每个连接到i2c总线上的设备都要有一个自己的地址,作为主机也不例外。地址可设置为7位或10位(受下面 i2c_acknowledgeaddress成员决定),只要该地址是i2c总线上唯一的即可。 stm32的i2c外设可同时使用两个地址,即同时对两个地址作出响应,这个结构成员i2c_ownaddress1配置的是默认的、oar1寄存器存储的地址,若需要设置第二个地址寄存器oar2,可使用 i2c_ownaddress2config函数来配置,oar2不支持10位地址。
• i2c_ack_enable 配置i 2c应答是否使能,设置为使能则可以发送响应信号。一般配置为允许应答(i2c_ack_enable),这是绝大多数遵循i 2c标准的设备的通讯要求,改为禁止应答(i2c_ack_disable)往往会导致通讯错误。
• i2c_acknowledgeaddress 选择i2c的寻址模式是7位还是10位地址。这需要根据实际连接到i2c总线上设备的地址进行选择,这个成员的配置也影响到 i2c_ownaddress1成员,只有这里设置成10位模式时, i2c_ownaddress1才支持10位地址。
利用库函数版本编写hal代码部分如下:


中国联通为重庆建设打造“智慧名城”、发展数字经济提供了重要支撑
华硕推出顶配旗舰笔记本:铝合金机身仅厚12.9mm!
USB 3.1type c连接器遇到这些情况该怎么解决?
不用表头指示的晶体三极管hFE测试器,HEF tester
电路设计与电路板设计的区别是什么呢?
IIC串行总线的基本介绍与代码详解
搜狗推AI录音笔C1 Pro出售,录音转文字准确率高达97%
小米击败苹果,成为全球第三大最畅销的手机制造商
Solar Frontier:利用CIS类太阳能电池挑战单晶硅
小米6还没抢到小米7就来了!小米7配置曝光:价格略有上涨,可能破3000
IBM POWER10处理器:为容器安全性带来了新的增强
一汽奔腾B30深度测评
永磁变频电机和普通变频电机的区别
光照培养箱是什么,有哪些功能
进阶版性能怪兽 OnePlus 7 Pro值得拥有
晶体管低频电压放大电路
如何通过工作量证明PoW来模拟容量证明PoC
DRANETZ简单专业的电能质量测试仪 HDPQ系列
荣耀V9、小米6、华为P10对比评测:华为荣耀V9、小米6、华为P10高性能高颜值你买了哪款?
初露峥嵘,无传感器马达设计降低系统成本与故障率