This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

EUSCI I2C如何发送RESTART?



代码:

#include <msp430.h>

volatile unsigned char ADXL345_Ptr;
volatile unsigned char RxBuffer;

int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop WDT

// Setup P2.0 UCB0SCL, P2.1 UCB0SDA
P2SEL |= BIT0 | BIT1; // Set P2.0,P2.1 to UCB0SCL, UCB0SDA

// Setup eUSCI_B0
UCB0CTLW0 |= UCSWRST; // Enable SW reset
UCB0CTLW0 |= UCMST | UCMODE_3 | UCSSEL_2; // I2C Master, use SMCLK

UCB0BRW_L = 12; // fSCL = SMCLK/12 = ~100kHz
UCB0BRW_H = 0;
UCB0I2CSA = 0x53; // Slave Address is 048h
UCB0CTLW0 &= ~UCSWRST; // Clear SW reset, resume operation
UCB0IE |= UCTXIE0; // Enable TX interrupt

ADXL345_Ptr = 1;
while (1)
{


while (UCB0CTLW0 & UCTXSTP) ; // Ensure stop condition got sent
UCB0CTLW0 |= UCTR | UCTXSTT; // I2C TX, start condition

__bis_SR_register(LPM0_bits | GIE); // Enter LPM0 w/ interrupts
__no_operation(); // Remain in LPM0 until all data
// is TX'd

}
}

//------------------------------------------------------------------------------
// The USCIAB0_ISR is structured such that it can be used to transmit any
// number of bytes by pre-loading TXByteCtr with the byte count.
//------------------------------------------------------------------------------
// USCI_B0 interrupt service routine
#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
{
switch (__even_in_range(UCB0IV, 30))
{
case USCI_NONE: break; // No interrupts
case USCI_I2C_UCALIFG: break; // ALIFG
case USCI_I2C_UCNACKIFG: break; // NACKIFG
case USCI_I2C_UCSTTIFG: break; // STTIFG
case USCI_I2C_UCSTPIFG: break; // STPIFG
case USCI_I2C_UCRXIFG3: break; // RXIFG3
case USCI_I2C_UCTXIFG3: break; // TXIFG3
case USCI_I2C_UCRXIFG2: break; // RXIFG2
case USCI_I2C_UCTXIFG2: break; // TXIFG2
case USCI_I2C_UCRXIFG1: break; // RXIFG1
case USCI_I2C_UCTXIFG1: break; // TXIFG1
case USCI_I2C_UCRXIFG0: // RXIFG0

RxBuffer = UCB0RXBUF;
UCB0CTLW0 |= UCTXSTP; // Generate I2C stop condition
__bic_SR_register_on_exit(LPM0_bits); // Exit active CPU

break;


case USCI_I2C_UCTXIFG0: // TXIFG0
{
switch(ADXL345_Ptr){
case 1:
{
UCB0TXBUF = 0x2C;
ADXL345_Ptr = 100;
}
case 100:
{
UCB0IE |= UCRXIE0;
UCB0IE &= ~UCTXIE0;
UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag
UCB0CTL1 &= ~UCTR;
UCB0CTL1 |= UCTXSTT; // I2C start condition
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
}
}

break;
case USCI_I2C_UCBCNTIFG: break; // CNTIFG
case USCI_I2C_UCCLTOIFG: break; // LTOIFG
case USCI_I2C_UCBIT9IFG: break; // BIT9IFG
default: break;
}
}

时序:

如果TX中断里的UCB0CTL1 |= UCTXSTT;   改成USCTXSTP的话,时序就是

如何发送RESTART呢?

  • 已解决,方法是

    UCB0IE |= UCRXIE0;
    UCB0IE &= ~UCTXIE0;
    UCB0IFG &= ~UCTXIFG0; // 清除中断标志
    UCB0CTLW0 &= ~UCTR;
    UCB0CTLW0 |= UCTXSTT; // I2C 重新开始信号
    ADXL345_Ptr = 3; //转到无效状态

    但为什么要连读3个字节.

    #include <msp430.h>

    volatile unsigned char ADXL345_Ptr;
    /*
    * ADXL345 1 = 写寄存器地址
    * 2 = 发送重新开始
    * 3 = STOP
    */
    volatile unsigned char RxBuffer;

    int main(void)
    {
    WDTCTL = WDTPW | WDTHOLD;

    P2SEL |= BIT0 | BIT1;


    UCB0CTLW0 |= UCSWRST;
    UCB0CTLW0 |= UCMST | UCMODE_3 | UCSSEL_1; // I2C 主机 ACLK
    UCB0I2CSA = 0x53; // 从机地址
    UCB0CTLW0 &= ~UCSWRST;
    UCB0IE |= UCTXIE0;

    ADXL345_Ptr = 1;

    UCB0CTLW0 |= UCTR | UCTXSTT;

    while (1)
    {

    __bis_SR_register(LPM3_bits | GIE); // 进入LPM3模式
    __no_operation(); // 断点测试

    }
    }


    #pragma vector = USCI_B0_VECTOR
    __interrupt void USCI_B0_ISR(void)
    {
    switch (__even_in_range(UCB0IV, 30))
    {
    case USCI_NONE: break; // No interrupts
    case USCI_I2C_UCALIFG: break; // ALIFG
    case USCI_I2C_UCNACKIFG: break; // NACKIFG
    case USCI_I2C_UCSTTIFG: break; // STTIFG
    case USCI_I2C_UCSTPIFG: break; // STPIFG
    case USCI_I2C_UCRXIFG3: break; // RXIFG3
    case USCI_I2C_UCTXIFG3: break; // TXIFG3
    case USCI_I2C_UCRXIFG2: break; // RXIFG2
    case USCI_I2C_UCTXIFG2: break; // TXIFG2
    case USCI_I2C_UCRXIFG1: break; // RXIFG1
    case USCI_I2C_UCTXIFG1: break; // TXIFG1
    case USCI_I2C_UCRXIFG0: // RXIFG0

    switch(ADXL345_Ptr){
    case 3:
    {
    RxBuffer = UCB0RXBUF;
    UCB0IFG &= ~UCRXIFG0;
    UCB0CTLW0 |= UCTXSTP;
    }
    default:
    break;
    }


    break;


    case USCI_I2C_UCTXIFG0: // TXIFG0
    {
    switch(ADXL345_Ptr){
    case 1:
    {
    UCB0TXBUF = 0x32; //寄存器地址
    ADXL345_Ptr = 2;
    }
    break;
    case 2:
    {
    UCB0IE |= UCRXIE0;
    UCB0IE &= ~UCTXIE0;
    UCB0IFG &= ~UCTXIFG0; // 清除中断标志
    UCB0CTLW0 &= ~UCTR;
    UCB0CTLW0 |= UCTXSTT; // I2C 重新开始信号
    ADXL345_Ptr = 3; //转到无效状态
    }
    break;
    default:
    break;
    }
    }

    break;
    case USCI_I2C_UCBCNTIFG: break; // CNTIFG
    case USCI_I2C_UCCLTOIFG: break; // LTOIFG
    case USCI_I2C_UCBIT9IFG: break; // BIT9IFG
    default: break;
    }
    __bic_SR_register_on_exit(LPM3_bits); // 退出LPM0模式
    }