[STM32H5] STM32H5通过 I3C 访问 IKS4A1 传感器

[复制链接]
10|0
codekid 发表于 2026-9-20 13:33 | 显示全部楼层 |阅读模式

我调试 I3C 相关代码,但是读取操作一直失败;读到的缓冲区全部都是 255,同时读出的温度值显示为 350 摄氏度。现在已经有点束手无策了。

奇怪的是,我自己写的几项状态检测是可以正常执行的;看起来从机地址分配这一步是成功的。如果我不插上传感器扩展板运行代码,这些检测逻辑就会导致死机。

这份代码是我参考两份 I3C 示例整合出来的。针对 H503‑Nucleo 开发板,ST 并没有提供 IKS4A1 的配套例程;
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* MPU Configuration--------------------------------------------------------*/
  MPU_Config();

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I3C1_Init();
  MX_ICACHE_Init();
  /* USER CODE BEGIN 2 */
  if (HAL_I3C_Ctrl_DynAddrAssign_IT(&hi3c1, I3C_RSTDAA_THEN_ENTDAA) != HAL_OK)
  {
    Error_Handler();
  }


  // new for finding
  while (HAL_I3C_GetState(&hi3c1) != HAL_I3C_STATE_READY) { }
  while (HAL_I3C_Ctrl_IsDeviceI3C_Ready(&hi3c1, 0x32, 300, 1000) != HAL_OK) {  }




  aContextBuffers[I3C_IDX_FRAME_1].CtrlBuf.pBuffer = aControlBuffer;
  aContextBuffers[I3C_IDX_FRAME_1].CtrlBuf.Size    = 1;
  aContextBuffers[I3C_IDX_FRAME_1].TxBuf.pBuffer   = aTxBuffer;
  aContextBuffers[I3C_IDX_FRAME_1].TxBuf.Size      = LSM6DSV16XCONFIGSIZE;


  /*##- Add context buffer transmit in Frame context #####################*/
  if (HAL_I3C_AddDescToFrame(&hi3c1,
                             NULL,
                             &aPrivateDescriptorConfig[I3C_IDX_FRAME_1],
                             &aContextBuffers[I3C_IDX_FRAME_1],
                             aContextBuffers[I3C_IDX_FRAME_1].CtrlBuf.Size,
                             I3C_PRIVATE_WITH_ARB_STOP) != HAL_OK)
  {
    Error_Handler();
  }


  if (HAL_I3C_Ctrl_Transmit_IT(&hi3c1, &aContextBuffers[I3C_IDX_FRAME_1]) != HAL_OK)
  {
    Error_Handler();
  }
  while (HAL_I3C_GetState(&hi3c1) != HAL_I3C_STATE_READY)
  {
  }


  /* USER CODE END 2 */

  /* Initialize led */
  BSP_LED_Init(LED_GREEN);

  /* Initialize USER push-button, will be used to trigger an interrupt each time it's pressed.*/
  BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);

  /* Initialize COM1 port (115200, 8 bits (7-bit data + 1 stop bit), no parity */
  BspCOMInit.BaudRate   = 115200;
  BspCOMInit.WordLength = COM_WORDLENGTH_8B;
  BspCOMInit.StopBits   = COM_STOPBITS_1;
  BspCOMInit.Parity     = COM_PARITY_NONE;
  BspCOMInit.HwFlowCtl  = COM_HWCONTROL_NONE;
  if (BSP_COM_Init(COM1, &BspCOMInit) != BSP_ERROR_NONE)
  {
    Error_Handler();
  }

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */




            aContextBuffers[I3C_IDX_FRAME_1].CtrlBuf.pBuffer = aControlBuffer;
            aContextBuffers[I3C_IDX_FRAME_1].CtrlBuf.Size    = 2;
            aContextBuffers[I3C_IDX_FRAME_1].TxBuf.pBuffer   = aTxBuffer;
            aContextBuffers[I3C_IDX_FRAME_1].TxBuf.Size      = LSM6DSV16XDATASIZE;
            aContextBuffers[I3C_IDX_FRAME_1].RxBuf.pBuffer   = aRxBuffer;
            aContextBuffers[I3C_IDX_FRAME_1].RxBuf.Size      = RXBUFFERSIZE;

            if (HAL_I3C_AddDescToFrame(&hi3c1,
                                       NULL,
                                       &aPrivateDescriptor[I3C_IDX_FRAME_1],
                                       &aContextBuffers[I3C_IDX_FRAME_1],
                                       aContextBuffers[I3C_IDX_FRAME_1].CtrlBuf.Size,
                                       I3C_PRIVATE_WITH_ARB_RESTART) != HAL_OK)
            {
              Error_Handler();
            }

            if (HAL_I3C_Ctrl_MultipleTransfer_IT(&hi3c1, &aContextBuffers[I3C_IDX_FRAME_1]) != HAL_OK)
            {
              Error_Handler();
            }

            while (HAL_I3C_GetState(&hi3c1) != HAL_I3C_STATE_READY)    {   }


                #define TEMP_OFFSET 25 /* Temperature offset is 25 degree celsius, mean Temperature value 0 correspond to 25 Celsius degree */

            int16_t Temperature       = 0;
            Temperature = TEMP_OFFSET + (((int16_t)(((int16_t)aRxBuffer[1] * 256) + (int16_t)aRxBuffer[0])) / 100);

            printf("\n\r----------------LSM6DSV16X Measurement----------------\n\r");
            printf("Temperature (Celsius degree): %d \n\r", Temperature);



  }
  /* USER CODE END 3 */
}

您需要登录后才可以回帖 登录 | 注册

本版积分规则

54

主题

759

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部
0