post2003 发表于 2018-5-11 09:13:20

CubeMX FreeRTOS 关于I2C总线故障解决方案的分享和疑惑

各位大神

我是stm32F103,使用CubeMX FreeRTOS,通过其配置访问24C16,碰到一个非常奇怪的问题:
原生cubeMX生成的代码,在同样一批板子上,有大概10%,在代码第一次读取24C16时,会陷入死循环,停在
stm32f1xx_hal_i2c.c中的

while((__HAL_I2C_GET_FLAG(hi2c, Flag) ? SET : RESET) == Status)
这里。

查了一些资料,对代码做了修改:

就OK了,无论是10%还是90%都可以正常工作。
分享给大家,

在stm32f1xx_hal_msp.c文件中,
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
函数中,在user code里增加如下两句
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hi2c->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspInit 0 */
/* USER CODE END I2C1_MspInit 0 */

    /**I2C1 GPIO Configuration   
    PB6   ------> I2C1_SCL
    PB7   ------> I2C1_SDA
    */
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    /* Peripheral clock enable */
    __HAL_RCC_I2C1_CLK_ENABLE();
/* USER CODE BEGIN I2C1_MspInit 1 */
    __HAL_RCC_I2C1_FORCE_RESET();
    __HAL_RCC_I2C1_RELEASE_RESET();
/* USER CODE END I2C1_MspInit 1 */
}
}



一来有点疑问请教大家:
1、这个原因是为什么?道理是什么?
2、为何STM的HAL库不这样实现?如果是Bug,这个Bug我看存在了很久了,STM不这样修改的原因是什么?
3、这样有什么隐患么?


欢迎讨论。谢谢。

toofree 发表于 2018-5-11 09:56:46

本帖最后由 toofree 于 2018-5-11 11:47 编辑

STM32启动后,在配置IO管脚过程中,I2C的管脚,有可能会被误产生I2C的启始位,或别的原因导致24C16的I2C总线处于“忙”的状态。

如果MCU的I2C管脚是真正的OC门或者像51单片机那样带弱上拉,这时就不会出现启动时总线的误动作。
也可能是基于这原因吧,NXP的一些MCU的I2C和GPIO复用管脚是OC门,不加上拉的话,是输出不了高状态的。

在I2C协议中是有总线复位操作部分的。好像是把检测到SDA被拉低超过一定时间后,连续发送9或17位时钟信号(时间长了,具体多少位可能不准确),目的就是把原有I2C指令冲掉,这样就算总线复位了。

MrJiu 发表于 2018-5-11 11:25:02

个人就一个建议,建议使用模拟的。。。硬件I2C最好还是不要用,而且ST的IO口定义,使其可以模拟很多个I2C,而代码量增加不大。。。而且,不同的I2C切换非常容易!!!;P;P;P

post2003 发表于 2018-5-11 15:06:46

toofree 发表于 2018-5-11 09:56
STM32启动后,在配置IO管脚过程中,I2C的管脚,有可能会被误产生I2C的启始位,或别的原因导致24C16的I2C总 ...

可是我对IO都加了上拉电阻,还是会出现这个问题。

那么现在这种复位,应该不会带来什么隐患把。

post2003 发表于 2018-5-11 15:07:54

MrJiu 发表于 2018-5-11 11:25
个人就一个建议,建议使用模拟的。。。硬件I2C最好还是不要用,而且ST的IO口定义,使其可以模拟很多个I2C, ...

没道理这么大的公司这么大的产品,一个硬件I2C还做不好?;P

butterflyspring 发表于 2018-5-11 15:21:59

这是有可能检测到外部信号,所以busy吧,你可以尝试在初始化I2C之前加个长delay试试?

toofree 发表于 2018-5-11 16:28:25

post2003 发表于 2018-5-11 15:06
可是我对IO都加了上拉电阻,还是会出现这个问题。

那么现在这种复位,应该不会带来什么隐患把。 ...

要不拿示波器看一下,最好跟踪,3.3V、SDA、SCL。

我也只是猜想,因为IO的输出寄存器默认是0,如果不修改输出寄存器的话,那么突然由输入或悬空切换到输出的时候,应该会瞬间出现个0才对。
IO是会受影响的,I2C设置的时候对应IO的状态会不会受影响就不清楚了。
页: [1]
查看完整版本: CubeMX FreeRTOS 关于I2C总线故障解决方案的分享和疑惑