I2C之知(四)--I2C总线的7bit从机地址

时钟拉伸(Clock stretching)
clock stretching通过将SCL线拉低来暂停一个传输.直到释放SCL线为高电平,传输才继续进行.clock stretching是可选的,实际上大多数从设备不包括SCL驱动,所以它们不能stretch时钟.
从字节级来看,一个设备可能在快速模式下接受数据,但是需要更多的时间来存储接收到的字节或者准备将要传输的另一个字节.从机可以以一种握手的处理方式在接受和应答字节后将SCL线拉低来强制使得主机进入wait状态知道从机准备好下一个字节的传输.
从位级来看,I2C总线上的设备可以通过增长每一个时钟的低周期来降低总线时钟.所以每个主机可以适应这个设备的内部操作速率.
在Hs模式,握手处理只能用在字节级别.

从机地址和R/W bit
下图是数据传输的格式:

在开始条件(S)后,发送从机地址.地址是7bit,后面的第8bit是数据的读写bit,0表示写,1表示读.具体的看下图:

数据传输被主机产生的终止条件(P)终止.然而,主机也可以无需先产生终止条件,产生一个重复的开始条件(Sr)和寻址另一个从机,
可能的数据传输格式如下:
主-发送器传到从-接收器.传输方向不变.从-接收器应答每一个字节.如下:

在第一个字节后主机从从机读数据.第一个应答后,主-发送器变为主-接收器而从-接收器变为从-发送器.第一个应答仍然是由从机产生的.主机产生余下的应答.主机在产生终止条件之前要发送一个NA.如下:

复合模式.在传输过程中改变方向,开始条件和从机地址都要重复,而读写bit要取反.如果主-接收器发送一个重复的开始条件,那么它在这之前要发送一个NA.

注意:
1.复合模式可以在比如控制串行内存器时用到.在第一个数据字节时一定要写内存器内部的地址.开开始条件和从地址重复后,数据就开始传输了.
2.自动增加或减少之前访问的内存位置都由设备的设计者决定.
3.每一个字节后面都跟着一个应答位,在图中用A或非A来表示.
4.兼容I2C总线的设备在接收到开始条件或重复开始条件时都一定要重启它们的总线逻辑,即使开始条件都不是正确的格式,它们都期望发送从机地址.
5.开始条件后立马跟着一个终止条件是不合法的格式.很多设备在设计时考虑了这一点,可以处理.
6.连接到总线上的每个设备都由唯一的地址来确定.通常是简单的主从关系,但可能存在多个一样的从机可以同时接收和响应,比如说组播.这里是以NXP的PCA9546A作为例子说明.(PCA9546A是NXP半导体生产的一款基于I2C总线控制的4通道双向多路复用器和开关。使用PCA9546A可以将一路SCL/SDA输入扩展为4路SCL/SDA输出,在对内部控制寄存器进行相应配置后,可同时选择一路或多路下行I2C总线与上行I2C总线通信。)


  • 8
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
在使用STM32单片机之间的I2C总线通信时,每个设备需要设置唯一的地址,以便在总线上进行识别和通信。以下是设置I2C设备地址的示例代码: ```c #include "stm32f1xx_hal.h" /* 定义I2C设备地址 */ #define DEVICE_ADDRESS 0x50 I2C_HandleTypeDef hi2c1; /* I2C初始化代码 */ void MX_I2C1_Init(void) { /* I2C时钟使能 */ __HAL_RCC_I2C1_CLK_ENABLE(); /* I2C GPIO初始化 */ GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* I2C初始化 */ hi2c1.Instance = I2C1; hi2c1.Init.ClockSpeed = 100000; hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 = DEVICE_ADDRESS << 1; // 设置I2C设备地址 hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0xFF; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; /* I2C使能 */ if (HAL_I2C_Init(&hi2c1) != HAL_OK) { Error_Handler(); } } ``` 以上代码演示了如何使用STM32F1xx_HAL库初始化I2C1总线,以及如何设置I2C设备地址。将DEVICE_ADDRESS设置为一个唯一的值即可。在这个示例中,设备地址为0x50。 注意,在STM32F1xx系列中,I2C设备地址是7位的,所以需要左移一位将8位地址转换为7位地址。在其他系列的STM32单片机上,I2C设备地址可能是不同的,具体设置方式可能有所不同。需要根据具体的芯片手册进行设置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值