有人知道 TI-RTOS 中的 I2C 驱动程序库是否与需要重复启动条件的芯片配合使用? 我尝试与一个 RTC 芯片通信、但它需要重复启动条件。
此致、
Bob Starr
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
有人知道 TI-RTOS 中的 I2C 驱动程序库是否与需要重复启动条件的芯片配合使用? 我尝试与一个 RTC 芯片通信、但它需要重复启动条件。
此致、
Bob Starr
我相信答案是肯定的。 Tiva TI-RTOS I2C 驱动程序源位于以下文件中: C:\ti_tirtos_tivac_2_16_00_08\products\tidrivers_tivac_2_16_00_08\packages/ti\drivers\i2c\I2CTiva.c
如果写入后需要读取、处理程序会调用函数 I2CTiva_hwiFxn()来发送停止条件或附加的启动条件。 查看210到321行:
案例 I2CTiva_write_mode: /*减量写入计数器*/ object->writeCountIdx-; /*检查是否需要发送更多数据*/ if (object->writeCountIdx){ Log_print3 (Diags_User2、 "I2C:(%p) ISR I2CTiva_write_mode:要写入的数据:" "0x%x;到从器件:0x%x"、 hwAttrs->baseAddr, *(object->writeBufIdx)、 object->currentTransaction->slaveAddress); /*将数据内容写入数据寄存器*/ I2CMasterDataPuthwAttrs->baseAddr、*(object->writeBufIdx); object->writeBufIdx++; if ((object->writeCountIdx < 2)&&!(object->readCountIdx)){ //所有内容都已发送,没有要接收的内容*/ /*下一状态:空闲模式*/ object->mode = I2CTiva_idle_mode; /*发送带停止位的最后一个字节*/ I2CMasterControlhwAttrs->baseAddr、 I2C_MASTER_CMD_BURST_SEND_FINISH); Log_Print1 (Diags_User2、 "I2C:(%p) ISR I2CTiva_write_mode:ACK received;" "写入带停止位"、 hwAttrs->baseAddr); } 否则{ /* *有更多的发送日期或某些日期 *接下来需要接收数据 * I2CMasterControlhwAttrs->baseAddr、 I2C_MASTER_CMD_BURST_SEND_CONT); Log_Print1 (Diags_User2、 "I2C:(%p) ISR I2CTiva_write_mode:ACK received;" "写入"、 hwAttrs->baseAddr); } } /*此时,我们知道我们需要接收数据*/ 否则{ /* *我们需要在传输完数据后进行检查,如果 *我们需要接收任何数据。 *在临界情况下、当我们仅传输一个字节时 *且没有要接收的数据、I2C 将自动发送 *停止位。 换言之、我们只需要检查一下 *是否需要接收数据。 如果是、则为多少。 * if (object->readCountIdx){ /*下一状态:接收模式*/ object->mode = I2CTiva_read_mode; /*切换到接收模式*/ I2CMasterSlaveAddrSet (hwAttrs->baseAddr、 object->currentTransaction ->slaveAddress、 true); if (object->readCountIdx >1){ /*发送重复开始*/ I2CMasterControlhwAttrs->baseAddr、 I2C_MASTER_CMD_BURST_Receive_start); Log_Print1 (Diags_User2、 "I2C:(%p) ISR I2CTiva_write_mode:->" "I2CTIVA_READ_MODE;通过重新启动和 ACK 进行读取"、 hwAttrs->baseAddr); } 否则{ /* *发送带有 NACK 的重复起始值、因为它是 *要接收的最后一个字节。 * I2C_MASTER_CMD_BURST_Receive_START_NACK 为 *是局部定义的、因为没有宏 *在发送后接收数据并发送 NACK *起始位(0x00000003) * I2CMasterControlhwAttrs->baseAddr、 I2C_MASTER_CMD_BURST_Receive_START_NACK); Log_Print1 (Diags_User2、 "I2C:(%p) ISR I2CTiva_write_mode:->" "I2CTIVA_READ_MODE;通过重新启动和 NACK 读取数据"、 hwAttrs->baseAddr); } } 否则{ /*完成所有传输*/ object->mode = I2CTiva_idle_mode; /* *无需再接收数据、因此请继续执行 *停止位 *同样、没有等效宏(0x00000004) *使用 I2C_MASTER_CMD_BURST_Receive_stop。 * I2CMasterControlhwAttrs->baseAddr、 I2C_MASTER_CMD_BURST_Receive_STOP); Log_Print1 (Diags_User2、 "I2C:(%p) ISR I2CTiva_write_mode:->" "I2CTIVA_IDLE_MODE;发送停止位"、 hwAttrs->baseAddr); } } 中断;
非常感谢您的回复、我不是 I2C 专家、使用此总线的经验有限。 是的、它看起来应该支持重复启动条件。 我很难理解如何从 RTC 时钟芯片和 RTC 器件的新功能中进行简单的寄存器读取。 我正在尝试从 MCP79410器件读取单个寄存器以检查运行状态。
我正在尝试写入命令字节并读回一个字节。 我不知道在写入读取寄存器命令和回读结果字节之间是否存在停止/启动条件。 似乎部件希望在写入/读取操作之间重复启动。 驱动程序中断在下面的部分给出了一个错误。
/*发生了某种错误! * object->mode = I2CTiva_error; if (errStatus &(I2C_MASTER_ERR_ARB_Lost | I2C_MASTER_ERR_ADDR_ACK){ I2CTiva_completeTransfer ((I2C_Handle)参数); }
#define RTCC 写入 0xDE // RTCC MCHP 的设备 ADDR (写入) #define RTCC 读取 0xDF // RTCC MCHP 的设备 ADDR (读取)
uint8_t MCP79410_read (MCP79410_Handle handle、uint8_t RCCD_reg)
{
//IArg 键;
I2C_Transaction i2cTransaction;
uint8_t txBuffer[2];
uint8_t rxBuffer[2];
txBuffer[0]= RTCC_reg;
/*用地址*/写入虚拟字节
i2cTransaction.slaveAddress = RTCC 写入;
i2cTransaction.writeBuf =&txBuffer;
i2cTransaction.writeCount = 1;
i2cTransaction.readBuf =&rxBuffer;
i2cTransaction.ReadCount = 0;
if (!I2C_transfer (handle->i2cHandle、&i2cTransaction))
{
system_printf ("unsuccessful I2C transfer\n");
system_flush();
}
txBuffer[0]= RTCC_reg;
/*初始化主 SPI 事务结构*/
i2cTransaction.slaveAddress = RTCC 读取;
i2cTransaction.writeBuf =&txBuffer;
i2cTransaction.writeCount = 0;
i2cTransaction.readBuf =&rxBuffer;
i2cTransaction.ReadCount = 1;
if (!I2C_transfer (handle->i2cHandle、&i2cTransaction))
{
system_printf ("unsuccessful I2C transfer\n");
system_flush();
}
返回 rxBuffer[0];
}
还使用"链接读取"运行了另一个示例、但迄今为止也不能成功执行此操作。
bool transferDone = false;
void I2C3writeCallback (I2C_Handle handle、I2C_Transaction *事务、bool 结果)
{
//设置长度字节
if (结果){
transferDone =真;
} 否则{
//事务失败,相应地执行...
system_printf ("unsuccessful I2C transfer\n");
system_flush();
}
}
uint8_t MCP79410_read (MCP79410_handle、uint8_t regadd)
{
I2C_Transaction i2cTrans1;
I2C_Transaction i2cTrans2;
uint8_t txBuffer1[2];
uint8_t rxBuffer1[2];
uint8_t txBuffer2[2];
uint8_t rxBuffer2[2];
txBuffer1[0]= regadd;
//初始化第一个主 I2C 事务结构
i2cTrans1.slaveAddress = RTCC 写入; // 0xDE
i2cTrans1.writeCount = 1;
i2cTrans1.writeBuf = txBuffer1;
i2cTrans1.ReadCount = 0;
i2cTrans1.readBuf = rxBuffer1;
txBuffer2[0]= regadd;
//第二次交易
i2cTrans2.slaveAddress = RTCC 读取; // 0xDF
i2cTrans2.writeCount = 0;
i2cTrans2.writeBuf = txBuffer2;
i2cTrans2.ReadCount = 1;
i2cTrans2.readBuf = rxBuffer2;
//执行链接 I2C 传输(在回调模式下)。
i2C_transfer (handle->i2cHandle、&i2cTrans1);
i2C_transfer (handle->i2cHandle、&i2cTrans2);
//在 I2C 处理传输时执行其他操作
//如果 I2C 传输完成,请执行一些操作
Task_sleep (1000);
if (转让人){
}
//继续...
返回 rxBuffer2[0];
}
尊敬的 Bob:
非常感谢!! 最后、让这个烦人的部件正常工作! 我的 GOof、我按照以下内容更改了地址宏。
#define RTCC 写入(0xDE >> 1)// RTCC MCHP 的设备 ADDR (写入)
#define RTCC 读取(0xDF >> 1)// RTCC MCHP 的设备 ADDR (读取)
最初、我编写和读取了一个字节的代码、但无法理解为什么它不起作用。
由于我自己的监督、我忘记了解决位移问题的所有事情。 非常感谢您的帮助!
此致、