我正在实现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;
}
您可以在接收到的数据中看到,在3个字节之后,写入了“未知”字样。由于这种未知的原因,我无法发送更多数据。
如果有人可以帮助我,我将非常感激。
谢谢