STM32Cube学习篇(2)----I2C通讯协议

目录

1.I2C协议

1.1协议简介

1.2物理层

学习时间:


1.I2C协议

1.1协议简介

I2C通讯协议是由Phiilps公司开发的,其优点是硬件实现简单,引脚较小,可扩展性强,不需要 USARTCAN 等通讯协议的外部收发设备,现在被广泛地使用在系统内多 个集成电路 (IC) 间的通讯。

1.2物理层

常见的I2C连线方式如图1:


图1 I2C通讯系统 

物理层具有以下特点:

  • 它是一个支持设备的总线。在一个 I2C 通讯总线中,可 连接多个 I2C 通讯设备,支持多个通讯主机及多个通讯从机。
  • 一个 I2C 总线只使用两条总线线路,一条双向 串行数据线 (SDA) ,一条 串行时钟线 (SCL) 。数据线即用来表示数据,时钟线用于数据收发同步。
  • 每个连接到总线的设备都有一个 独立的地址 ,主机可以利用这个地址进行不同设备之间的访问。
  • 总线通过上拉电阻接到电源。当 I2C 设备空闲时,会输出高阻态,而当所有设备都空闲,都
    输出高阻态时,由上拉电阻把总线拉成高电平。
  • 多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定由哪个设备占用总线。
  • 具有三种传输模式:标准模式传输速率为 100kbit/s ,快速模式为 400kbit/s ,高速模式下可
    3.4Mbit/s ,但目前大多 I 2 C 设备尚不支持高速模式。

1.3协议层

I2C协议的格式包括起始和停止信号、有效数据、数据响应、仲裁、同步和地址广播等。通讯过程如图2、图3和图4所示:

图2:主机向从机写数据

图3: 主机读从机数据

 图4:I2C通讯复合格式

其中 S 表示由主机的 I2C 接口产生的 传输起始信号 (S) ,这时连接到 I2C 总线上的所有从机都会接收到这个信号。
起始信号产生后,所有从机就开始等待主机紧接下来 广播 从机地址信号 (SLAVE_ADDRESS)。 在 I2C 总线上,每个设备的地址都是唯一的,当主机广播的地址与某个设备地址相同时,这个设备
就被选中了,没被选中的设备将会忽略之后的数据信号。根据 I2C 协议,这个从机地址可以是 7
10
在地址位之后,是传输方向的选择位,该位为 0 时,表示后面的数据传输方向是由主机传输至从机,即主机向从机写数据。该位为 1 时,则相反,即主机由从机读数据。
从机接收到匹配的地址后,主机或从机会返回一个应答 (ACK) 或非应答 (NACK) 信号,只有接收
到应答信号后,主机才能继续发送或接收数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 硬件连接 首先,我们需要将EEPROM连接到STM32微控制器的I2C总线上。在本示例中,我们将使用STM32F4Discovery开发板,并将EEPROM连接到其I2C1总线。以下是硬件连接图: ![image.png](attachment:image.png) 2. STM32CubeIDE设置 在STM32CubeIDE中,我们需要启用I2C总线并配置它。以下是步骤: - 打开STM32CubeIDE并创建一个新项目。 - 选择“STM32F4xx”系列微控制器和您的开发板型号。 - 启用I2C总线。在“Pinout & Configuration”选项卡中,选择“I2C1”并启用它。 - 配置I2C总线。在“Configuration”选项卡中,选择“I2C1”并进行必要的配置,例如时钟速度和地址模式等。 3. 代码实现 现在,我们可以开始编写代码来读写EEPROM。以下是基本的代码框架: ```c #include "stm32f4xx_hal.h" #include "stdio.h" I2C_HandleTypeDef hi2c1; #define EEPROM_ADDR 0xA0 void EEPROM_Write(uint16_t addr, uint8_t data); uint8_t EEPROM_Read(uint16_t addr); int main(void) { HAL_Init(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_I2C1_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct = {0}; 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_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); hi2c1.Instance = I2C1; hi2c1.Init.ClockSpeed = 100000; hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK) { Error_Handler(); } uint8_t data = 0x55; EEPROM_Write(0x0001, data); uint8_t read_data = EEPROM_Read(0x0001); while (1) { } } void EEPROM_Write(uint16_t addr, uint8_t data) { uint8_t tx_data[3] = {addr >> 8, addr & 0xFF, data}; HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDR, tx_data, 3, 1000); } uint8_t EEPROM_Read(uint16_t addr) { uint8_t tx_data[2] = {addr >> 8, addr & 0xFF}; uint8_t rx_data[1]; HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDR, tx_data, 2, 1000); HAL_I2C_Master_Receive(&hi2c1, EEPROM_ADDR, rx_data, 1, 1000); return rx_data[0]; } ``` 在此示例中,我们定义了两个函数:`EEPROM_Write()`和`EEPROM_Read()`。`EEPROM_Write()`函数将一个字节写入EEPROM,`EEPROM_Read()`函数从EEPROM中读取一个字节。这两个函数使用STM32 HAL库中的I2C主机传输函数。 4. 测试 现在,我们可以将代码下载到STM32F4Discovery开发板上并测试代码。在本示例中,我们将向地址0x0001写入0x55,并从该地址读取数据。如果一切正常,我们应该能够读取写入的数据(0x55)。 以上就是使用STM32CubeIDE进行I2C接口读写EEPROM的步骤和代码示例。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值