I2C通信中的问题-STM32(HAL库)



我面临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, &reg_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个时钟周期内,传感器的任何未决传输都应该完成,您可以恢复通信。

最新更新