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.

msp430 i2c communication

Other Parts Discussed in Thread: MSP430F1611, MSP430G2231

I tried i2c communication between msp430f1611 and msp430g2231 with msp430f1611 as master device. I used 

//******************************************************************************
//   MSP-FET430P140 Demo - I2C, Master Transmits to MSP430 Slave RX
//
//   Description: This demo connects two MSP430's via the I2C bus. The master
//   transmits to the slave. This is the master code. The slave code is called
//   fet140_i2c_07.c. Master continuously transmits 0x5A inside
//   the TX ISR
//   Run the code in Slave device before starting the Master device for proper
//   communication
//   The TXRDYIFG interrupt is used to know when to TX
//   ACLK = n/a, MCLK = SMCLK = I2CCLOCK = DCO ~ 800kHz
//  //* MSP430F169 Device Required *//
//
//                                 /|\  /|\
//                  MSP430F169     10k  10k     MSP430F169
//                    slave         |    |        master
//              -----------------|  |    |  -----------------
//             |             P3.1|<-|---+->|P3.1             |
//             |                 |  |      |                 |
//             |                 |  |      |                 |
//             |             P3.3|<-+----->|P3.3             |
//             |                 |         |                 |
//
//
//  H. Grewal
//  Texas Instruments Inc.
//  Feb 2005
//  Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.21A
//******************************************************************************

#include  <msp430x16x.h>

void main (void)
{

  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  P3SEL |= 0x0A;                            // Select I2C pins

  U0CTL |= I2C + SYNC;                      // Recommended init procedure
  U0CTL &= ~I2CEN;                          // Recommended init procedure
  I2CTCTL |= I2CSSEL0;                      // SMCLK
  I2CNDAT = 0x01;                           // Write one byte
  I2CSA = 0x0048;                           // Slave Address is 048h
  I2CIE = TXRDYIE;                          // Enable RXRDYIFG interrupt
  U0CTL |= I2CEN;                           // Enable I2C

  _EINT();                                  // Enable interrupts

  while (1)
  {
    U0CTL |= MST;                           // Master mode
    I2CTCTL |= I2CSTT + I2CSTP + I2CTRX;    // Initiate transfer
    _BIS_SR(CPUOFF);                        // Enter LPM0
  }

}

// Common ISR for I2C Module
#pragma vector=USART0TX_VECTOR
__interrupt void I2C_ISR(void)
{
 switch(I2CIV)
 {
   case  0: break;                          // No interrupt
   case  2: break;                          // Arbitration lost
   case  4: break;                          // No Acknowledge
   case  6: break;                          // Own Address
   case  8: break;                          // Register Access Ready
   case 10: break;                          // Receive Ready
   case 12:
     I2CDRB = 128;                         // TX data
     while (I2CBUSY & I2CDCTL);             // I2C ready?
     _BIC_SR_IRQ(CPUOFF);                   // Clear LPM0
     break;                                 // Transmit Ready

   case 14: break;                          // General Call
   case 16: break;                          // Start Condition
 }
}
in f16x device and 
//******************************************************************************
//  MSP430G2x21/G2x31 Demo - I2C Slave Receiver, single byte
//
//  Description: I2C Slave communicates with I2C Master using
//  the USI. Master data should increment from 0x00 with each transmitted byte
//  which is verified by the slave.
//  LED off for address or data Ack; LED on for address or data NAck.d by the slave.
//  ACLK = n/a, MCLK = SMCLK = Calibrated 1MHz
//
//  ***THIS IS THE SLAVE CODE***
//
//                  Slave                      Master
//                                      (msp430g2x21_usi_07.c)
//             MSP430G2x21/G2x31          MSP430G2x21/G2x31
//             -----------------          -----------------
//         /|\|              XIN|-    /|\|              XIN|-
//          | |                 |      | |                 |
//          --|RST          XOUT|-     --|RST          XOUT|-
//            |                 |        |                 |
//      LED <-|P1.0             |        |                 |
//            |                 |        |             P1.0|-> LED
//            |         SDA/P1.7|<-------|P1.7/SDA         |
//            |         SCL/P1.6|<-------|P1.6/SCL         |
//
//  Note: internal pull-ups are used in this example for SDA & SCL
//
//  D. Dang
//  Texas Instruments Inc.
//  October 2010
//  Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
//******************************************************************************

#include <msp430g2221.h>


char MST_Data = 0;                     // Variable for received data
char SLV_Addr = 0x90;                  // Address is 0x48<<1 for R/W
int I2C_State = 0;                     // State variable

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;            // Stop watchdog
  if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)                                     
  {  
    while(1);                          // If calibration constants erased
                                       // do not load, trap CPU!!
  }   
  BCSCTL1 = CALBC1_1MHZ;               // Set DCO
  DCOCTL = CALDCO_1MHZ;

  P1OUT = 0xC0;                        // P1.6 & P1.7 Pullups
  P1REN |= 0xC0;                       // P1.6 & P1.7 Pullups
  P1DIR = 0xFF;                        // Unused pins as outputs
  P1SEL |= 0X04;
  P2OUT = 0;
  P2DIR = 0xFF;

  USICTL0 = USIPE6+USIPE7+USISWRST;    // Port & USI mode setup
  USICTL1 = USII2C+USIIE+USISTTIE;     // Enable I2C mode & USI interrupts
  USICKCTL = USICKPL;                  // Setup clock polarity
  USICNT |= USIIFGCC;                  // Disable automatic clear control
  USICTL0 &= ~USISWRST;                // Enable USI
  USICTL1 &= ~USIIFG;                  // Clear pending flag
  _EINT();

  while(1)
  {
    LPM0;                              // CPU off, await USI interrupt
    _NOP();                            // Used for IAR
  }
}

//******************************************************************************
// USI interrupt service routine
//******************************************************************************
#pragma vector = USI_VECTOR
__interrupt void USI_TXRX (void)
{
  if (USICTL1 & USISTTIFG)             // Start entry?
  {
    P1OUT |= 0x01;                     // LED on: sequence start
    I2C_State = 2;                     // Enter 1st state on start
  }

  switch(I2C_State)
    {
      case 0: // Idle, should not get here
              break;

      case 2: // RX Address
              USICNT = (USICNT & 0xE0) + 0x08; // Bit counter = 8, RX address
              USICTL1 &= ~USISTTIFG;   // Clear start flag
              I2C_State = 4;           // Go to next state: check address
              break;

      case 4: // Process Address and send (N)Ack
              if (USISRL & 0x01)       // If read...
                SLV_Addr++;            // Save R/W bit
              USICTL0 |= USIOE;        // SDA = output
              if (USISRL == SLV_Addr)  // Address match?
              {
                USISRL = 0x00;         // Send Ack
                P1OUT &= ~0x01;        // LED off
                I2C_State = 8;         // Go to next state: RX data
              }
              else
              {
                USISRL = 0xFF;         // Send NAck
                P1OUT |= 0x01;         // LED on: error
                I2C_State = 6;         // Go to next state: prep for next Start
              }
              USICNT |= 0x01;          // Bit counter = 1, send (N)Ack bit
              break;

      case 6: // Prep for Start condition
              USICTL0 &= ~USIOE;       // SDA = input
              SLV_Addr = 0x90;         // Reset slave address
              I2C_State = 0;           // Reset state machine
              break;

      case 8: // Receive data byte
              USICTL0 &= ~USIOE;       // SDA = input
              USICNT |=  0x08;         // Bit counter = 8, RX data
              I2C_State = 10;          // Go to next state: Test data and (N)Ack
              break;

      case 10:// Check Data & TX (N)Ack
              USICTL0 |= USIOE;        // SDA = output
              if (USISRL == MST_Data)  // If data valid...
              {
                USISRL = 0x00;         // Send Ack
                MST_Data++;            // Increment Master data
                P1OUT &= ~0x01;        // LED off
              }
              else
              {
                USISRL = 0xFF;         // Send NAck
                P1OUT |= 0x01;         // LED on: error
              }
              USICNT |= 0x01;          // Bit counter = 1, send (N)Ack bit
              I2C_State = 6;           // Go to next state: prep for next Start
              break;
    }

  USICTL1 &= ~USIIFG;                  // Clear pending flags
}
 in g2x device. But there seems to be an error and i am not able to get the answer. Can anyone help me?

  • Hi, It would be very easy to think about and help if you can post the "exact error message". But any ways, most of the time as regards to I2C communication (Think you r using the standard code examples) there were few standard errors like Pull up resistors ,Slave device addressing etc. Make sure that you have got them right. And then probe the SCL and SDA lines with a scope or logic analyzer and compare to what you want. This way you can actually cut short the issues that u r looking at.

    Regards,

    Sri.

  • As Sri mentioned, a Logic Analyzer can be indispensable for debugging spi and i2C communications.

    I bought one of these recently.  It decodes all protocols you can think of, has an UNLIMITED buffer (uses PC memory), and shows all of the transaction types of I2C.  

    Not only that, its TINY, and only costs 149$   Its helped me out several times.

    http://www.saleae.com/logic16?gclid=CILb0PG1lbQCFeJ9OgodHGUAnw

**Attention** This is a public forum