STM32 I2C HAL FXOS8700通信问题

STM32 I2C HAL FXOS8700 communication problem

我有一个通过 I2C2 端口连接到 fxos8700cq 传感器的 STM32F103RE MCU。 我已经使用 stm32cubemx 设置了外围设备,我正在尝试简单地测试与传感器的通信。但是当我调试代码时,数据传输似乎没有正确发生。

这些是 i2c 设置:

 hi2c2.Instance = I2C2;
  hi2c2.Init.ClockSpeed = 100000;
  hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c2.Init.OwnAddress1 = 0;
  hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c2.Init.OwnAddress2 = 0;
  hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;

这里是主要代码:

 uint8_t send_buffer[1];
    uint8_t receive_buffer[1];
    uint8_t FXOS_ADDR = (FXOS8700_DEVICE_ADDR_SA_11 << 1);
    
    send_buffer[0] = FXOS8700_WHO_AM_I;
    receive_buffer[0] = 0;
    // chip select for fxos
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_SET);
    HAL_Delay(500);
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET);
    HAL_Delay(500);
    
    ret = HAL_I2C_Master_Transmit(&hi2c2, FXOS_ADDR, send_buffer, 1, 100);
    //ret = HAL_I2C_Master_Transmit_IT(&hi2c2, FXOS_ADDR, send_buffer, 1);
    HAL_Delay(2);
    ret = HAL_I2C_Master_Receive(&hi2c2, FXOS_ADDR, receive_buffer, 1, 100);
    //ret = HAL_I2C_Master_Receive_IT(&hi2c2, FXOS_ADDR, receive_buffer, 1);
    
    if (receive_buffer[0] == FXOS8700_WHO_AM_I_PROD_VALUE)
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
     else
         HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);

但是在我调试代码并在执行 HAL_I2C_Master_Transmit(&hi2c2, FXOS_ADDR, send_buffer, 1, 100); 函数后观察 i2c 寄存器后,我得到 these values。这意味着 SR1 寄存器中的 TXE 位未设置。

我也尝试过使用中断模式,但那也不起作用。 ret = HAL_I2C_Master_Transmit_IT(&hi2c2, FXOS_ADDR, send_buffer, 1); 行之后的 i2c 寄存器值类似于 this.

在所有情况下函数 return HAL_OK 并且没有错误。

我已经使用 mbed 测试了传感器和电路板通信,它工作正常。所以硬件没有问题。

使用设备的 I2C 接口时,您不需要切换芯片 select。 设备的芯片select信号只针对SPI接口。 您应该将 SA0 和 SA1 引脚拉高或拉低以使用 I2C 接口和 select 设备的 I2C 地址。请参阅数据表中的 table 11 和第 10.2.3 节。

HAL_I2C_Master_Transmit() 和 HAL_I2C_Master_Receive() 不是从设备读取寄存器值的最佳函数。这些函数传输开始条件、设备地址、数据,最后是停止条件。但这不是 FXOS8700CQ datasheet 在第 10.1.2 节“Single-byte 阅读”中推荐的内容。它表示传输开始条件,带 W 位的设备地址,寄存器地址,repeat-start 条件(注意重复开始前没有停止),带 R 位的设备地址,然后是数据,最后是停止条件。

HAL_I2C_Mem_Read() 函数可用于执行 single-byte 读取,如数据表中所述。 (即写入寄存器地址,repeat-start,读取数据。)尝试这样的事情。

uint8_t data_byte = 0;
HAL_StatusTypeDef hal_status = HAL_I2C_Mem_Read(&hi2c2, FXOS_ADDR, FXOS8700_WHO_AM_I, I2C_MEMADD_SIZE_8BIT, &data_byte, 1, 100);

如果这没有帮助,请检查 HAL 库调用中的 return 值。

如果这没有帮助,则使用逻辑分析仪或示波器检查 I2C 时钟和数据信号。