I2C 通信问题 - STM32(HAL 库)
Issue in the I2C communication - STM32 (HAL Library)
我遇到 I2C 通信问题。在第一个 运行 期间,MCU 和传感器之间的通信正常,然后我可以毫无问题地读取和写入传感器的寄存器。
然而,当我第二次尝试调试时,当我尝试与传感器通信时收到 HAL_BUSY,当电路板的电源被切断然后再次供电时,通信才重新建立.
写入寄存器的代码片段如下:
HAL_StatusTypeDef MAX30105_WriteRegister(uint8_t reg_addr, uint8_t reg_value){
HAL_StatusTypeDef returnValue = HAL_ERROR;
//Check if the MAX30105 is ready in a trial of 5 times
HAL_StatusTypeDef result = HAL_I2C_IsDeviceReady(&hi2c1, MAX30105_ADDR, 5, 10);
if (result == HAL_OK) // HAL_ERROR or HAL_BUSY or HAL_TIMEOUT
{
returnValue = HAL_I2C_Mem_Write(&hi2c1, MAX30105_ADDR, reg_addr , 1, ®_value, sizeof(reg_value), 10);
if(returnValue != HAL_OK)
return returnValue;
}
return returnValue;
}
I2C 设置为:
static void MX_I2C1_Init(void)
{
/* USER CODE BEGIN I2C1_Init 0 */
/* USER CODE END I2C1_Init 0 */
/* USER CODE BEGIN I2C1_Init 1 */
/* USER CODE END I2C1_Init 1 */
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2C1_Init 2 */
/* USER CODE END I2C1_Init 2 */
}
我在STM32F407G和STM32F103 Blue Pill板试过,都出现了同样的问题。
传感器是 Maxim 的 MAX30105。
I2C 通信是否缺少某些导致此类问题的内容?
如果你重新调试,你的MCU会被重置,但你的传感器不会。因此,传感器处于您的 MCU 不期望的状态,并且通信不工作。可能是传感器正在拉低 SDA 并等待更多的时钟周期来完成其传输。
如果您不知道 I2C 通信是如何工作的:SCL 和 SDA 线都上拉到 Vcc。 SCL 只能由主机拉低,但总线上的所有设备都可以拉低 SDA。如果多个设备“不同意”总线状态,一个设备可能会拉低 SDA,而主设备停止切换 SCL。这会杀死总线。
您应该重新启动系统或通过发送 9 个时钟周期清除 I2C 总线。在 9 个时钟周期内,您的传感器的任何待处理传输都应该完成,您可以恢复通信。
我遇到 I2C 通信问题。在第一个 运行 期间,MCU 和传感器之间的通信正常,然后我可以毫无问题地读取和写入传感器的寄存器。
然而,当我第二次尝试调试时,当我尝试与传感器通信时收到 HAL_BUSY,当电路板的电源被切断然后再次供电时,通信才重新建立.
写入寄存器的代码片段如下:
HAL_StatusTypeDef MAX30105_WriteRegister(uint8_t reg_addr, uint8_t reg_value){
HAL_StatusTypeDef returnValue = HAL_ERROR;
//Check if the MAX30105 is ready in a trial of 5 times
HAL_StatusTypeDef result = HAL_I2C_IsDeviceReady(&hi2c1, MAX30105_ADDR, 5, 10);
if (result == HAL_OK) // HAL_ERROR or HAL_BUSY or HAL_TIMEOUT
{
returnValue = HAL_I2C_Mem_Write(&hi2c1, MAX30105_ADDR, reg_addr , 1, ®_value, sizeof(reg_value), 10);
if(returnValue != HAL_OK)
return returnValue;
}
return returnValue;
}
I2C 设置为:
static void MX_I2C1_Init(void)
{
/* USER CODE BEGIN I2C1_Init 0 */
/* USER CODE END I2C1_Init 0 */
/* USER CODE BEGIN I2C1_Init 1 */
/* USER CODE END I2C1_Init 1 */
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2C1_Init 2 */
/* USER CODE END I2C1_Init 2 */
}
我在STM32F407G和STM32F103 Blue Pill板试过,都出现了同样的问题。
传感器是 Maxim 的 MAX30105。
I2C 通信是否缺少某些导致此类问题的内容?
如果你重新调试,你的MCU会被重置,但你的传感器不会。因此,传感器处于您的 MCU 不期望的状态,并且通信不工作。可能是传感器正在拉低 SDA 并等待更多的时钟周期来完成其传输。
如果您不知道 I2C 通信是如何工作的:SCL 和 SDA 线都上拉到 Vcc。 SCL 只能由主机拉低,但总线上的所有设备都可以拉低 SDA。如果多个设备“不同意”总线状态,一个设备可能会拉低 SDA,而主设备停止切换 SCL。这会杀死总线。
您应该重新启动系统或通过发送 9 个时钟周期清除 I2C 总线。在 9 个时钟周期内,您的传感器的任何待处理传输都应该完成,您可以恢复通信。