我尝试通过 I2C 从温度传感器读取数据。 我设法启动并运行了通信、但我发现了一些奇怪的行为。
我无法正确计时 STOP 标志、结果是我读取了大量数据。
我的问题是,如何在第二个帧上发出停止标志,而不会因我 遇到的延迟而在第四个帧上发出停止信号?
上图显示了停止标志计时问题。 请注意、DIO2信号是在 STP 标志有效时发出的。 然后、在新的 I2C 事务开始时、我将 DIO2信号设置为零。
为了清楚、我希望 I2C 结构如下所示:
| S |地址| R | A |数据| A |数据| NAK | P |
我要得到的结果:
| S |地址| R | A |数据| A |数据| A |不需要的数据| A |不需要的 数据| NAK | P |
代码:
#include
#include
unsigned char RXData;
unsigned char TXData;
uint8_t RXByteCtr = 0;
uint8_t TXByteCtr = 0;
空 I2CInit (空)
{
P3REN |= 0x03;
P3OUT |= 0x03;
P3SEL |= 0x03;//将 I2C 引脚分配给 USCI_B0
UCB0CTL1 |= UCSWRST;//启用 SW 复位
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;// I2C 主器件、同步模式
UCB0CTL1 = UCSSEL_2 + UCSWRST;//使用 SMCLK、保持软件复位
UCB0BR0 = 10;// fSCL = SMCLK/10 = 100kHz
UCB0BR1 = 0;
UCB0I2CSA = 0x48;//从器件地址为048h
UCB0CTL1 &=~UCSWRST;//清除 SW 复位,恢复运行
}
空 I2CWriteInit (空)
{
UCB0CTL1 |= UCTR;
UCB0IFG &=~ UCTXIFG;
UCB0IE &=~ UCRXIE;
UCB0IE |= UCTXIE;
}
空 I2CReadInit (空)
{
UCB0CTL1 &=~ UCTR;
UCB0IFG &=~ UCRXIFG;
UCB0IE &=~ UCTXIE;
UCB0IE |= UCRXIE;
}
空 ReadTemp (空)
{
while (UCB0STAT 和 UCBBUSY);
P1OUT &=~BIT6;
RXByteCtr = 2;
I2CReadInit();
UCB0CTL1 |= UCTXSTT;
}
空 SetRegPtr (空)
{
while (UCB0STAT 和 UCBBUSY);
TXByteCtr = 1;
TXData = 0x00;
I2CWriteInit();
UCB0CTL1 |= UCTXSTT;
}
int main (空)
{
WDTCTL = WDTPW + WDTHOLD;
I2CInit();
P1DIR |= BIT6;
P1OUT &=~BIT6;
_enable_interrupt ();
SetRegPtr ();
while (1)
{
ReadTemp();
}
}
#pragma vector = USCI_B0_vector
_interrupt void USCI_B0_ISR (void)
{
switch (__evo_in_range (UCB0IV、12))
{
案例10:
IF (RXByteCtr -)
{
RXData = UCB0RXBUF;
}
其他
{
UCB0CTL1 |= UCTXSTP;
P1OUT |= BIT6;
}
中断;
情况12:
IF (TXByteCtr)
{
UCB0TXBUF = TXData;
TXByteCtr --;
}
其他
{
UCB0CTL1 |= UCTXSTP;
UCB0IFG &=~UCTXIFG;
}
中断;
默认值:break;
}
}