ST意法半导体
直播中

吕钢格

9年用户 1075经验值
私信 关注
[问答]

请问STM32MP135 I2C MemAddress最多两个字节吗?

MP135的I2C底层读写函数里面对于MemAddress做了限制, 最多两个字节的MemAddress, 这是MP135的硬件限制 还是 单纯的在功能的实现上做了限制?
我现在对接的设备 他必须要三字节的MemAddress,怎么办呢

回帖(2)

彭铮

2025-3-14 14:51:12
在I2C通信中,通常使用7位或10位地址来标识设备,而MemAddress通常是8位或16位,这取决于设备的规格。如果需要处理超过16位的MemAddress,这通常意味着需要使用I2C扩展模式,或者通过多次读写操作来实现。
举报

艾玛

2025-3-21 17:53:39

针对STM32MP135的I2C接口MemAddress限制及三字节地址需求的解决方案如下:




1. 确认硬件限制



  • 查阅参考手册:首先检查STM32MP135的I2C控制器硬件能力。根据STM32系列的设计,其I2C外设通常支持多字节地址传输,但具体实现可能依赖以下配置:

    • I2C 协议规范:I2C标准未限制地址字节数,但主控制器可能对单次传输的数据长度有硬件限制(如STM32的I2C_CR2寄存器中的NBYTES字段)。

    • MemAddress 传输模式:STM32的I2C模块支持 MEM_ADD_SIZE 配置(1或2字节),但若设备需要3字节地址,需通过软件扩展。





2. 软件层面的限制与驱动修改


若确认硬件支持灵活的数据长度,但驱动库(如HAL库)限制了MemAddress为2字节,可采取以下步骤:


修改驱动函数



  • 调整地址参数
    修改底层读写函数(如HAL_I2C_Mem_Read/Write),将MemAddSize参数扩展为支持3字节,并调整传输逻辑:
    // 示例:修改HAL库的MemAddress处理逻辑
    HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) {
      // 支持3字节地址
      if (MemAddSize == I2C_MEMADD_SIZE_8BIT) {
          // 1字节地址处理
      } else if (MemAddSize == I2C_MEMADD_SIZE_16BIT) {
          // 2字节地址处理
      } else if (MemAddSize == I2C_MEMADD_SIZE_24BIT) { // 自定义扩展
          // 发送3字节地址
          uint8_t addrBytes[3];
          addrBytes[0] = (MemAddress >> 16) & 0xFF;
          addrBytes[1] = (MemAddress >> 8) & 0xFF;
          addrBytes[2] = MemAddress & 0xFF;
          HAL_I2C_Master_Transmit(hi2c, DevAddress, addrBytes, 3, Timeout);
      }
      // 发送数据...
    }


使用底层API组合传输




  • 手动拆分地址
    若库函数无法修改,可通过HAL_I2C_Master_TransmitHAL_I2C_Master_Receive手动发送地址和数据:


    // 发送三字节地址 + 数据(写操作)
    uint8_t addrData[4];
    addrData[0] = (MemAddress >> 16) & 0xFF;  // 高字节
    addrData[1] = (MemAddress >> 8) & 0xFF;
    addrData[2] = MemAddress & 0xFF;
    addrData[3] = dataToWrite;

    HAL_I2C_Master_Transmit(&hi2c1, DevAddress, addrData, 4, timeout);





3. 硬件限制的替代方案


若硬件I2C控制器确实不支持3字节地址传输(需参考手册验证),可尝试以下方法:


分步传输地址



  • 使用重复起始条件(Repeated Start)

    1. 发送写操作,传输前两个地址字节。

    2. 发送重复起始条件(Repeated Start)。

    3. 发送第三个地址字节并读取/写入数据。
      // 伪代码示例
      HAL_I2C_Mem_Write(&hi2c1, DevAddr, MemAddrHigh, 2, timeout); // 发送高2字节
      HAL_I2C_Mem_Read(&hi2c1, DevAddr, MemAddrLow, 1, pData, Size, timeout); // 发送第3字节并读取



软件模拟I2C(Bit-banging)



  • GPIO模拟时序
    若硬件限制无法绕过,可通过GPIO引脚手动控制SCL/SDA信号,完全自主实现3字节地址传输:
    void I2C_Write_3ByteAddr(uint8_t devAddr, uint32_t memAddr, uint8_t data) {
      i2c_start();
      i2c_send_byte(devAddr << 1 | I2C_WRITE);
      i2c_send_byte((memAddr >> 16) & 0xFF);
      i2c_send_byte((memAddr >> 8) & 0xFF);
      i2c_send_byte(memAddr & 0xFF);
      i2c_send_byte(data);
      i2c_stop();
    }




4. 与设备厂商沟通



  • 确认设备协议细节:联系设备厂商,确认是否支持以下特性:

    • 地址分页(Paging):通过命令字切换地址页,减少实际需要的地址长度。

    • 扩展指令集:如使用特定指令(如0xXX)后跟3字节地址。





总结



  • 硬件可能性大:STM32MP135的I2C控制器通常支持灵活的数据传输,3字节地址限制更可能是软件库或驱动实现的问题。

  • 推荐方案:修改驱动或使用底层API组合传输,优先尝试软件扩展。若验证为硬件限制,再考虑分步传输或Bit-banging。

  • 测试验证:修改后需通过逻辑分析仪或示波器抓取I2C波形,确认地址和数据正确性。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分