STM32入门教程:I2C通信

I2C(Inter-Integrated Circuit)是一种串行通信协议,常用于连接微控制器和外部设备。在STM32系列微控制器中,I2C总线是通过I2C外设来实现的。在本教程中,我们将介绍如何在STM32上使用I2C进行通信。

一、I2C的工作原理 I2C通信是基于主从架构的,其中一个设备充当主设备,其他设备充当从设备。主设备控制整个通信过程,可以向从设备发送读取或写入数据的请求。

I2C总线由两条信号线组成:SCL(串行时钟)和SDA(串行数据)。SCL线负责同步数据传输,而SDA线用于传输实际的数据。

在I2C通信中,每个设备都有一个唯一的地址。主设备可以通过发送设备地址来选择与之通信的从设备。从设备在收到地址后,可以向主设备发送ACK(应答)信号来确认通信建立。

二、使用STM32 HAL库进行I2C通信 在STM32中,我们使用STM32Cube HAL库来方便地配置和使用I2C外设。下面是一个简单的步骤来设置并使用I2C通信。

  1. 配置I2C外设 首先,我们需要在STM32CubeMX中配置I2C外设。打开STM32CubeMX并创建一个新的工程,然后选择你的STM32型号和启动时钟频率。

在"Pinout & Configuration"选项卡中,找到I2C外设并选择要使用的I2C引脚。确保为I2C外设分配合适的引脚。然后,点击"Configuration"选项卡,配置I2C的时钟频率和其他参数。

  1. 生成代码 配置完I2C外设后,点击"Project"菜单并选择"Generate Code"来生成初始化代码。

  2. 初始化I2C外设 在代码中,使用HAL_I2C_Init()函数来初始化I2C外设。此函数将在I2C通信之前一次性配置所有必要的寄存器和参数。

例如,要初始化I2C1外设,使用以下代码:

I2C_HandleTypeDef hi2c1;

/* 初始化I2C1外设 */
void I2C1_Init(void)
{
  hi2c1.Instance = I2C1;
  hi2c1.Init.Timing = 0x00303D5B;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  
  HAL_I2C_Init(&hi2c1);
}

  1. 发送和接收数据 在STM32中,HAL库提供了一组I2C相关的函数来发送和接收数据。使用HAL_I2C_Master_Transmit()函数来发送数据,而使用HAL_I2C_Master_Receive()函数来接收数据。

例如,要向从设备发送一个字节的数据,使用以下代码:

uint8_t data = 0xAA;
uint8_t slaveAddr = 0x50;

/* 发送一个字节的数据给从设备 */
HAL_I2C_Master_Transmit(&hi2c1, slaveAddr, &data, 1, HAL_MAX_DELAY);

要从从设备接收一个字节的数据,使用以下代码:

uint8_t receivedData;

/* 接收一个字节的数据从从设备 */
HAL_I2C_Master_Receive(&hi2c1, slaveAddr, &receivedData, 1, HAL_MAX_DELAY);

  1. 处理错误 在I2C通信中可能会出现错误。使用HAL_I2C_GetError()函数来获取最后一次I2C操作的错误代码。你可以根据这个错误代码来进行相应的处理。

例如,使用以下代码来检查是否出现错误:

if (HAL_I2C_GetError(&hi2c1) != HAL_OK)
{
  /* 处理错误 */
}

三、案例:使用STM32通过I2C与I2C EEPROM通信 下面是一个使用STM32和I2C EEPROM进行通信的案例。我们将使用STM32F4 Discovery Kit和一个24LC64 EEPROM。

  1. 硬件连接 将STM32F4 Discovery Kit的I2C1总线的SDA线连接到EEPROM的SDA线,将SCL线连接到EEPROM的SCL线。确保I2C总线的引脚连接正确。

  2. 配置STM32CubeMX 打开STM32CubeMX并创建一个新的工程。选择STM32F4型号和启动时钟频率。

在"Pinout & Configuration"选项卡中,找到I2C1外设并为其分配合适的引脚。

  1. 生成代码 点击"Project"菜单并选择"Generate Code"来生成初始化代码。

  2. 初始化I2C外设和GPIO外设 在代码中,使用HAL_I2C_Init()函数来初始化I2C1外设,并使用HAL_GPIO_Init()函数来初始化GPIO外设。

main.c文件的开头添加以下代码:

#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_i2c.h"
#include "stm32f4xx_hal_gpio.h"

I2C_HandleTypeDef hi2c1;

/* I2C1外设初始化 */
void I2C1_Init(void)
{
  hi2c1.Instance = I2C1;
  hi2c1.Init.Timing = 0x00303D5B;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  
  HAL_I2C_Init(&hi2c1);
}

/* GPIO外设初始化 */
void GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;

  __HAL_RCC_GPIOB_CLK_ENABLE();

  /* I2C1 SCL引脚配置 */
  GPIO_InitStruct.Pin = GPIO_PIN_6;
  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);

  /* I2C1 SDA引脚配置 */
  GPIO_InitStruct.Pin = GPIO_PIN_9;
  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);
}

main()函数中,添加以下代码来初始化I2C外设和GPIO外设:

int main(void)
{
  HAL_Init();

  /* 初始化I2C外设和GPIO外设 */
  I2C1_Init();
  GPIO_Init();

  while (1)
  {
    /* 主程序循环 */
  }
}

  1. 使用STM32与I2C EEPROM通信 在main()函数中,我们可以使用I2C外设来与I2C EEPROM进行通信。以下是一个例子,演示了如何向EEPROM写入一个字节的数据,并从EEPROM读取一个字节的数据:
#define EEPROM_ADDRESS 0xA0

int main(void)
{
  ...
  
  uint8_t dataToWrite = 0xAA;
  uint8_t dataToRead;

  /* 向EEPROM写入一个字节的数据 */
  HAL_I2C_Master_Transmit(&hi2c1, EEPROM_ADDRESS, &dataToWrite, 

  • 25
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大黄鸭duck.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值