STM32F103与4525I压力传感器通讯中的硬件I2C的解决方案

至我感谢亲爱的妻子大喵和孩子们

1,问题的背景介绍

一直以来总有人说STM32F103的I2C有BUG。所以大家一般都是用GPIO模拟I2C。而实际上,这个问题还是可以解决的。
手头上有个项目,需要用103的I2C和TE的压力传感器通讯并且不允许使用操作系统。GPIO - I2C的主要问题是需要不断的轮询,并且不能使用中断、DMA。如果你还对波形的形状有所要求,比如时钟周期不要有波动,GPIO模拟的I2C的性能其实是不好的。相比之下,那么硬件I2C表现出来的性能还是不错的。
在项目的测试中发现,如果直接使用寄存器编程,103的硬件I2C的主要问题有:

  1. 传感器发来ACK响应,103的状态寄存器没有响应。这个问题主要发生在主机发送了ADDR以后,传感器虽然已经发送了ACK,但是103的状态寄存器没有相应置位,直接判定为Acknowledge failure并置位I2C_SR1的AF位。
  2. 配置CCR的分频往往不生效。

2, 原因分析

目前找到了HAL库的解决方案。根据前面的分析怀疑是I2C的GPIO时钟使能不生效。
跟I2C相关的时钟至少有两个,分别是APB1和相应的GPIO的时钟。这两个始终都必须要使能。

3, 解决方案

总的思路是,两次使能I2C时钟。

3.1, HAL库的解决方案

IDE: STM32CubeIDE(任何版本) (含STM32CubeMX) + 修改生成的函数
这里需要说明的是,使用HAL库开发103的时候推荐使用ST的官方IDE。因为在Keil的RTE上提供的是标准库。标准库有关I2C的函数其实大概就是寄存器的转写。所有使用寄存器会遇到的问题使用标准库同样会遇到。

Stm32CubeIDE中的管脚配置:
Alt
参数设置为:
ALT
Alt
并且要在NVIC配置中将I2C2的 event interupt使能。

配置好项目,点击Generate Code。在生成的代码中的i2c.h中找到void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)函数,注意,必须在此函数中两次使能时钟才能让I2C正常工作,代码如下所示。

void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(i2cHandle->Instance==I2C2)
  {
  /* USER CODE BEGIN I2C2_MspInit 0 */
	  __HAL_RCC_I2C2_CLK_ENABLE(); //就是这句!!!!!!
  /* USER CODE END I2C2_MspInit 0 */

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**I2C2 GPIO Configuration
    PB10     ------> I2C2_SCL
    PB11     ------> I2C2_SDA
    */
    GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* I2C2 clock enable */
    __HAL_RCC_I2C2_CLK_ENABLE();

    /* I2C2 interrupt Init */
    HAL_NVIC_SetPriority(I2C2_EV_IRQn, 3, 0);
    HAL_NVIC_EnableIRQ(I2C2_EV_IRQn);
  /* USER CODE BEGIN I2C2_MspInit 1 */

  /* USER CODE END I2C2_MspInit 1 */
  }
}

注意第一次__HAL_RCC_I2C2_CLK_ENABLE()的调用。非常关键

3.2, CMSIS-Driver库解决方案

IDE:KEIL 5.20以后的版本可以考虑使用使用CMSIS-DRIVER中的I2C Driver。经测试没有问题。要注意的是,对于Cortex-M3的核,CMSIS-Driver是自主设计的驱动;而Cortex-M4则直接调用的Hal库。

4,结论

103的硬件I2C其实是可以使用的。人们认为的bug其实是可以通过两次使能GPIO的时钟来规避。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F103是一款由STMicroelectronics开发的微控制器芯片,它具有强大的处理能力和丰富的外设功能。其之一就是I2C(Inter-Integrated Circuit)硬件接口。 I2C是一种串行通信协议,用于连接微控制器与外部器件,如传感器、存储器、显示器等。STM32F103的I2C硬件接口包含主模式和从模式两种运行模式,可以灵活地满足不同的应用需求。 在主模式下,STM32F103可以作为I2C总线的主设备,控制和管理多个从设备。主设备可以发送I2C起始信号、地址和数据,还可以接收从设备的响应和数据。I2C硬件接口的寄存器和控制器可以实现自动重复启动、多字节传输、多主设备共享总线等功能,方便主设备与从设备之间进行高效的数据交换。 在从模式下,STM32F103可以作为I2C总线的从设备,响应主设备的命令和传输数据。从设备可以根据主设备的地址选择性地响应,还可以通过自动应答机制向主设备发送数据。I2C硬件接口的寄存器和控制器还支持接收和发送缓冲区,以及断和DMA传输方式,提升了从设备的灵活性和数据处理能力。 总之,STM32F103的I2C硬件接口为嵌入式系统提供了高效、可靠的串行通信解决方案。它的主模式和从模式能够满足不同的通信要求,支持多主设备同时共享总线,并配备了丰富的功能和灵活的操作方式,使得它成为许多应用领域的理想选择。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值