你好!
我正在开发一个可移植 I2C 库、该库应依赖可在 G2553至 I2041器件上找到的通用标志:我现在仅选择 TX、RX 和 NACK 标志。
然而、这个问题的目的是为了更好地了解 I2C 的运行、而不管所选的 MCU 是什么。 我在 I2C 寄存器和主操作流程图中阅读了三个或四个用户指南、但仍然不清楚应该如何以及何时复位标志。
这是参考方案(eUSCI I2C 模式、来自 SLAU335):
根据这项计划,我得出了以下结论,并编写了一个测试代码。 如果我错了、请告诉我。
- 当我置位 UCTR 时、开始序列(连同从器件地址)被发送。 UCTXIFG 变为1、这意味着我可以在 UCBxTXBUF 中写入数据(TX 标志轮询)
- 如果并且只有在 UCBxTXBUF 中写入了某个内容、从器件才可以 ACK /否定应答地址字节、因此在写入数据后、我必须清除 UCTXIFG、检查 UCNACKIFG、并最终给出停止或启动条件。 因此、一个 ACK/NACK 要求在启动条件之后立即在 TXBUF 中写入一些内容。
- 在 TXBUF 写入之后、只有当我决定是发送另一个字节还是发出启动/停止条件时、UCTXIFG 才会被置位。
- 只有当我执行另一个 TXBUF 写入或一个启动/停止条件时、数据字节后的 ACK/NACK 才会出现。
因此、为了发送多个字节、我编写了此代码、但只能使用一个数据字节:
char I2C_Send (unsigned char Slave_Address、unsigned char ByteNum、unsigned char * TxArrayAddr)
{
unsigned int txBuf_index=0;
UCB0I2CSA =从器件地址; //地址分配
UCB0IFG &=~(UCTXIFG + UCNACKIFG);//标志清零
UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX、启动条件
//UCB0IFG &=~ UCTXIFG; // Azzero UCTXIFG (si alza Solo Dopo l'ack)
while (!(UCB0IFG & UCTXIFG));// while TXIFG = 0
while (txBuf_index <(ByteNum - 1))
{
UCB0IFG &=~ UCTXIFG;// BO
UCB0TXBUF = TxArrayAddr[txBuf_index+];//填充 TxBuffer (从器件 CAN ACK / NACK)
while (!(UCB0IFG & UCTXIFG)) // Mbentre UCTXIFG è 0、
{
IF (UCB0IFG 和 UCNACKIFG) // se evo ricun Nack,ESCO。
{
UCB0CTL1 |= UCTXSTP; //发出停止
返回1;
}
}
IF (UCB0IFG 和 UCNACKIFG) // se evo ricun Nack,ESCO。
{
UCB0CTL1 |= UCTXSTP; //发出停止
返回1;
}
// se è uno (Posso trasmettere anche il sondo 字节)
//UCB0IFG &=~ UCTXIFG; //标志清除
}
UCB0IFG &=~ UCTXIFG;// BO
UCB0TXBUF = TxArrayAddr[txBuf_index++];
while (!(UCB0IFG & UCTXIFG)) // Mbentre UCTXIFG è 0、
{
IF (UCB0IFG 和 UCNACKIFG) // se evo ricun Nack,ESCO。
{
UCB0CTL1 |= UCTXSTP; //发出停止
返回1;
}
}
UCB0CTL1 |= UCTXSTP;
返回0;
}
我缺少什么? 是否明显有问题、我没有抓住它? 在两个字节后、我接收到一个 NACK 、但它将忽略它。
提前感谢您!
