该问题由某客户提出,发生在 STM32F103VDT6 器件上。据其工程师讲述:在其产品设计中,使用了 STM32 的一个 I2C 接口与一个 EEPROM 通信。在系统靠性测试中发现,经过长时间运行后,STM32 会出现不能读写 EEPROM 的现象。通过 NRST 管脚对STM32 进行复位,复位后该现象依旧存在。关掉电源,然后重新上电,现象消失。通过进一步测试发现,如果对 STM32 反复做复位操作,会很容易复现这一现象。6 [5 r+ v) ~, U, ?/ H9 [ , R# E) O( w' O( z/ \/ e 问题详细描述以及ST官方解答见文档: |
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)7 C5 U) c. J& q: M5 o% u" [
{" \" D0 T1 @8 E
GPIO_InitTypeDef GPIO_InitStruct;
if(hi2c->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspInit 0 */+ q" p: @+ G" g' S9 U
: n @: s( d6 G& O! F" u2 X- g
/* USER CODE END I2C1_MspInit 0 */; z5 o% x, e( `5 Q/ n
/**I2C1 GPIO Configuration 2 Z& F- f+ u, d3 C" Z. @1 z
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;/ I: I( W, B- O. G
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);% c2 P6 f l _1 P6 @, Q6 F3 h
& C( c# n7 W/ A, N# `4 b- z
/* Peripheral clock enable *// s# K$ A$ [6 p5 S
__I2C1_CLK_ENABLE();
/ z j8 f/ T$ U Q. p
/* Peripheral interrupt init*/# K& p& v, Q) q9 ]& K( B4 K
HAL_NVIC_SetPriority(I2C1_EV_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);
HAL_NVIC_SetPriority(I2C1_ER_IRQn, 0, 0);0 C# i3 }: K) ^6 \% C
HAL_NVIC_EnableIRQ(I2C1_ER_IRQn);
/* USER CODE BEGIN I2C1_MspInit 1 */7 b0 Q/ r+ @: N$ x) A% V
/* USER CODE END I2C1_MspInit 1 */- E: v3 h. q% h2 m$ R
}
}
这时总会处现在发送时就停在了busy这个位置,sda一直为低,后来看用以前的库写的! x/ F5 {( b6 x
__I2C1_CLK_ENABLE();是在GPIO设置之前,将它改到之前后就可以发送数据了,但是发现改后如再次用CUBE生成代码,它又回到了以前地方,因此再加个软复位来解决
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hi2c->Instance==I2C1)4 F/ q5 p9 O; n" z
{ X6 ]& x5 v7 f2 H3 \1 a
/* USER CODE BEGIN I2C1_MspInit 0 */( f& o3 P; k3 f- E3 y, R$ z
/* USER CODE END I2C1_MspInit 0 */( k8 a7 M4 {4 r3 W% f9 o0 P, O
$ M! d- ^" F4 [% V, p U; v
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL5 n% ~! F/ i" X& G" @- v
PB7 ------> I2C1_SDA
*/# f# P/ I* {# k/ j
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;2 n' y5 z, z$ `" t0 f9 o
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; @% M! s7 r8 a- i* t u+ h
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
$ _) }! A* I: ]6 V3 ?0 ^
/* Peripheral clock enable */! G% }0 Z, |) l6 ?3 V" Z
__I2C1_CLK_ENABLE();
/ v6 N+ d5 y; y% P
/* Peripheral interrupt init*/
HAL_NVIC_SetPriority(I2C1_EV_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);
HAL_NVIC_SetPriority(I2C1_ER_IRQn, 0, 0);1 R/ t; U$ J' X9 R/ v5 f+ g$ M
HAL_NVIC_EnableIRQ(I2C1_ER_IRQn);& p7 O* H4 F% k
/* USER CODE BEGIN I2C1_MspInit 1 */. L0 T0 Z( s0 c- T) i |( G: |
SET_BIT(hi2c->Instance->CR1, I2C_CR1_SWRST);
CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_SWRST);
/* USER CODE END I2C1_MspInit 1 */
}. S1 M) P# r4 c
}
试了一下果然可以解决这个问题,感谢!
RE:【ST MCU实战经验】I2C 接口进入 Busy 状态不能退出
有个问题请教下。
这样真的好了吗?参考一下