[STM32F1] STM32F103C8T6的I2C通信实现与调试

[复制链接]
4055|11
 楼主| 公羊子丹 发表于 2025-1-19 08:06 | 显示全部楼层 |阅读模式
在嵌入式系统中,I2C(Inter-Integrated Circuit)是一种常用的通信协议,广泛应用于传感器、显示器、存储设备等外设的连接。STM32系列单片机提供了强大的I2C硬件支持,能够简化I2C通信的实现与调试。本文将介绍如何使用STM32F103C8T6实现I2C通信,并给出实际的代码示例及调试技巧。
1. STM32F103C8T6概述STM32F103C8T6属于STMicroelectronics的STM32F1系列,采用ARM Cortex-M3内核,具有高效的处理能力和丰富的外设资源。该单片机工作频率最高可达72MHz,支持多个通信接口(如I2C、SPI、USART等)。在本篇文章中,我们将专注于STM32F103C8T6的I2C通信模块。
2. I2C通信协议I2C是一种多主机、多从机的串行通信协议,使用两根信号线:数据线SDA和时钟线SCL。I2C协议的特点是通信速度快,线缆少,且支持多种外设连接。STM32的I2C接口不仅支持标准模式(100Kbps),也支持快速模式(400Kbps)。
3. 硬件连接在本实验中,我们将STM32F103C8T6与一个I2C设备(如EEPROM或传感器)连接。硬件连接非常简单,只需要将SDA、SCL引脚连接到I2C外设的对应引脚,同时使用适当的上拉电阻。
STM32F103C8T6引脚I2C外设引脚
PB6SCL
PB7SDA此外,在SDA和SCL引脚上分别加上4.7kΩ的上拉电阻,确保I2C信号线处于正常的高电平状态。
4. STM32F103C8T6的I2C配置I2C的配置过程主要分为以下几个步骤:
  • 开启I2C外设时钟
  • 配置GPIO为I2C模式
  • 初始化I2C外设
  • 设置I2C的通信参数(如时钟频率)
  • 发送和接收数据
5. I2C通信代码示例接下来是STM32F103C8T6 I2C通信的完整代码示例。该示例演示了如何初始化I2C、发送和接收数据。
  1. #include "stm32f1xx_hal.h"

  2. // I2C句柄定义
  3. I2C_HandleTypeDef hi2c1;

  4. // I2C初始化函数
  5. void I2C_Init(void)
  6. {
  7.     __HAL_RCC_GPIOB_CLK_ENABLE();
  8.     __HAL_RCC_I2C1_CLK_ENABLE();

  9.     // 配置I2C的GPIO引脚
  10.     GPIO_InitTypeDef GPIO_InitStruct = {0};
  11.     GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;    // PB6 (SCL), PB7 (SDA)
  12.     GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;            // 开漏输出模式
  13.     GPIO_InitStruct.Pull = GPIO_NOPULL;                // 不使用上拉电阻
  14.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;      // 高速
  15.     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  16.     // 配置I2C外设
  17.     hi2c1.Instance = I2C1;
  18.     hi2c1.Init.ClockSpeed = 100000;         // 100kHz
  19.     hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; // 50%占空比
  20.     hi2c1.Init.OwnAddress1 = 0x00;         // 设备地址
  21.     hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  22.     hi2c1.Init.Acknowledgement = I2C_ACKNOWLEDGE_ENABLE;
  23.     hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  24.     hi2c1.Init.Mode = I2C_MODE_MASTER;     // 设置为主机模式
  25.     hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  26.     hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  27.     hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;

  28.     // 初始化I2C外设
  29.     if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  30.     {
  31.         // 初始化失败,错误处理
  32.         Error_Handler();
  33.     }
  34. }

  35. // 发送数据
  36. HAL_StatusTypeDef I2C_SendData(uint16_t deviceAddr, uint8_t *data, uint16_t size)
  37. {
  38.     return HAL_I2C_Master_Transmit(&hi2c1, deviceAddr, data, size, 1000);
  39. }

  40. // 接收数据
  41. HAL_StatusTypeDef I2C_ReceiveData(uint16_t deviceAddr, uint8_t *data, uint16_t size)
  42. {
  43.     return HAL_I2C_Master_Receive(&hi2c1, deviceAddr, data, size, 1000);
  44. }

  45. int main(void)
  46. {
  47.     // HAL库初始化
  48.     HAL_Init();
  49.     I2C_Init();

  50.     uint8_t txData[] = "Hello I2C!";
  51.     uint8_t rxData[10];

  52.     // 发送数据
  53.     if (I2C_SendData(0xA0, txData, sizeof(txData)) == HAL_OK)
  54.     {
  55.         // 数据发送成功
  56.     }

  57.     // 接收数据
  58.     if (I2C_ReceiveData(0xA0, rxData, sizeof(rxData)) == HAL_OK)
  59.     {
  60.         // 数据接收成功
  61.     }

  62.     while (1)
  63.     {
  64.     }
  65. }

  66. void Error_Handler(void)
  67. {
  68.     // 错误处理代码
  69.     while (1)
  70.     {
  71.     }
  72. }
6. 调试技巧
  • 检查I2C时钟频率:I2C总线的时钟频率对于通信稳定性至关重要。确保时钟频率符合外设要求,避免过高或过低的频率导致通信不稳定。
  • 使用逻辑分析仪调试:如果通信出现问题,使用逻辑分析仪可以帮助你检查SDA和SCL信号的时序,查看是否符合I2C协议的要求。
  • 检查设备地址:I2C通信的设备地址可能会因为不同的外设或不同的配置而有所不同。确认设备地址的设置,确保正确的地址用于发送和接收数据。
  • 确保上拉电阻:如果没有适当的上拉电阻,I2C总线可能无法正常工作,尤其是在高速模式下,确保SDA和SCL都有合适的上拉电阻。
7. 总结STM32F103C8T6在实现I2C通信时具备高效和灵活的配置能力,能够满足不同应用场景的需求。通过使用HAL库,开发者可以更加简单地进行I2C通信的配置与调试,从而节省开发时间并提高系统稳定性。

周半梅 发表于 2025-1-19 08:06 | 显示全部楼层
刚刚接触STM32,这篇文章真的很有帮助!I2C配置的细节讲得很清楚。
帛灿灿 发表于 2025-1-19 08:07 | 显示全部楼层
代码很好,特别是I2C的初始化部分,照着做就能跑起来了。
童雨竹 发表于 2025-1-19 08:07 | 显示全部楼层
STM32的I2C库很强大,和其他平台比起来,真的是简单很多。
万图 发表于 2025-1-19 08:07 | 显示全部楼层
我在做项目时用过这个I2C示例,成功收发了数据,感谢分享!
Wordsworth 发表于 2025-1-19 08:07 | 显示全部楼层
我一直担心I2C时钟配置的问题,文章里讲解得很透彻。
Bblythe 发表于 2025-1-19 08:08 | 显示全部楼层
刚刚遇到I2C通信不稳定的问题,逻辑分析仪的建议非常有用
Pulitzer 发表于 2025-1-19 08:08 | 显示全部楼层
遇到I2C通信错误时,总是对地址问题很头疼,这篇文章解决了我的疑问。
Uriah 发表于 2025-1-19 08:08 | 显示全部楼层
STM32F103C8T6的性能很强,I2C调试也相对简单,做嵌入式开发还是推荐这个型号。
Clyde011 发表于 2025-1-19 08:08 | 显示全部楼层
文章有用,特别是关于上拉电阻的问题,之前一直没有注意这个细节
Amazingxixixi 发表于 2025-1-21 17:04 | 显示全部楼层
学习一下啊,还有好多需要学习的。
SophiaOP 发表于 2025-1-22 22:18 来自手机 | 显示全部楼层
一直在用硬件iic,没感觉到哪有问题啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则

231

主题

6924

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部