我构建了两个函数、用于使用 eusci i2c 接口读取和写入单个字节。
我找不到任何不使用中断的示例、因此我构建自己的中断。
我使用逻辑分析仪进行了很多调试、但现在它们工作正常。
OID i2c_init(){
P1SEL1 |= BIT6 | BIT7; //配置 I2C 引脚
P1SEL0 &=~(BIT6 | BIT6); //配置 I2C 引脚
// I2C 默认使用 SMCLK
UCB0CTL1 |= UCSWRST; //将 eUSCI_B 置于复位状态
UCB0CTLW0 |= UCMODE_3 | UCMST | UCSYNC;// I2C、主器件、SYNC
UCB0BRW = 0x000A; //波特率= SMCLK / 10 = 100kHz
UCB0CTL1 &=~UCSWRST; // eUSCI_B 处于运行状态
}
void i2c_write (uint8_t SLV_addr、uint8_t reg_addr、uint8_t data){
while (UCB0STAT 和 UCBBUSY);
UCB0I2CSA = SLV_addr; //设置从器件地址
UCB0CTLW0 |= UCTR | UCTXSTT; //发送器模式和启动条件。
while (UCB0CTLW0和 UCTXSTT);
UCB0TXBUF = REG_addr;
while (!(UCB0IFG & UCTXIFG0));
UCB0TXBUF =数据;
while (!(UCB0IFG & UCTXIFG0));
UCB0CTLW0 |= UCTXSTP;
while (UCB0CTLW0和 UCTXSTP); //等待停止
}
uint8_t i2c_read (uint8_t SLV_addr、uint8_t reg_addr){
uint8_t data = 0;
while (UCB0STAT 和 UCBBUSY);
UCB0I2CSA = SLV_addr; //设置从器件地址
UCB0CTLW0 |= UCTR | UCTXSTT; //发送器模式和启动条件。
while (UCB0CTLW0和 UCTXSTT);
UCB0TXBUF = REG_addr;
while (!(UCB0IFG & UCTXIFG0));
UCB0CTLW0 &=~UCTR; //接收器模式
UCB0CTLW0 |= UCTXSTT; //起始条件
while (UCB0CTLW0和 UCTXSTT); //确保已清除启动
UCB0CTLW0 |= UCTXSTP; //停止条件
while (!(UCB0IFG & UCRXIFG0));
数据= UCB0RXBUF;
while (UCB0CTLW0和 UCTXSTP);
返回数据;
}
我发现调试一次读写操作时、所有"指令"都应按照正确的顺序工作、使其稳定。
但是、某些传感器要求您在不使用中间停止的情况下读取多个寄存器。
因为如果您尝试逐字节读取它们、那么在读取第一个字节后、新数据将存储在寄存器中。
根据我的理解:
-停止和重复启动都会自动发送一个 NACK,而不是 ACK
- while (UCB0STAT 和 UCBBUSY);只要总线忙、就等待。 (因此不应使用重复启动来检查此项?)
我应该如何修改我的单个读取函数、以便它能够读取多个字节?
我尝试了一些操作、但应该何时发送重复起始? 在与 STOP 相同的位置?
理想情况下、我希望具有如下函数:
uint8_t i2c_read_multi(uint8_t SLV_addr、uint8_t reg_addr、uint8_t l、uint8_t arr*){}
l 表示要读取的字节数,arr*表示大小为 l 的数组的指针