从从站接收数据时如何停止I2C通信?

时间:2019-11-15 16:06:46

标签: c smartcard i2c msp430

我正在实现I2C通信协议。我正在将5个字节的数据发送到从属设备(从属地址为0x48)。然后想要查看响应。

我得到了想要的答复,但是我面临的唯一问题是我无法停止此通信。

例如,我发送5个字节的数据,作为回应,我期望3个字节的数据。我得到了这些数据,但此后没有看到任何停止条件。因此,我无法将更多数据发送到我的从设备。

我正在使用逻辑分析仪检查结果,并且在逻辑分析仪中收到3个字节后显示未知。 (附有图片)。

似乎我没有正确启动和停止I2C通信。

我编写的代码如下:

#include <msp430.h>


char TXData[5] = { 0x5A, 0xCF, 0x00 };        //Data to be transmitted
//unsigned char TXData[] = { 0x5A, 0x40, 0x09, 0x80, 0x04, 0x00, 0x22, 0x03, 0x41, 0x01, 0x01, 0x04, 0xE5, 0xEF }; // GetMemory APDU
//unsigned char TXData[] = { 0x5A, 0x00, 0x0B, 0x80, 0x04, 0x00, 0x1B, 0x04, 0x00, 0x01, 0x02, 0x03, 0x04, 0x0A, 0xEE, 0x07 }; // CreateSession APDU
//unsigned char TXData[] = { 0x5A, 0x00, 0x16, 0x00, 0xA4, 0x04, 0x00, 0x10, 0xA0, 0x00, 0x00, 0x03, 0x96, 0x54, 0x53, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xC8 }; // GetVersion APDU
volatile unsigned char RXData[3];                                     // To save the received data
unsigned char SlaveAddress = 0x48;                          // slave address
volatile unsigned char TXByteCtr;
volatile unsigned char TxByteCnt = 0;
volatile unsigned char RxByteCnt = 0;
unsigned char Rx;                                                 // To enable reception
void Transmit(void);
void Recieve(void);
short crc_ret;
//short final;
unsigned short crc16_x25(char* pData, int length)
{
    int i;
    unsigned short wCrc = 0xffff;
    while (length--) {
        wCrc ^= *(unsigned char *)pData++ << 0;
        for (i=0; i < 8; i++)
            wCrc = wCrc & 0x0001 ? (wCrc >> 1) ^ 0x8408 : wCrc >> 1;
    }
    return wCrc ^ 0xffff;
}
int main(void)
{

    WDTCTL = WDTPW | WDTHOLD;
    //while(1);
    // Configure GPIO
    P8OUT |= BIT0;                                          // Clear P8.0 output latch
    P8DIR |= BIT0;
    P7SEL0 |= BIT0 | BIT1;
    P7SEL1 &= ~(BIT0 | BIT1);


    // Disable the GPIO power-on default high-impedance mode to activate
    // previously configured port settings
    PM5CTL0 &= ~LOCKLPM5;

    // Configure USCI_B2 for I2C mode
    UCB2CTLW0 |= UCSWRST;                                        // put eUSCI_B in reset state
    UCB2CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK;              // I2C master mode, SMCLK
    UCB2BRW = 0x8;                                              // baudrate = SMCLK / 8
    UCB2CTLW0 &= ~UCSWRST;                                      // clear reset register
    UCB2IE |= UCTXIE0 | UCNACKIE | UCRXIE0;                     // transmit, Receive and NACK interrupt enable

    crc_ret = crc16_x25(TXData, (sizeof(TXData) - 2));   // Calling CRC function

    TXData[3] = (char)crc_ret;
    TXData[4] = (char)((crc_ret&0xFF00)>>8);

    while(1)
    {
       __delay_cycles(2000);                                    // Delay between transmissions
        UCB2I2CSA = SlaveAddress;                               // configure slave address
        TXByteCtr = 1;                                          // Load TX byte counter
        Transmit();                                             //Implementing the transmit function
        __delay_cycles(2000);
        Rx = 1;
        Recieve();                                              //Implementing the receive function
        __delay_cycles(2000);

    }
}

#pragma vector = EUSCI_B2_VECTOR
__interrupt void USCI_B2_ISR(void)

{

   switch(__even_in_range(UCB2IV, USCI_I2C_UCBIT9IFG))
    {
        case USCI_NONE:          break;                             // Vector 0: No interrupts
        case USCI_I2C_UCALIFG:   break;                                 // Vector 2: ALIFG
        case USCI_I2C_UCNACKIFG:                                    // Vector 4: NACKIFG
            UCB2CTLW0 |= UCTXSTT;                                   // resend start if NACK
            break;
        case USCI_I2C_UCSTTIFG:  break;                                 // Vector 6: STTIFG
        case USCI_I2C_UCSTPIFG:  break;                                 // Vector 8: STPIFG
        case USCI_I2C_UCRXIFG3:  break;                                 // Vector 10: RXIFG3
        case USCI_I2C_UCTXIFG3:  break;                                 // Vector 12: TXIFG3
        case USCI_I2C_UCRXIFG2:  break;                                 // Vector 14: RXIFG2
        case USCI_I2C_UCTXIFG2:  break;                                 // Vector 16: TXIFG2
        case USCI_I2C_UCRXIFG1:  break;                                 // Vector 18: RXIFG1
        case USCI_I2C_UCTXIFG1:  break;                                 // Vector 20: TXIFG1
        case USCI_I2C_UCRXIFG0:                                     // Vector 22: RXIFG0

            if (Rx < 3)                                          // Check RX byte counter
            {
                RXData[RxByteCnt]= UCB2RXBUF;                       // Load TX buffer
                RxByteCnt++;
                Rx++;                                        // Decrement TX byte counter
                __bic_SR_register_on_exit(LPM0_bits);               // Exit LPM0
            }
            else
            {
                UCB2CTLW0 |= UCTXSTP;                               // I2C stop condition
                UCB2IFG &= ~UCRXIFG;                                // Clear USCI_B2 RX int flag
                __bic_SR_register_on_exit(LPM0_bits);               // Exit LPM0
            }
            break;
        case USCI_I2C_UCTXIFG0:                                     // Vector 24: TXIFG0


            if (TXByteCtr < (sizeof(TXData) + 1))                    // Check TX byte counter
            {
                UCB2TXBUF = TXData[TxByteCnt];                       // Load TX buffer
                TxByteCnt++;
                TXByteCtr++;                                        // Decrement TX byte counter
                __bic_SR_register_on_exit(LPM0_bits);               // Exit LPM0
            }
            else
            {
                TxByteCnt = 0;

                UCB2CTLW0 |= UCTXSTP;                               // I2C stop condition
                UCB2IFG &= ~UCTXIFG;                                // Clear USCI_B2 TX int flag
                __bic_SR_register_on_exit(LPM0_bits);               // Exit LPM0
            }
            break;
        case USCI_I2C_UCBCNTIFG: break;                              // Vector 26: BCNTIFG
        case USCI_I2C_UCCLTOIFG: break;                             // Vector 28: clock low timeout
        case USCI_I2C_UCBIT9IFG: break;                             // Vector 30: 9th bit
        default: break;
    }
}


void Transmit(void)
{
    while (UCB2CTLW0 & UCTXSTP);                            // Ensure stop condition got sent
    UCB2CTLW0 |= UCTR | UCTXSTT;                            // I2C TX, start condition
    __bis_SR_register(GIE);                     // Enter LPM0 w/ interrupts
                                                            // Remain in LPM0 until all data
                                                            // is TX'd

}

void Recieve(void)
{

    while (UCB2CTLW0 & UCTXSTP);                            // Ensure stop condition got se
    UCB2CTLW0 &= ~UCTR;
    UCB2CTLW0 |= UCTXSTT;

    __bis_SR_register(GIE);                     // Enter LPM0 w/ interrupts//start condition;
                                                   // I2C stop condition
    UCB2CTLW0 &= ~UCTXSTP;

    //UCB2IFG &= ~UCRXIFG;


}

发送和接收的数据也被附加: 5 bytes of data I am transmitting

3 bytes of received data

您可以在接收到的数据中看到,在3个字节之后,写入了“未知”字样。由于这种未知的原因,我无法发送更多数据。

如果有人可以帮助我,我将非常感激。

谢谢

0 个答案:

没有答案