• Join
  • Sign In with my.TI Login
Texas Instruments
  • Products
  • Applications
  • Tools & Software
  • Support & Community
  • Sample & Buy
  • About TI
Sample & Purchase Cart Sample & Purchase Cart
  • Search
  • Advanced
TI E2E™ Community
  • Support Forums
  • Blogs
  • Groups
  • Videos
  • 简体中文
  • More ...
TI Home » TI E2E Community » Support Forums » Microcontrollers » MSP430™ Microcontrollers » MSP430 Ultra-Low Power 16-bit Microcontroller Forum » I2C Interfacing
Share
MSP430™ Microcontrollers
  • Forum
  • Announcements
  • E2E Wiki
Options
  • Subscribe via RSS
MSP430 Resources
  • MSP430 Product Folder
  • MSP-EXP430G2 - MSP430 LaunchPad Value Line Development kit
  • MSP430 Getting Started Guide
  • MSP430 Microcontroller Projects
  • More Resources >
  • Forums

    I2C Interfacing

    This question is not answered
    PAVAN ANAND
    Posted by PAVAN ANAND
    on Apr 11 2012 11:14 AM
    Prodigy160 points

    Hey,

    I am new to MSP430. I have to write data to an external memory( Non- volatile) chip (DS1682). It supports 2 wire serial interface( I2C). I am using MSP430G2231. And also i have to read the bytes written onto this chip. Does msp430g2231 have any inbuilt library to read and write data onto external memory..i have to write 16 bit data. 

    IAR MSP430 microcontroller Serial Communication IAR Embedded Workbench
    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    All Replies
    • Jan
      Posted by Jan
      on Apr 11 2012 11:59 AM
      Expert1425 points

      Hi Pavan,

      the MSP430G2231 has built in an USI module which will support you in hardware. Here is one of the code examples:

      //******************************************************************************
      //  MSP430G2x21/G2x31 Demo - I2C Master Receiver, single byte
      //
      //  Description: I2C Master communicates with I2C Slave using
      //  the USI. Slave data should increment from 0x00 with each transmitted byte
      //  which is verified by the Master.
      //  LED off for address or data Ack; LED on for address or data NAck.
      //  ACLK = n/a, MCLK = SMCLK = Calibrated 1MHz
      //
      //  ***THIS IS THE MASTER CODE***
      //
      //                  Slave                      Master
      //          (msp430g2x21_usi_09.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 SLV_data = 0x00;                  // Variable for received data
      char SLV_Addr = 0x91;                  // Address is 0x48 << 1 bit + 1 for Read
      int I2C_State = 0;                     // State variable

      void main(void)
      {
        volatile unsigned int i;             // Use volatile to prevent removal

        WDTCTL = WDTPW + WDTHOLD;            // Stop watchdog
        if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)                                     
        {  
          while(1);                          // If calibration constants are 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
        P2OUT = 0;
        P2DIR = 0xFF;

        USICTL0 = USIPE6+USIPE7+USIMST+USISWRST;// Port & USI mode setup
        USICTL1 = USII2C+USIIE;              // Enable I2C mode & USI interrupt
        USICKCTL = USIDIV_3+USISSEL_2+USICKPL;// Setup USI clocks: SCL = SMCLK/8 (~120kHz)
        USICNT |= USIIFGCC;                  // Disable automatic clear control
        USICTL0 &= ~USISWRST;                // Enable USI
        USICTL1 &= ~USIIFG;                  // Clear pending flag
        _EINT();

        while(1)
        {
          USICTL1 |= USIIFG;                 // Set flag and start communication
          LPM0;                              // CPU off, await USI interrupt
          _NOP();                            // Used for IAR
          for (i = 0; i < 5000; i++);        // Dummy delay between communication cycles
        }
      }

      /******************************************************
      // USI interrupt service routine
      ******************************************************/
      #pragma vector = USI_VECTOR
      __interrupt void USI_TXRX (void)
      {
        switch(I2C_State)
          {
            case 0: // Generate Start Condition & send address to slave
                    P1OUT |= 0x01;           // LED on: sequence start
                    USISRL = 0x00;           // Generate Start Condition...
                    USICTL0 |= USIGE+USIOE;
                    USICTL0 &= ~USIGE;
                    USISRL = SLV_Addr;       // ... and transmit address, R/W = 1
                    USICNT = (USICNT & 0xE0) + 0x08; // Bit counter = 8, TX Address
                    I2C_State = 2;           // Go to next state: receive address (N)Ack
                    break;

            case 2: // Receive Address Ack/Nack bit
                    USICTL0 &= ~USIOE;       // SDA = input
                    USICNT |= 0x01;          // Bit counter = 1, receive (N)Ack bit
                    I2C_State = 4;           // Go to next state: check (N)Ack
                    break;

            case 4: // Process Address Ack/Nack & handle data RX
                    if (USISRL & 0x01)       // If Nack received...
                    { // Prep Stop Condition
                      USICTL0 |= USIOE;
                      USISRL = 0x00;
                      USICNT |=  0x01;       // Bit counter = 1, SCL high, SDA low
                      I2C_State = 10;        // Go to next state: generate Stop
                      P1OUT |= 0x01;         // Turn on LED: error
                    }
                    else                     // Ack received
                    { // Receive Data from slave
                      USICNT |=  0x08;       // Bit counter = 8, RX data
                      I2C_State = 6;         // Go to next state: Test data and (N)Ack
                      P1OUT &= ~0x01;        // LED off
                    }
                    break;

            case 6: // Send Data Ack/Nack bit
                    USICTL0 |= USIOE;        // SDA = output
                    if (USISRL == SLV_data)  // If data valid...
                    {
                      USISRL = 0x00;         // Send Ack
                      SLV_data++;            // Increment Slave 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 = 8;           // Go to next state: prep stop
                    break;

            case 8: // Prep Stop Condition
                    USICTL0 |= USIOE;        // SDA = output
                    USISRL = 0x00;
                    USICNT |=  0x01;         // Bit counter = 1, SCL high, SDA low
                    I2C_State = 10;          // Go to next state: generate Stop
                    break;

            case 10: // Generate Stop Condition
                    USISRL = 0x0FF;          // USISRL = 1 to release SDA
                    USICTL0 |= USIGE;        // Transparent latch enabled
                    USICTL0 &= ~(USIGE+USIOE);// Latch/SDA output disabled
                    I2C_State = 0;           // Reset state machine for next transmission
                    LPM0_EXIT;               // Exit active for next transfer
                    break;
          }

        USICTL1 &= ~USIIFG;                  // Clear pending flag
      }

      from: http://www.ti.com/lit/zip/slac463

      --
      Regards,
      Jan

      Oxfam Trailwalker 2012 - Runner

      Found any horribly english mistakes? - Drop me a note as private conversation via my profile if you like ;-)

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • PAVAN ANAND
      Posted by PAVAN ANAND
      on Apr 11 2012 12:12 PM
      Prodigy160 points

      Thanks for the early reply Jan!

      But shouldnt I use MSP430G2231 as a master ? I have seen the example code which sends/transmits multiple bytes (usi_12 in the example codes). But I was not able to figure out where to put the data which i want to write!

      any help would be greatly appreciated  !

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jens-Michael Gross
      Posted by Jens-Michael Gross
      on Apr 11 2012 13:38 PM
      Guru140085 points

      PAVAN ANAND
      But shouldnt I use MSP430G2231 as a master ?

      This is code for the master. Howeve,r it is code for a master receiver. You require code for master transmitter.

      The differences aren't that big. A different slave address to be sent (LSB clear instead of set), no ACK bit generated but received instead, and write outgoing byte to USISRL before writing the count instead of writing the count, waiting until it reaches zero and reading the incoming byte from USISRL.

      _____________________________________
      Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.
      If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • PAVAN ANAND
      Posted by PAVAN ANAND
      on Apr 12 2012 08:10 AM
      Prodigy160 points

      Hey,

      Can i use the  program shown below to send multiple bytes to my eeprom chip( example code) ? but i am not able to figure out where to enter the data which i need to send..also my eeprom has 32 bits..and i have to write the first 16 bits with data..how to access the first 16 bits..plz help

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • PAVAN ANAND
      Posted by PAVAN ANAND
      on Apr 12 2012 08:12 AM
      Prodigy160 points
      //******************************************************************************
      // MSP430G2x21/G2x31 Demo - I2C Master Transmitter / Reciever, multiple bytes
      //
      // Description: I2C Master communicates with I2C Slave using
      // the USI. Master data should increment from 0x55 with each transmitted byte
      // and Master determines the number of bytes recieved, set by
      // the Number_of_Bytes value. LED off for address or data Ack;
      // LED on for address or data NAck.
      // ACLK = n/a, MCLK = SMCLK = Calibrated 1MHz
      //
      //
      // ***THIS IS THE MASTER CODE***
      //
      // Slave Master
      // (msp430g2x21_usi_15.c)
      // MSP430G2x21/G2x31 MSP430G2x21/G2x31
      // ----------------- -----------------
      // /|\| XIN|- /|\| XIN|-
      // | | | | | |
      // --|RST XOUT|- --|RST XOUT|-
      // | | | |
      // LED <-|P1.0 | | |
      // | | | P1.0|-> LED
      // | SDA/P1.7|------->|P1.6/SDA |
      // | SCL/P1.6|<-------|P1.7/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>


      #define number_of_bytes 5 // How many bytes?

      void Master_Transmit(void);
      void Master_Recieve(void);

      void Setup_USI_Master_TX(void);
      void Setup_USI_Master_RX(void);

      char MST_Data = 0x55; // Variable for transmitted data
      char SLV_Addr = 0x90;
      int I2C_State, Bytecount, Transmit = 0; // State variable
      void Data_TX (void);
      void Data_RX (void);
      void main(void)
      {
      volatile unsigned int i; // Use volatile to prevent removal

      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, others to 0
      P1REN |= 0xC0; // P1.6 & P1.7 Pullups
      P1DIR = 0xFF; // Unused pins as outputs
      P2OUT = 0;
      P2DIR = 0xFF;



      while(1)
      {
      Master_Transmit();
      _NOP(); // Used for IAR

      Master_Recieve();
      _NOP();
      }
      }

      /******************************************************
      // USI interrupt service routine
      // Data Transmit : state 0 -> 2 -> 4 -> 10 -> 12 -> 14
      // Data Recieve : state 0 -> 2 -> 4 -> 6 -> 8 -> 14
      ******************************************************/
      #pragma vector = USI_VECTOR
      __interrupt void USI_TXRX (void)
      {
      switch(__even_in_range(I2C_State,14))
      {
      case 0: // Generate Start Condition & send address to slave
      P1OUT |= 0x01; // LED on: sequence start
      Bytecount = 0;
      USISRL = 0x00; // Generate Start Condition...
      USICTL0 |= USIGE+USIOE;
      USICTL0 &= ~USIGE;
      if (Transmit == 1){
      USISRL = 0x90; // Address is 0x48 << 1 bit + 0 (rw)
      }
      if (Transmit == 0){
      USISRL = 0x91; // 0x91 Address is 0x48 << 1 bit
      // + 1 for Read
      }
      USICNT = (USICNT & 0xE0) + 0x08; // Bit counter = 8, TX Address
      I2C_State = 2; // next state: rcv address (N)Ack
      break;

      case 2: // Receive Address Ack/Nack bit
      USICTL0 &= ~USIOE; // SDA = input
      USICNT |= 0x01; // Bit counter=1, receive (N)Ack bit
      I2C_State = 4; // Go to next state: check (N)Ack
      break;

      case 4: // Process Address Ack/Nack & handle data TX

      if(Transmit == 1){
      USICTL0 |= USIOE; // SDA = output
      if (USISRL & 0x01) // If Nack received...
      { // Send stop...
      USISRL = 0x00;
      USICNT |= 0x01; // Bit counter=1, SCL high, SDA low
      I2C_State = 14; // Go to next state: generate Stop
      P1OUT |= 0x01; // Turn on LED: error
      }
      else
      { // Ack received, TX data to slave...
      USISRL = MST_Data++; // Load data byte
      USICNT |= 0x08; // Bit counter = 8, start TX
      I2C_State = 10; // next state: receive data (N)Ack
      Bytecount++;
      P1OUT &= ~0x01; // Turn off LED
      break;
      }
      } if(Transmit == 0){

      if (USISRL & 0x01) // If Nack received
      { // Prep Stop Condition
      USICTL0 |= USIOE;
      USISRL = 0x00;
      USICNT |= 0x01; // Bit counter= 1, SCL high, SDA low
      I2C_State = 8; // Go to next state: generate Stop
      P1OUT |= 0x01; // Turn on LED: error
      }
      else{ Data_RX();} // Ack received


      }
      break;

      case 6: // Send Data Ack/Nack bit
      USICTL0 |= USIOE; // SDA = output
      if (Bytecount <= number_of_bytes-2)
      { // If this is not the last byte
      USISRL = 0x00; // Send Ack
      P1OUT &= ~0x01; // LED off
      I2C_State = 4; // Go to next state: data/rcv again
      Bytecount++;
      }

      else //last byte: send NACK
      {
      USISRL = 0xFF; // Send NAck
      P1OUT |= 0x01; // LED on: end of comm
      I2C_State = 8; // stop condition
      }
      USICNT |= 0x01; // Bit counter = 1, send (N)Ack bit
      break;

      case 8: // Prep Stop Condition
      USICTL0 |= USIOE; // SDA = output
      USISRL = 0x00;
      USICNT |= 0x01; // Bit counter= 1, SCL high, SDA low
      I2C_State = 14; // Go to next state: generate Stop
      break;

      case 10: // Receive Data Ack/Nack bit
      USICTL0 &= ~USIOE; // SDA = input
      USICNT |= 0x01; // Bit counter = 1, receive (N)Ack bit
      I2C_State = 12; // Go to next state: check (N)Ack
      break;

      case 12: // Process Data Ack/Nack & send Stop
      USICTL0 |= USIOE;
      if (Bytecount == number_of_bytes){// If last byte
      USISRL = 0x00;

      I2C_State = 14; // Go to next state: generate Stop
      P1OUT |= 0x01;
      USICNT |= 0x01; } // set count=1 to trigger next state
      else{
      P1OUT &= ~0x01; // Turn off LED
      Data_TX(); // TX byte
      }
      break;

      case 14:// Generate Stop Condition
      USISRL = 0x0FF; // USISRL = 1 to release SDA
      USICTL0 |= USIGE; // Transparent latch enabled
      USICTL0 &= ~(USIGE+USIOE); // Latch/SDA output disabled
      I2C_State = 0; // Reset state machine for next xmt
      LPM0_EXIT; // Exit active for next transfer
      break;
      }

      USICTL1 &= ~USIIFG; // Clear pending flag
      }


      void Data_TX (void){

      USISRL = MST_Data++; // Load data byte
      USICNT |= 0x08; // Bit counter = 8, start TX
      I2C_State = 10; // next state: receive data (N)Ack
      Bytecount++;
      }

      void Data_RX (void){
      USICTL0 &= ~USIOE; // SDA = input --> redundant
      USICNT |= 0x08; // Bit counter = 8, RX data
      I2C_State = 6; // Next state: Test data and (N)Ack
      P1OUT &= ~0x01; // LED off
      }


      void Setup_USI_Master_TX (void)
      {
      _DINT();
      Bytecount = 0;
      Transmit = 1;
      USICTL0 = USIPE6+USIPE7+USIMST+USISWRST; // Port & USI mode setup
      USICTL1 = USII2C+USIIE; // Enable I2C mode & USI interrupt
      USICKCTL = USIDIV_7+USISSEL_2+USICKPL; // USI clk: SCL = SMCLK/128
      USICNT |= USIIFGCC; // Disable automatic clear control
      USICTL0 &= ~USISWRST; // Enable USI
      USICTL1 &= ~USIIFG; // Clear pending flag
      _EINT();
      }


      void Setup_USI_Master_RX (void)
      {
      _DINT();
      Bytecount = 0;
      Transmit = 0;
      USICTL0 = USIPE6+USIPE7+USIMST+USISWRST; // Port & USI mode setup
      USICTL1 = USII2C+USIIE; // Enable I2C mode & USI interrupt
      USICKCTL = USIDIV_7+USISSEL_2+USICKPL; // USI clks: SCL = SMCLK/128
      USICNT |= USIIFGCC; // Disable automatic clear control
      USICTL0 &= ~USISWRST; // Enable USI
      USICTL1 &= ~USIIFG; // Clear pending flag
      _EINT();

      }

      void Master_Transmit(void){
      Setup_USI_Master_TX();
      USICTL1 |= USIIFG; // Set flag and start communication
      LPM0; // CPU off, await USI interrupt
      __delay_cycles(10000); // Delay between comm cycles
      }
      void Master_Recieve(void){
      Setup_USI_Master_RX();
      USICTL1 |= USIIFG; // Set flag and start communication
      LPM0; // CPU off, await USI interrupt
      __delay_cycles(10000); // Delay between comm cycles
      }
      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • PAVAN ANAND
      Posted by PAVAN ANAND
      on Apr 12 2012 08:12 AM
      Prodigy160 points
      //******************************************************************************
      // MSP430G2x21/G2x31 Demo - I2C Master Transmitter / Reciever, multiple bytes
      //
      // Description: I2C Master communicates with I2C Slave using
      // the USI. Master data should increment from 0x55 with each transmitted byte
      // and Master determines the number of bytes recieved, set by
      // the Number_of_Bytes value. LED off for address or data Ack;
      // LED on for address or data NAck.
      // ACLK = n/a, MCLK = SMCLK = Calibrated 1MHz
      //
      //
      // ***THIS IS THE MASTER CODE***
      //
      // Slave Master
      // (msp430g2x21_usi_15.c)
      // MSP430G2x21/G2x31 MSP430G2x21/G2x31
      // ----------------- -----------------
      // /|\| XIN|- /|\| XIN|-
      // | | | | | |
      // --|RST XOUT|- --|RST XOUT|-
      // | | | |
      // LED <-|P1.0 | | |
      // | | | P1.0|-> LED
      // | SDA/P1.7|------->|P1.6/SDA |
      // | SCL/P1.6|<-------|P1.7/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>


      #define number_of_bytes 5 // How many bytes?

      void Master_Transmit(void);
      void Master_Recieve(void);

      void Setup_USI_Master_TX(void);
      void Setup_USI_Master_RX(void);

      char MST_Data = 0x55; // Variable for transmitted data
      char SLV_Addr = 0x90;
      int I2C_State, Bytecount, Transmit = 0; // State variable
      void Data_TX (void);
      void Data_RX (void);
      void main(void)
      {
      volatile unsigned int i; // Use volatile to prevent removal

      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, others to 0
      P1REN |= 0xC0; // P1.6 & P1.7 Pullups
      P1DIR = 0xFF; // Unused pins as outputs
      P2OUT = 0;
      P2DIR = 0xFF;



      while(1)
      {
      Master_Transmit();
      _NOP(); // Used for IAR

      Master_Recieve();
      _NOP();
      }
      }

      /******************************************************
      // USI interrupt service routine
      // Data Transmit : state 0 -> 2 -> 4 -> 10 -> 12 -> 14
      // Data Recieve : state 0 -> 2 -> 4 -> 6 -> 8 -> 14
      ******************************************************/
      #pragma vector = USI_VECTOR
      __interrupt void USI_TXRX (void)
      {
      switch(__even_in_range(I2C_State,14))
      {
      case 0: // Generate Start Condition & send address to slave
      P1OUT |= 0x01; // LED on: sequence start
      Bytecount = 0;
      USISRL = 0x00; // Generate Start Condition...
      USICTL0 |= USIGE+USIOE;
      USICTL0 &= ~USIGE;
      if (Transmit == 1){
      USISRL = 0x90; // Address is 0x48 << 1 bit + 0 (rw)
      }
      if (Transmit == 0){
      USISRL = 0x91; // 0x91 Address is 0x48 << 1 bit
      // + 1 for Read
      }
      USICNT = (USICNT & 0xE0) + 0x08; // Bit counter = 8, TX Address
      I2C_State = 2; // next state: rcv address (N)Ack
      break;

      case 2: // Receive Address Ack/Nack bit
      USICTL0 &= ~USIOE; // SDA = input
      USICNT |= 0x01; // Bit counter=1, receive (N)Ack bit
      I2C_State = 4; // Go to next state: check (N)Ack
      break;

      case 4: // Process Address Ack/Nack & handle data TX

      if(Transmit == 1){
      USICTL0 |= USIOE; // SDA = output
      if (USISRL & 0x01) // If Nack received...
      { // Send stop...
      USISRL = 0x00;
      USICNT |= 0x01; // Bit counter=1, SCL high, SDA low
      I2C_State = 14; // Go to next state: generate Stop
      P1OUT |= 0x01; // Turn on LED: error
      }
      else
      { // Ack received, TX data to slave...
      USISRL = MST_Data++; // Load data byte
      USICNT |= 0x08; // Bit counter = 8, start TX
      I2C_State = 10; // next state: receive data (N)Ack
      Bytecount++;
      P1OUT &= ~0x01; // Turn off LED
      break;
      }
      } if(Transmit == 0){

      if (USISRL & 0x01) // If Nack received
      { // Prep Stop Condition
      USICTL0 |= USIOE;
      USISRL = 0x00;
      USICNT |= 0x01; // Bit counter= 1, SCL high, SDA low
      I2C_State = 8; // Go to next state: generate Stop
      P1OUT |= 0x01; // Turn on LED: error
      }
      else{ Data_RX();} // Ack received


      }
      break;

      case 6: // Send Data Ack/Nack bit
      USICTL0 |= USIOE; // SDA = output
      if (Bytecount <= number_of_bytes-2)
      { // If this is not the last byte
      USISRL = 0x00; // Send Ack
      P1OUT &= ~0x01; // LED off
      I2C_State = 4; // Go to next state: data/rcv again
      Bytecount++;
      }

      else //last byte: send NACK
      {
      USISRL = 0xFF; // Send NAck
      P1OUT |= 0x01; // LED on: end of comm
      I2C_State = 8; // stop condition
      }
      USICNT |= 0x01; // Bit counter = 1, send (N)Ack bit
      break;

      case 8: // Prep Stop Condition
      USICTL0 |= USIOE; // SDA = output
      USISRL = 0x00;
      USICNT |= 0x01; // Bit counter= 1, SCL high, SDA low
      I2C_State = 14; // Go to next state: generate Stop
      break;

      case 10: // Receive Data Ack/Nack bit
      USICTL0 &= ~USIOE; // SDA = input
      USICNT |= 0x01; // Bit counter = 1, receive (N)Ack bit
      I2C_State = 12; // Go to next state: check (N)Ack
      break;

      case 12: // Process Data Ack/Nack & send Stop
      USICTL0 |= USIOE;
      if (Bytecount == number_of_bytes){// If last byte
      USISRL = 0x00;

      I2C_State = 14; // Go to next state: generate Stop
      P1OUT |= 0x01;
      USICNT |= 0x01; } // set count=1 to trigger next state
      else{
      P1OUT &= ~0x01; // Turn off LED
      Data_TX(); // TX byte
      }
      break;

      case 14:// Generate Stop Condition
      USISRL = 0x0FF; // USISRL = 1 to release SDA
      USICTL0 |= USIGE; // Transparent latch enabled
      USICTL0 &= ~(USIGE+USIOE); // Latch/SDA output disabled
      I2C_State = 0; // Reset state machine for next xmt
      LPM0_EXIT; // Exit active for next transfer
      break;
      }

      USICTL1 &= ~USIIFG; // Clear pending flag
      }


      void Data_TX (void){

      USISRL = MST_Data++; // Load data byte
      USICNT |= 0x08; // Bit counter = 8, start TX
      I2C_State = 10; // next state: receive data (N)Ack
      Bytecount++;
      }

      void Data_RX (void){
      USICTL0 &= ~USIOE; // SDA = input --> redundant
      USICNT |= 0x08; // Bit counter = 8, RX data
      I2C_State = 6; // Next state: Test data and (N)Ack
      P1OUT &= ~0x01; // LED off
      }


      void Setup_USI_Master_TX (void)
      {
      _DINT();
      Bytecount = 0;
      Transmit = 1;
      USICTL0 = USIPE6+USIPE7+USIMST+USISWRST; // Port & USI mode setup
      USICTL1 = USII2C+USIIE; // Enable I2C mode & USI interrupt
      USICKCTL = USIDIV_7+USISSEL_2+USICKPL; // USI clk: SCL = SMCLK/128
      USICNT |= USIIFGCC; // Disable automatic clear control
      USICTL0 &= ~USISWRST; // Enable USI
      USICTL1 &= ~USIIFG; // Clear pending flag
      _EINT();
      }


      void Setup_USI_Master_RX (void)
      {
      _DINT();
      Bytecount = 0;
      Transmit = 0;
      USICTL0 = USIPE6+USIPE7+USIMST+USISWRST; // Port & USI mode setup
      USICTL1 = USII2C+USIIE; // Enable I2C mode & USI interrupt
      USICKCTL = USIDIV_7+USISSEL_2+USICKPL; // USI clks: SCL = SMCLK/128
      USICNT |= USIIFGCC; // Disable automatic clear control
      USICTL0 &= ~USISWRST; // Enable USI
      USICTL1 &= ~USIIFG; // Clear pending flag
      _EINT();

      }

      void Master_Transmit(void){
      Setup_USI_Master_TX();
      USICTL1 |= USIIFG; // Set flag and start communication
      LPM0; // CPU off, await USI interrupt
      __delay_cycles(10000); // Delay between comm cycles
      }
      void Master_Recieve(void){
      Setup_USI_Master_RX();
      USICTL1 |= USIIFG; // Set flag and start communication
      LPM0; // CPU off, await USI interrupt
      __delay_cycles(10000); // Delay between comm cycles
      }
      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jens-Michael Gross
      Posted by Jens-Michael Gross
      on Apr 12 2012 10:27 AM
      Guru140085 points

      PAVAN ANAND
      i am not able to figure out where to enter the data which i need to send


      In the code you posted, the transmitter sends the value in MST_Data, then increases it. So starting with 0x55 ("U"), it will send "UVWXY" (5 bytes).

      To send an independent string, you must change the following:

      change
      char MST_Data = 0x55;
      to
      unsigned char * MST_Data = myData;

      add your data array
      unsigned char myData[number_of_bytes]="data"; // or "= {0x12, 0x34, 64, 'a', 0};"

      and change the lines containing
      USISRL=MST_Data++;
      to
      USISRL=*(MST_Data++);

      Then it will number_of_bytes bytes from myData to the slave.

      _____________________________________
      Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.
      If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • PAVAN ANAND
      Posted by PAVAN ANAND
      on Apr 13 2012 00:55 AM
      Prodigy160 points

      Thanks.That helped me a lot.

      How do I access these registers? I  have the data sheet I have to write bytes to addresses 09 and 0A

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • PAVAN ANAND
      Posted by PAVAN ANAND
      on Apr 13 2012 04:35 AM
      Prodigy160 points

      I tried the suggestions..plz tell me how to access particular registers on my chip? and to read the data is it enough if i just change the slave address and transmit variable =0?

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Leo Hendrawan
      Posted by Leo Hendrawan
      on Apr 13 2012 10:03 AM
      Mastermind27240 points

      Hi,

      i just finished creating another example with USI in I2C mode, it is available under the following wiki page:

      http://processors.wiki.ti.com/index.php/I2C_Communication_with_USI_Module

      the library provided in the example code should be more straight forward and easier to be understood.

      Comments are highly welcomed.

      -Leo-

      Regards,

      Leo Hendrawan

      I2C USI
      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jens-Michael Gross
      Posted by Jens-Michael Gross
      on Apr 13 2012 10:34 AM
      Guru140085 points

      PAVAN ANAND
      plz tell me how to access particular registers on my chip

      There are two types of registers. Processor registers and hardware registers. Processor registers are outside the scope of the C language. Since it is necessary to access the status register, the compiler provides intrinsics (pseudo-functions) like bic_SR_register(x).
      Hardware registers are mapped in teh normal processor memory space. They are accessed liek ram or flash by the processor. And for the compiler, the header files (mspxxxx.h) define them as volatile variables. So you can use them by their defined name as if they were normal variables.

      PAVAN ANAND
      and to read the data is it enough if i just change the slave address and transmit variable=0?

      ??? Sorry, I don't understand what you mean.

      _____________________________________
      Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.
      If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • PAVAN ANAND
      Posted by PAVAN ANAND
      on Apr 14 2012 23:42 PM
      Prodigy160 points

      In the program I mentioned to write data onto my eeprom chip is it enough if i change the slave address and transmit=1 to send data?

      According to the eeprom datasheet (DS1682 ETC) I have to send 1) Slave address first 2) Then the register address 3) Then the actual data

      In the program I posted above, I dont see where the registers are addressed. Where do I send register addresses?

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • PAVAN ANAND
      Posted by PAVAN ANAND
      on Apr 16 2012 07:41 AM
      Prodigy160 points

      I have to send slave address first, then the register byte then the actual data..plz reply!

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jens-Michael Gross
      Posted by Jens-Michael Gross
      on Apr 16 2012 12:33 PM
      Guru140085 points

      PAVAN ANAND
      In the program I mentioned to write data onto my eeprom chip is it enough if i change the slave address and transmit=1 to send data?

      well, yes, sort of. Actually, you don't change the address, you change the direction control bit that is part of the slave addressing byte, but not part of the slave address. However, most datasheets jsut include this bit and give two addresses for read and write.
      If you ever use an MSP with USCI module, then this bit is NOT part of the slave address (you have to specify in a separate register) and will be added by USCI hardware depending on transfer direction.

      PAVAN ANAND
      According to the eeprom datasheet (DS1682 ETC) I have to send 1) Slave address first 2) Then the register address 3) Then the actual data


      THat's the usualy way. After the start condition, you send the sklave address (7 bits), the direction bit (one bit, of course) and check for the slave ACK. THis is done for read or write identically.
      Now in write mode, you send one byte with the address, then the data. Mos tslaves simply increase teh address after each data byte. However, slaves wiht more than 8 bit (256 byte) address range may require a two-byte address.

      PAVAN ANAND
      In the program I posted above, I dont see where the registers are addressed. Where do I send register addresses?

      The program just sends a fixed sequence of bytes, beginning with 0x55 and then incrementing. It does not send independent values. Hence the correcitons/changes I suggested.

      _____________________________________
      Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.
      If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • PAVAN ANAND
      Posted by PAVAN ANAND
      on Apr 17 2012 02:05 AM
      Prodigy160 points

      Jens-michael Gross ,

      The data sheet of DS1682 specifically says that I have to send register address after sending the slave address while writing. N either my program nor your's has this facility. In my program there is facility to send slave address first then the data bytes, but where do I send the register? (I have to send register address right after I send the slave address ).

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    12
    TI E2E™ Community
    • Support Forums
    • Blogs
    • Videos
    • Groups
    • Site Support & Feedback
    • Settings
    TI E2E™ Community Groups
    • TI University Program
    • Make the Switch
    • Microcontroller Projects
    • Motor Drive & Control
    Other Communities
    • Deyisupport
    • Designsomething.org
    • beagleboard.org
    • TI on Element 14
    • TI on TechXchangeSM
    Other Technical & Support Resources
    • WEBENCH® Design Center
    • Product Information Centers
    • Technical Documents
    • TI Design Network
    • TI Technical Articles
    • TI Training

    All content and materials on this site are provided "as is". TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with regard to these materials, including but not limited to all implied warranties and conditions of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with respect to these materials. No license, either express or implied, by estoppel or otherwise, is granted by TI. Use of the information on this site may require a license from a third party, or a license from TI.

    Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms of Use of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms of Use of this site. TI, its suppliers and providers of content reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.

    Follow Us Texas Instruments on Facebook Texas Instruments on Twitter Texas Instruments on LinkedIn Texas Instruments on Google+
    TI Worldwide | Contact Us | my.TI Login | Site Map | Corporate Citizenship | mobile m.ti.com (Mobile Version)

    TI is a global semiconductor design and manufacturing company. Innovate with 100,000+ analog ICs and
    embedded processors, along with software, tools and the industry’s largest sales/support staff.

    © Copyright 1995-2013 Texas Instruments Incorporated. All rights reserved.
    Trademarks | Privacy Policy | Terms of Use