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.

MSP430F5529 I2C COMMUNICATION

Part Number: MSP430F5529

I WANT TO READ DATA FROM SPECIFIC 0X03 REGISTER OF I2C SLAVE MODULE USING MSP430F5529 BUT INSTEAD OF 16 BIT DATA WITH ACKNOWLEDGE I COULD ONLY GET 8 BIT DATA WITCH NACK.MY CODE

#include <msp430.h>
char Data_In=0;
unsigned char RXByteCtr;
unsigned char *PRxData;
volatile unsigned char RxBuffer[128];
void main(void)
{
    volatile int i;
WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT                          // P1.0 output
 P3SEL |= 0x03;                            // Assign I2C pins to USCI_B0
 UCB0CTL1 |= UCSWRST;                      // Enable SW reset
 UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
 UCB0CTL1 |= UCSSEL_2;            // Use SMCLK
 UCB0BR0 = 12;                             // fSCL = SMCLK/12 = ~100kHz
 UCB0BR1 = 0;
 UCB0I2CSA = 0x40;                         // Slave Address is 048h
 UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
UCB0IE |= UCTXIE;
UCB0IE |= UCSTPIE + UCSTTIE + UCRXIE;
volatile int c=1;
__enable_interrupt();
  while(1)
  {
     
RXByteCtr = 2;
UCB0CTL1 |= UCTR + UCTXSTT;
while (UCB0CTL1 & UCTXSTP);
UCB0CTL1 &=~UCTXSTP;
UCB0CTL1 &=~UCTR;
UCB0CTL1 |=UCTXSTT;
while (UCB0CTL1 & UCTXSTP);
UCB0CTL1 &=~UCTXSTP;
  }
    }

#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
{
    switch(UCB0IV){
        case 0x0A:
            RXByteCtr--;                            // Decrement RX byte counter
               if (RXByteCtr)
               {
                 *PRxData++ = UCB0RXBUF;               // Move RX data to address PRxData
                 if (RXByteCtr == 1)                   // Only one byte left?
                   UCB0CTL1 |= UCTXSTP;                // Generate I2C stop condition
               }
               else
               {
                 *PRxData = UCB0RXBUF;                 // Move final RX data to PRxData
                 __bic_SR_register_on_exit(LPM0_bits); // Exit active CPU
               }
               break;
        case 0x0C:
            UCB0TXBUF = 0X01;
            break;
        default:
            break;}
}

  • I can READ from either 0x01 or 0x03 all are 16 bit registers .I want to read 16 bit data from specific register.

  • Hi Makkapati,

    You could refer to the I2C example code. This will help you.

    dev.ti.com/.../node

  • Hi allen its to recieve transmitted signal but we have to read particular register of slave here 0x03 register I have to read

  • Hi Makkapati,

    You need to check the slave device datasheet of it I2C read protocol. Generally a read protocol is something like this.

    Send a write command to write the special register you want read and re-start command and then send the read command and wait for slave transfer the data.


  • I HAVE TO READ 2 BYTES BUT HERE I COULD ABLE TO READ ONLY MSB 8 BITS OF DATA

  • >while (UCB0CTL1 & UCTXSTP);

    Waiting for TXSTP to go low is not an effective way of waiting for completion, since TXSTP is not initially high. The Tx side might be working by accident, but you're almost certainly stopping the Rx side prematurely. Try replacing that with

    > LPM0;  // Wait for completion.

    You'll have to add this to the "case 0x0C":

      __bic_SR_register_on_exit(LPM0_bits); // Exit active CPU

  • HI BRUCE i TRIED AS YOU SAID BUT EVEN COMMUNICATION IS NOT ESTABLISHED IT SEEMS TO BE IRRESPONSIVE PAGE.

    #include <msp430.h>
    int Data_In=0;
    unsigned int RXByteCtr;
    unsigned int Temperature;
    volatile unsigned int RxBuffer[128];
    void main(void)
    {
    volatile int i;
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT // P1.0 output
    P3SEL |= 0x03; // Assign I2C pins to USCI_B0
    UCB0CTL1 |= UCSWRST; // Enable SW reset
    UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
    UCB0CTL1 |= UCSSEL_2; // Use SMCLK
    UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
    UCB0BR1 = 0;
    UCB0I2CSA = 0x40; // Slave Address is 048h
    UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
    //UCB0IE |= UCRXIE;
    UCB0IE |= UCTXIE;
    UCB0IE |= UCSTPIE + UCSTTIE + UCRXIE;
    volatile int c=1;
    __enable_interrupt();
    while(1)
    {
    //if(c%2==1)
    //{
    RXByteCtr = 2;
    UCB0CTL1 |= UCTR + UCTXSTT;
    //while (UCB0CTL1 & UCTXSTP);
    LPM0;
    UCB0CTL1 &=~UCTXSTP;
    UCB0CTL1 &=~UCTR;
    UCB0CTL1 |=UCTXSTT;
    //while (UCB0CTL1 & UCTXSTP);
    LPM0;
    UCB0CTL1 &=~UCTXSTP;
    // else if(c%2==0)
    // {
    // while (UCB0CTL1 & UCTXSTP);
    //UCB0CTL1 |= UCTR + UCTXSTT;
    //UCB0CTL1 &=~UCTXSTP;
    //UCB0CTL1 |=UCTXSTT;
    //UCB0CTL1 &=~UCTR;
    //while (UCB0CTL1 & UCTXSTP);
    // }
    //UCB0CTL1 &=~UCTXSTP;
    }
    }
    #pragma vector = USCI_B0_VECTOR
    __interrupt void USCI_B0_ISR(void)
    {
    switch(UCB0IV){
    case 0x0A:
    RXByteCtr--; // Decrement RX byte counter
    if (RXByteCtr)
    {
    Temperature |= UCB0RXBUF; // Move RX data to address PRxData
    if (RXByteCtr == 1)
    // MSB of temperature
    Temperature |= UCB0RXBUF<< 8;
    Temperature |= UCB0RXBUF;
    UCB0CTL1 |= UCTXSTP; // Only one byte left?
    // Generate I2C stop condition
    }
    else
    {
    // Move final RX data to PRxData
    __bic_SR_register_on_exit(LPM0_bits); // Exit active CPU
    }
    break;
    case 0x0C:
    UCB0TXBUF = 0X03;
    __bic_SR_register_on_exit(LPM0_bits);
    break;
    default:
    break;
    }
    }

  • Hi Makkapati,

    if (RXByteCtr)
    {
    Temperature |= UCB0RXBUF; // Move RX data to address PRxData

    When the second time go into ISR, the RxByteCtr=, the new RXBUF data will replace the low 8 bit of Temperature which has load the previous RXBUF data. 

  • YES HOW COULD I SEND THAT 

  • means how to store the lsb bit also

  • Hi Makkapati,

    Judge first before proceeding, That is the logic problem. Do you have any problem of using the device?

  • logic problem as you told its only msb byte going through i2c bus..

  • Hi Makkapati,

    Have you solved your problem? Get the fist 8 bit data and shift it to the high 8 bit of "int" variant.  Then get the next 8 bit data put it to the lower.

  • I DIDNT RESOLVED 

  • I resolved my issue thankyou all for responding.

**Attention** This is a public forum