i2c总线的寻址方法有哪些?

i2c总线的寻址方式 10位寻址和7 位寻址兼容,而且可以结合使用。
10位寻址采用了保留的1111xxx 作为起始条件(s)或重复起始条件(sr )后第一个字节的头7 位。
10 位寻址不会影响已有的7 位寻址,有7 位和10 位地址的器件可以连接到相同的i2c 总线。它们都能用于标准模式(f/s)和高速模式(hs)系统。
保留地址位1111xxx 有8 个组合,但是只有4 个组合11110xx 用于10 位寻址,剩下的4个组合11111xx 保留给后续增强的i2c 总线。
10 位从机地址是由在起始条件(s) 或重复起始条件(sr )后的头两个字节组成。
第一个字节的头7 位是11110xx 的组合,其中最后两位(xx) 是10 位地址的两个最高位(msb)。
第一个字节的第8 位是r/w 位,决定了传输的方向,第一个字节的最低位是“0”表示主机将写信息到选中的从机,“1 ”表示主机将向从机读信息。
如果r/w 位是“0 ”,则第二个字节是10 位从机地址剩下的8 位;如果r/w 位是“1” 则下一个字节是从机发送给主机的数据。
i2c器件寻址 由于i2c上接有多个器件, 就存在器件寻址问题
i2c总线上传送的数据信号是广义的, 既包括地址信号, 又包括真正的数据信号
主机发出开始信号后, 发送一个从机地址(7位), 第八位是数据方向位(r:1/w:0)
数据传输一般由主机产生结束信号,
但是当主机仍希望通信, 可以发出重复起始条件(sr)和寻址另一个从机, 而不是产生一个停止条件
i2c寻址模式 i2c 每一位信号的时序流程,而 i2c 通信在字节级的传输中,也有固定的时序要求。i2c 通信的起始信号(start)后,首先要发送一个从机的地址,这个地址一共有 7位,紧跟着的第 8 位是数据方向位(r/w),“0”表示接下来要发送数据(写),‘“1”表示接下来是请求数据(读)。
我们知道,打电话的时候,当拨通电话,接听方捡起电话肯定要回一个“喂”,这就是告诉拨电话的人,这边有人了。同理,这个第九位 ack 实际上起到的就是这样一个作用。当我们发送完了这 7 位地址和 1 位方向后,如果发送的这个地址确实存在,那么这个地址的器件应该回应一个 ack(拉低 sda 即输出“0”),如果不存在,就没“人”回应 ack(sda将保持高电平即“1”)。
那我们写一个简单的程序,访问一下我们板子上的 eeprom 的地址,另外再写一个不存在的地址,看看它们是否能回一个 ack,来了解和确认一下这个问题。
我们板子上的 eeprom 器件型号是 24c02,在 24c02 的数据手册 3.6 节中可查到,24c02的 7 位地址中,其中高 4 位是固定的 0b1010,而低 3 位的地址取决于具体电路的设计,由芯片上的 a2、a1、a0 这 3 个引脚的实际电平决定,来看一下我们的 24c02 的电路图,它和24c01 的原理图完全一样,如图 14-4 所示。
图 14-4 24c02 原理图
从图 14-4 可以看出来,我们的 a2、a1、a0 都是接的 gnd,也就是说都是 0,因此 24c02的 7 位地址实际上是二进制的 0b1010000,也就是 0x50。我们用 i2c 的协议来寻址 0x50,另外再寻址一个不存在的地址 0x62,寻址完毕后,把返回的 ack 显示到我们的 1602 液晶上,大家对比一下。
文件程序源代码
我们把这个程序在 kst-51 开发板上运行完毕,会在液晶上边显示出来我们预想的结果,主机发送一个存在的从机地址,从机会回复一个应答位,即应答位为 0;主机如果发送一个不存在的从机地址,就没有从机应答,即应答位为 1。
前面的章节中已经提到利用库函数_nop_()可以进行精确延时,一个_nop_()的时间就是一个机器周期,这个库函数包含在 intrins.h 这个文件中,如果要使用这个库函数,只需要在程序最开始,和包含 reg52.h 一样,include《intrins.h》之后,程序中就可以使用这个库函数了。
还有一点要提一下,i2c 通信分为低速模式 100kbit/s、快速模式 400kbit/s 和高速模式3.4mbit/s。因为所有的 i2c 器件都支持低速,但却未必支持另外两种速度,所以作为通用的i2c 程序我们选择 100k 这个速率来实现,也就是说实际程序产生的时序必须小于等于 100k的时序参数,很明显也就是要求 scl 的高低电平持续时间都不短于 5us,因此我们在时序函数中通过插入 i2cdelay()这个总线延时函数(它实际上就是 4 个 nop 指令,用 define 在文件开头做了定义),加上改变 scl 值语句本身占用的至少一个周期,来达到这个速度限制。如果以后需要提高速度,那么只需要减小这里的总线延时时间即可。
此外我们要学习一个发送数据的技巧,就是 i2c 通信时如何将一个字节的数据发送出去。大家注意函数 i2cwrite 中,用的那个 for 循环的技巧。for (mask=0x80; mask!=0; mask》》=1),由于 i2c 通信是从高位开始发送数据,所以我们先从最高位开始,0x80 和 dat 进行按位与运算,从而得知 dat 第 7 位是 0 还是 1,然后右移一位,也就是变成了用 0x40 和 dat 按位与运算,得到第 6 位是 0 还是 1,一直到第 0 位结束,最终通过 if 语句,把 dat 的 8 位数据依次发送了出去。其它的逻辑大家对照前边讲到的理论知识,认真研究明白就可以了。

芯动速度:169天实现奠基到首批设备入厂
该如何增加网站服务器的安全性能
碱性锌锰电池优缺点_碱性锌锰电池发展前景
2021国际电机博览会即将开幕,兆威机电邀您共同参与
CMOS晶体振荡器具有超低抖动性能
i2c总线的寻址方法有哪些?
河南省实现县城以上城区5G网络全覆盖
TCP是如何实现可靠传输 HTTP与HTTPS的区别
华为鸿蒙操作系统再次被质疑 国产是原罪
室内仓储库房温湿度监测系统485总线解决方案
PLL 时钟合成器模块CKM151 EUVIS
超出int范围的整数如何输出
河南省加快推进5G各项重点工作
未来的中国数字货币会是怎样的
DC-DC同步整流24V转12V3A降压芯片AH8322
中国手机厂商的崛起导致LG手机业务退出中国市场
什么是钳形表,钳形表怎么用
传明年苹果将推出5.8寸OLED屏幕iPhone8 淘汰4寸机型
新的iPad Pro 10.5是市面上最好的平板电脑吗?
NVIDIA cuBLAS库加速BLAS的GPU设计实现