Stm32_hal库IIC时钟拉伸的漏洞

2023-11-20 14:47:08 浏览数 (2)

iic可以开启时钟拉伸功能,这种功能可以让主机决定什么时候继续发送时钟,此功能作用时会将从机SCL拉低。

针对主机多读或者多写的情况(比如主机收10个字节,从机发送5个字节),hal库并未作处理,会导致从机一直拉低SCL。Hal库原来的程序是这样:

代码语言:javascript复制
static void
I2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c)
{
 if
(hi2c->XferCount != 0U)
 {
/* Write data to DR */
hi2c->Instance->DR = *hi2c->pBuffPtr;
/* Increment Buffer pointer */
hi2c->pBuffPtr  ;
/* Update counter */
hi2c->XferCount--;
 }
}
static void
I2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c)
{
 if
(hi2c->XferCount != 0U)
 {
/* Read data from DR */
*hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
/* Increment Buffer pointer */
hi2c->pBuffPtr  ;
/* Update counter */
hi2c->XferCount--;
 }
}

这个是原来的库函数,多读或者多写后,会触发btf中断进入这个函数,同时hi2c->XferCount为0(原计划的数据量读写已经完成),导致btf中断函数什么也没做,SCL持续拉低.

可以做如下修改解决此问题

代码语言:javascript复制
static void I2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c)
{
   if (hi2c->XferCount != 0U)
    {
      /* Write data to DR */
      hi2c->Instance->DR = *hi2c->pBuffPtr;
      /* Increment Buffer pointer */
      hi2c->pBuffPtr  ;
      /* Update counter */
      hi2c->XferCount--;
   }
    else
    {
       hi2c->Instance->CR1&= ~(1<<0);
       hi2c->Instance->CR1|= (1<<0);
    }
}
static void I2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c)
{
   if (hi2c->XferCount != 0U)
   {
      /* Read data from DR */
      *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
      /* Increment Buffer pointer */
      hi2c->pBuffPtr  ;
      /* Update counter */
      hi2c->XferCount--;
   }
  else
  {
       hi2c->Instance->CR1&= ~(1<<0);
       hi2c->Instance->CR1|= (1<<0);
  }
}

这样清除btf标志位,结束此次通信。

0 人点赞