您好!
我尝试在自己的 PCB 中使用 MSP430G2553 + LDC1614 + MPU6050、但在通过 I2C 通道与 LDC1614通信时遇到了一些问题。
PCB 配置:
拉高电阻10K
P1.6 > I2C SCL
P1.7 > I2C SDA
P2.4 > LDC1614 INTB
P2.5 > LDC1614 SD
LDC1614 ADDR > GND
LDC1614 CLKIN > GND
问题:
当 LDC1614为 I2C 从设备时、最后一个数据包不能发送。
假设有3个字节、代码每次发送一个字节作为数据包。
当第二个信号被成功发送时、IFG2的 UCB0TXIFG 将被清零。
然后、当示波器测量来自 SCL 引脚的信号时、将出现噪声。
2.MPU6050可与 MSP430G2553完美搭配、实现 PCB 中的 I2C 通信。
相同的代码可以很好地用于 Launch Pad (嵌入式 MSP430G2553)和 LDC1614 EVM 板。
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
BCSCTL1 = CALBC1_8MHZ; //20201127 1M -> 8M
DCOCTL = CALDCO_8MHZ;
BCSCTL2 |= DIVS_1; //20201127 SMCLK / 2 = 4MHz
__delay_cycles(10000);
//reset EVM
P2SEL &= ~BIT5;
P2REN |= BIT5;
P2DIR |= BIT5; //P2.5 > SD
P2OUT |= BIT5;
__delay_cycles(480);
P2OUT &= ~BIT5;
I2C_init();
EVM_init();
MPU_init();
for(;;)
{
sensor_mode();
MPU_read();
}
}
void MPU_init()
{
UCB0CTL1 |= UCSWRST; //20210927
UCB0I2CSA = 0x68;
UCB0CTL1 &= ~UCSWRST; //20210927
TX_Data[1] = 0x6B;
TX_Data[0] = 0x00;
TX_ByteCtr = 2;
I2C_TX_DATA();
}
void MPU_read()
{
UCB0CTL1 |= UCSWRST; //20210927
UCB0I2CSA = 0x68;
UCB0CTL1 &= ~UCSWRST; //20210927
TX_Data[0] = 0x3B;
TX_ByteCtr = 1;
I2C_TX_DATA();
RX_ByteCtr = 6;
I2C_RX_DATA();
xAccel = RX_Data[5] << 8 | RX_Data[4];
yAccel = RX_Data[3] << 8 | RX_Data[2];
zAccel = RX_Data[1] << 8 | RX_Data[0];
__no_operation();
__delay_cycles(600000);
}
void EVM_init()
{
//LDC1614 INTB setup
EVM_INT_DIR &= ~EVM_INT_BIT; // INPUT
EVM_INT_IE |= EVM_INT_BIT; // interrupt enabled
EVM_INT_IES |= EVM_INT_BIT; // Hi->Lo Edge
EVM_INT_IFG &= ~EVM_INT_BIT; // Clear IFG
Transmit(0x1C,0x8000); //LDC13xx16xx_CMD_RESET_DEVICE
Transmit(0x08,0xFFFF); //LDC13xx16xx_CMD_REF_COUNT_CH0
Transmit(0x0C,0x0000); //LDC13xx16xx_CMD_OFFSET_CH0
Transmit(0x10,0x044c); //LDC13xx16xx_CMD_SETTLE_COUNT_CH0
Transmit(0x14,0x1001); //LDC13xx16xx_CMD_CLOCK_DIVIDERS_CH0
Transmit(0x1E,0x8c40); //LDC13xx16xx_CMD_DRIVE_CURRENT_CH0
Transmit(0x1A,0x1d01); //LDC13xx16xx_CMD_CONFIG
Transmit(0x1B,0x020C); //LDC13xx16xx_CMD_MUX_CONFIG
Transmit(0x19,0x0001); //LDC13xx16xx_CMD_ERROR_CONFIG
}
void sensor_mode()
{
EVM_INT_IE |= EVM_INT_BIT;
EVM_read();
}
void EVM_read()
{
static unsigned int evmStatus;
if(dataReady == 0)
{
if(evmStatus & 0x0048)
{
dataReady=1;
}
}
if(dataReady==1)
{
Receive(LDC13xx16xx_CMD_STATUS,&evmStatus);
Receive(LDC13xx16xx_CMD_DATA_MSB_CH0,&allData[0]);
Receive(LDC13xx16xx_CMD_DATA_LSB_CH0,&allData[1]);
uHcal(allData[0],allData[1]);
dataReady=0;
}
}
void Transmit(unsigned char code, unsigned int data)
{
__disable_interrupt();
UCB0CTL1 |= UCSWRST; //20210927
UCB0I2CSA = 0x2A;
UCB0CTL1 &= ~UCSWRST;
TX_Data[2] = code;
TX_Data[1] = (data >> 8) & 0xFF;
TX_Data[0] = data & 0xFF;
TX_ByteCtr = 3;
done = FALSE;
I2C_TX_DATA();
}
void Receive(unsigned char code, unsigned int* data)
{
UCB0CTL1 |= UCSWRST; //20210927
UCB0I2CSA = 0x2A;
UCB0CTL1 &= ~UCSWRST;
TX_Data[0] = code;
I2C_TX_DATA();
RX_ByteCtr = 2;
I2C_RX_DATA();
}
void I2C_TX_DATA()
{
__disable_interrupt();
IE2 |= UCB0TXIE;
while (UCB0CTL1 & UCTXSTP);
UCB0CTL1 |= UCTR + UCTXSTT;
if(UCB0I2CSA == 0x2A)
{
__bis_SR_register(GIE);
__no_operation();
}
else
{
__bis_SR_register(CPUOFF + GIE);
__no_operation();
}
}
void I2C_RX_DATA()
{
__disable_interrupt();
IE2 |= UCB0RXIE;
while (UCB0CTL1 & UCTXSTP);
UCB0CTL1 &= ~UCTR;
UCB0CTL1 |= UCTXSTT;
__bis_SR_register(CPUOFF + GIE);
__no_operation();
IE2 &= ~UCB0RXIE;
}
// USCIAB0TX_ISR
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
if(UCB0CTL1 & UCTR) // TX mode (UCTR == 1)
{
if (TX_ByteCtr) // TRUE if more bytes remain
{
TX_ByteCtr--; // Decrement TX byte counter
UCB0TXBUF = TX_Data[TX_ByteCtr]; // Load TX buffer
}
else // no more bytes to send
{
UCB0CTL1 |= UCTXSTP; // I2C stop condition
IFG2 &= ~UCB0TXIFG; // Clear USCI_B0 TX int flag
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
}
else // (UCTR == 0) // RX mode
{
if (--RX_ByteCtr) // RxByteCtr != 0
{
RX_Data[RX_ByteCtr] = UCB0RXBUF; // Get received byte
if (RX_ByteCtr == 1) // Only one byte left?
{
UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition
}
}
else // RxByteCtr == 0
{
RX_Data[RX_ByteCtr] = UCB0RXBUF; // Get final received byte
IFG2 &= ~UCB0RXIFG;
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
}
}