跳到主要内容

STM32 I2C 配置

介绍

I2C(Inter-Integrated Circuit)是一种常用的串行通信协议,广泛用于连接微控制器与各种外设,如传感器、EEPROM、LCD 显示屏等。I2C 使用两根线进行通信:SDA(数据线)SCL(时钟线)。STM32 微控制器内置了硬件 I2C 外设,可以方便地实现 I2C 通信。

在本教程中,我们将学习如何在 STM32 上配置 I2C,并通过一个实际案例展示如何使用 I2C 与外部设备通信。

I2C 通信基础

I2C 是一种主从式通信协议,支持多主多从架构。每个设备都有一个唯一的地址,主设备通过地址选择从设备进行通信。I2C 通信的基本步骤如下:

  1. 起始条件:主设备发送起始信号。
  2. 地址传输:主设备发送从设备的地址。
  3. 数据传输:主设备或从设备发送数据。
  4. 停止条件:主设备发送停止信号。
备注

I2C 的通信速率通常为 100 kHz(标准模式)或 400 kHz(快速模式),但 STM32 支持更高的速率。

STM32 I2C 配置步骤

1. 硬件连接

首先,确保 STM32 的 I2C 引脚(SCL 和 SDA)正确连接到外部设备的对应引脚。通常,SCL 和 SDA 引脚需要上拉电阻(通常为 4.7 kΩ)。

2. 配置 GPIO 引脚

在 STM32 中,I2C 引脚需要配置为复用功能模式。以下是配置 GPIO 引脚的代码示例:

c
// 配置 GPIO 引脚为 I2C 功能
GPIO_InitTypeDef GPIO_InitStruct = {0};

// 使能 GPIO 时钟
__HAL_RCC_GPIOB_CLK_ENABLE();

// 配置 PB6 为 SCL,PB7 为 SDA
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; // 复用为 I2C1
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

3. 配置 I2C 外设

接下来,配置 I2C 外设的时钟和通信参数。以下是配置 I2C 的代码示例:

c
// 配置 I2C
I2C_HandleTypeDef hi2c1;

// 使能 I2C 时钟
__HAL_RCC_I2C1_CLK_ENABLE();

// 配置 I2C 参数
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000; // 100 kHz
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) {
// 初始化错误处理
}

4. 发送和接收数据

配置完成后,可以使用 HAL 库提供的函数进行数据发送和接收。以下是一个简单的示例,展示如何向 I2C 设备写入数据:

c
uint8_t data[] = {0x01, 0x02, 0x03};  // 要发送的数据
uint8_t deviceAddress = 0x50; // 从设备地址

// 向设备写入数据
if (HAL_I2C_Master_Transmit(&hi2c1, deviceAddress << 1, data, sizeof(data), HAL_MAX_DELAY) != HAL_OK) {
// 发送错误处理
}
提示

在 I2C 通信中,设备地址通常需要左移一位,因为最低位用于指示读/写操作。

实际案例:读取温度传感器数据

假设我们有一个 I2C 温度传感器(如 LM75),我们可以通过以下步骤读取温度数据:

  1. 发送读取命令:向传感器发送读取温度的命令。
  2. 接收数据:从传感器读取温度数据。

以下是代码示例:

c
uint8_t tempData[2];  // 用于存储温度数据
uint8_t deviceAddress = 0x48; // LM75 的 I2C 地址

// 读取温度数据
if (HAL_I2C_Master_Receive(&hi2c1, deviceAddress << 1, tempData, 2, HAL_MAX_DELAY) != HAL_OK) {
// 接收错误处理
}

// 计算温度值
int16_t temperature = (tempData[0] << 8) | tempData[1];
temperature = temperature >> 5; // LM75 的温度数据格式

总结

通过本教程,我们学习了如何在 STM32 上配置和使用 I2C 通信协议。我们了解了 I2C 的基本原理,并通过实际案例展示了如何与外部设备进行通信。

警告

在实际应用中,务必确保 I2C 设备的地址和通信速率正确配置,以避免通信失败。

附加资源与练习

  • 练习:尝试使用 I2C 与不同的外设(如 EEPROM 或 LCD 显示屏)进行通信。
  • 资源:参考 STM32 官方文档,了解更多关于 I2C 的高级配置和功能。

通过不断实践和探索,您将能够熟练掌握 STM32 的 I2C 通信技术。