[英]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 應該只被master 拉低,但是總線上的所有設備都可以拉低SDA。 如果多個設備對總線狀態“不一致”,則一個設備可能會拉低 SDA,而主設備則停止切換 SCL。 這會殺死總線。
您應該重啟系統或通過發送 9 個時鍾周期來清除 I2C 總線。 在 9 個時鍾周期內,傳感器的任何未決傳輸都應該完成,您可以恢復通信。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.