主题中讨论的其他器件:TMP101、 C2000WARE
工具与软件:
我正在从 CM 访问 I2C 温度器件(TMP101)。CM 在总线上设置为 I2C 主器件。 它仅配置 I2C 从器件、然后每秒读取一次温度数据。
在查看逻辑分析仪上的流量时、看到的流量与预期完全相同、器件将返回正确的数据。 这表明总线事务是正确的(器件正确 ACK)。 但在 CM 固件中、从 I2CMDR 寄存器读取2个字节的数据时经常会收到重复的值。 我不使用中断或 FIFO 机制、而只是做后台轮询循环。 我注意到最后一个有效值保留在 MDR 寄存器中、因此在错误的时间读取寄存器(或如果它未按预期更新)会导致值重复。
我遵循了 TRM 中记录的流程图。 是否有如何使用这些 API 的示例? MDR 中的数据何时有效且就绪、固件如何指示? C2000Ware 示例区域中唯一不适用的图形。
void i2cTemperaturePoll(uint32_t i2cInstance) { if(I2C_isMasterBusy(TEMPERATURE_I2C_BASE)) { return; }; // Set I2C target address // FC: write slave address to I2CMSA I2C_setSlaveAddress(TEMPERATURE_I2C_BASE, i2cAddresses[i2cInstance], I2C_MASTER_READ); // FC: Check busy (may be omitted in single master system) while(I2C_isBusBusy(TEMPERATURE_I2C_BASE)); // Start transaction // FC: write xxx0_1011 to I2CMCS I2C_setMasterConfig(TEMPERATURE_I2C_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START); for (int i = 0; i < TEMPERATURE_I2C_DATA_BYTES; i++) { // FC: read I2CMCS while(I2C_isMasterBusy(TEMPERATURE_I2C_BASE)); // FC: ERROR bit == 0? i2cBusStatus[i2cInstance] |= I2C_getMasterErr(TEMPERATURE_I2C_BASE); // Grab read first data byte // FC: Read data from I2CMDR rawData[i] = I2C_getMasterData(TEMPERATURE_I2C_BASE); if (i < TEMPERATURE_I2C_DATA_BYTES - 1) { // Continue transaction and STOP // FC: write xxx0_1001 to I2CMCS I2C_setMasterConfig(TEMPERATURE_I2C_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT); } else { // FC: last byte // FC: write xxx0_1101 to I2CMCS I2C_setMasterConfig(TEMPERATURE_I2C_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH_ACK); } } // FC: Check busy while(I2C_isMasterBusy(TEMPERATURE_I2C_BASE)); // FC: ERROR bit == 0? i2cBusStatus[i2cInstance] |= I2C_getMasterErr(TEMPERATURE_I2C_BASE); }
我编辑了 CM I2C API 来定义配置类型 I2C_MASTER_CMD_BURST_RECEIVE_FINE_ACK。 此类型定义为:
//! BURST RECEIVE FINISH I2C_MASTER_CMD_BURST_RECEIVE_FINISH = 0x00000005U, //! BURST RECEIVE FINISH WITH ACK I2C_MASTER_CMD_BURST_RECEIVE_FINISH_ACK = 0x0000000dU,
此配置会确认来自器件的数据。 它并非100%必要、但与预期的总线事务相匹配。
谢谢!