工具/软件:
大家好、我尝试通过 MSP430F5529 与传感器 BH1750FVI 进行通信、但在尝试读取数据时、我遇到了从器件的 NACK 问题。 并获取无效数据。
该传感器的地址引脚连接到 VCC -> 0x5C
另外在 while 循环中我的代码被卡住了:
而不会继续等待下一条消息。
代码如下所示、我还使用 5k Ω 的上拉电阻器和 10kHz 的频率来尝试让其立即正常工作。
#include "driverlib.h"
#include "intrinsics.h"
#include "msp430f5529.h"
#include "msp430f5xx_6xxgeneric.h"
//#include <cstdint>
uint8_t TransmitBuffer;
uint8_t* on = 0x01; // turn on
uint8_t* data = 0x20; // get data
uint8_t Data_In[2] = {0, 0};
int bytes = 0;
typedef enum I2C_ModeEnum{
SENSOR_ACTIVATE,
TX_DATA_MODE
} I2C_Mode;
I2C_Mode MasterMode;
void sensorON(void);
void main (void)
{
WDTCTL = WDTPW | WDTHOLD;
P4DIR |= BIT7;
P1DIR |= BIT0;
UCB1CTL1 |= UCSWRST; // put in SW reset
UCB1CTL1 |= UCSSEL_3;
UCB1BR0 = 100; // fSCL = SMCLK/10 = ~100kHz
UCB1BR1 = 0;
UCB1CTL0 |= UCMODE_3 + UCSYNC; // I2C mode
UCB1CTL0 |= UCMST; // Master mode
UCB1I2CSA = 0x5C; // Slave Address is 5C -> address pin connected to VCC
P4SEL &= ~BIT1;
P4SEL &= ~BIT2;
P4SEL |= BIT1 + BIT2; // PIN 4.1, 4.2 for communication
UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB1IE |= UCNACKIE + UCTXIE + UCRXIE;
// Communication
while (1)
{
sensorON();
// Transmit register Address with WRITE message
MasterMode = TX_DATA_MODE;
UCB1IFG &= ~(UCTXIFG + UCRXIFG); // Clear any pending interrupts
UCB1IE &= ~UCRXIE; // Disable RX interrupt
UCB1IE |= UCTXIE; // Enable TX interrupt
UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
bytes = 2;
__bis_SR_register(LPM0_bits + GIE);
__no_operation();
if (Data_In[0] != 0 | Data_In[1] != 0)
{
P4OUT |= BIT7;
}
}
}
void sensorON(void)
{
// Transmit register Address with WRITE message
UCB1IFG &= ~(UCTXIFG + UCRXIFG); // Clear any pending interrupts
UCB1IE &= ~UCRXIE; // Disable RX interrupt
UCB1IE |= UCTXIE; // Enable TX interrupt
UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
MasterMode = SENSOR_ACTIVATE;
__bis_SR_register(LPM0_bits + GIE);
__no_operation();
}
//-------------------------------------------------------------------------------
//-- ISR
#pragma vector=USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
{
switch(UCB1IV)
{
case USCI_NONE:break; // Vector 0 - no interrupt
case USCI_I2C_UCALIFG:break; // Interrupt Vector: I2C Mode: UCALIFG
case USCI_I2C_UCNACKIFG:
P1OUT |= BIT0;
break; // Interrupt Vector: I2C Mode: UCNACKIFG
case USCI_I2C_UCSTTIFG:break; // Interrupt Vector: I2C Mode: UCSTTIFG
case USCI_I2C_UCSTPIFG:break; // Interrupt Vector: I2C Mode: UCSTPIFG
case USCI_I2C_UCRXIFG:
if (bytes)
{
Data_In[bytes-1] = UCB1RXBUF;
bytes--;
}
if (bytes == 1)
{
UCB1CTL1 |= UCTXSTP;
}
else if (bytes == 0)
{
UCB1IE &= ~UCRXIE;
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
break;
case USCI_I2C_UCTXIFG:
switch (MasterMode)
{
case SENSOR_ACTIVATE:
//UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
UCB1TXBUF = 0x01; // turn on sensor
UCB1CTL1 |= UCTXSTP;
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
//while (!(UCB1IFG & UCSTPIFG)); // Wait until STOP condition interrupt flag is set
//UCB1IFG &= ~UCSTPIFG; // Clear it
break;
case TX_DATA_MODE:
UCB1TXBUF = 0x10; // read command
UCB1IE |= UCRXIE; // Enable RX interrupt
UCB1IE &= ~UCTXIE; // Disable TX interrupt
UCB1CTL1 &= ~UCTR; // Switch to receiver
UCB1CTL1 |= UCTXSTT; // Send repeated start
if (bytes == 1)
{
//Must send stop since this is the N-1 byte
while((UCB1CTL1 & UCTXSTT));
UCB1CTL1 |= UCTXSTP; // Send stop condition
}
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
break;
default:
__no_operation();
break;
}
break;
default:
break;
}
}
我提供了从示波器拍摄的一些照片。




