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.

MSP430F5418A I2C通信

Other Parts Discussed in Thread: TMP101, MSP430F5418A

Hi,all

我在用MSP430F5418A和温度传感器TMP101通信过程中,遇到以下这个问题:

我向TMP101发送数据时,总是发送到第五个数据的时候就进不了中断了,前四个数据是正常发送的,请问这是怎么回事?

下面是我的源程序,请指教:

#include "msp430x54xA.h"

unsigned char *PTxData;                     // Pointer to TX data

unsigned char TXByteCtr;

#define VCC3P3_PwrOn         (P8OUT |= BIT5)

#define VCC3P3_PwrGood       (P8IN & BIT6)

#define LED_ON               (P3OUT &= ~(BIT6))

#define LED_OFF              (P3OUT |= BIT6)

const unsigned char TxData[] =              // Table of data to transmit

{

 0x01,

 0x0b,

 0x02,

 0x01,

 0x04,

 0x03,

 0x32,

 0x00,

};

void test_mcu_port_init(void);

void main(void)

{

 WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

 test_mcu_port_init();

 VCC3P3_PwrOn;

 while(!(VCC3P3_PwrGood))

 {

;

 }

 LED_ON;

 P3SEL |= 0x80;                            // Assign I2C pins to USCI_B0

 P5SEL |= 0x10;

 UCB1CTL1 |= UCSWRST;                      // Enable SW reset

 UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode

 UCB1CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset

 UCB1BR0 = 12;                             // fSCL = SMCLK/12 = ~100kHz

 UCB1BR1 = 0;

 UCB1I2CSA = 0x4a;                         // Slave Address is 048h

 UCB1CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation

 UCB1IE |= UCTXIE;                         // Enable TX interrupt

//  while (1)

//  {

   __delay_cycles(50);                     // Delay required between transaction

   PTxData = (unsigned char *)TxData;      // TX array start address

                                           // Place breakpoint here to see each

                                           // transmit operation.

   TXByteCtr = sizeof TxData;              // Load TX byte counter

   UCB1CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition

   __bis_SR_register(GIE);     // Enter LPM0, enable interrupts

   __no_operation();                       // Remain in LPM0 until all data

                                           // is TX'd

   while (UCB1CTL1 & UCTXSTP);             // Ensure stop condition got sent

//  }

}

void test_mcu_port_init(void)

{

/*将所有端口恢复到初始值*/

P1OUT &= 0x00;

P2OUT &= 0x00;

P3OUT &= 0x00;

/*LED为关闭状态*/

LED_OFF;

P4OUT &= 0x00;

/*I/O扩展芯片中断管脚拉高*/

P4OUT |= BIT6;

P5OUT &= 0x00;

P6OUT &= 0x00;

P7OUT &= 0x00;

/*关闭1.8V的MOSFET*/

P7OUT |= BIT4;

P8OUT |= 0x00;

/*定义所有端口方向和功能选择*/

P1SEL |= 0x00;

P1DIR |= 0x5b;

P2SEL |= 0x00;

P2DIR |= 0xe7;

P3SEL |= 0xbf;

P3DIR |= 0x40;

P4SEL |= 0x59;

P4DIR |= 0xae;

P5SEL |= 0xd0;

P5DIR |= 0x25;

P6SEL |= 0x03;

P6DIR |= 0x78;

P7SEL |= 0x0b;

P7DIR |= 0xb4;

P8SEL |= 0x00;

P8DIR |= 0x3f;

}

//------------------------------------------------------------------------------

// The USCIAB0TX_ISR is structured such that it can be used to transmit any

// number of bytes by pre-loading TXByteCtr with the byte count. Also, TXData

// points to the next byte to transmit.

//------------------------------------------------------------------------------

#pragma vector = USCI_B1_VECTOR

__interrupt void USCI_B1_ISR(void)

{

 switch(__even_in_range(UCB1IV,12))

 {

 case  0: break;                           // Vector  0: No interrupts

 case  2: break;                           // Vector  2: ALIFG

 case  4: break;                           // Vector  4: NACKIFG

 case  6: break;                           // Vector  6: STTIFG

 case  8: break;                           // Vector  8: STPIFG

 case 10: break;                           // Vector 10: RXIFG

 case 12:                                  // Vector 12: TXIFG

   if (TXByteCtr)                          // Check TX byte counter

   {

     UCB1TXBUF = *PTxData++;               // Load TX buffer

     TXByteCtr--;                          // Decrement TX byte counter

   }

   else

   {

     UCB1CTL1 |= UCTXSTP;                  // I2C stop condition

     UCB1IFG &= ~UCTXIFG;                  // Clear USCI_B0 TX int flag

   }

 default: break;

 }

}

程序中,我想将数组TxData中的数据发送到TMP101,但是出现了上面所说的那个情况。请帮忙看一下到底是哪里出错了?

Thx

Nick

  • Nick,

    您好!

    ”总是发送到第五个数据的时候就进不了中断了,前四个数据是正常发送的“

    与TMP101的通信必须得符合TMP101的时序要求。最好是用示波器抓一下波形看一下,这样最清楚了!

    在您的另一个帖子中已经回复了您的问题。

    谢谢!

  • 谢谢您的及时回复。

    我还有个问题想请教:

    每次单片机上电之后,初始化I2C时,只要执行完UCB1CTL1 &= ~UCSWRST; 这条语句,寄存器UCBSTAT中的

    UCBBUSY位就会置1,之后程序就不能正常收发数据了。UCBBUSY位只有在产生了UCTXSTT之后才会置1,但是实际

    程序上没有到UCTXSTT这条语句。按说上电之后,SDA应该是高电平呀,可是为什么UCBBUSY位还会置1呢?

    谢谢

    Nick

  • The bus busy bit, UCBBUSY, is set after a START and cleared after a STOP. 那么作为master从上电开始UCBBUSY置置位并不影响整个i2c读写程序。

  • The bus busy bit, UCBBUSY, is set after a START and cleared after a STOP. 那么作为master从上电开始UCBBUSY置置位并不影响整个i2c读写程序。

  • 谢谢您的回复,但是我是在执行完UCB1CTL1 &= ~UCSWRST; 这条语句UCBBUSY位就置1了,还没有START。UCBBUSY

    位置1会产生影响,进不了中断,不能正常收发数据。

    Thx

    Nick

  • 如你所说执行到第五个数据出现错误,前四个都是正确的,但这与UCBBUSY上电开始置位是没有关系的。具体检查一下程序,如鸵鸟蝈蝈所说,用示波器观测一下。

  • 每次单片机上电之后,初始化I2C时,只要执行完UCB1CTL1 &= ~UCSWRST; 这条语句,寄存器UCBSTAT中的

    UCBBUSY位就会置1,之后程序就不能正常收发数据了。

    出现这个问题应该是从机将SCL拉高,也就是从机在等待主机发送stop位,上次运行时主机没有给从机发送STOP位。断电后重新上电能够正常就能验证是上述问题,解决办法,将代码完善,或者将I2C口配成普通I/O口,强行拉低