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.

Trouble with I2C on MSP430F5529

Other Parts Discussed in Thread: MSP430F5529

Hey guys,


I'm having a little trouble getting I2C set up on my MSP430F5529. I'm attempting to send commands to a Newhaven LCD using the TI example "MSP430F55xx_uscib0_i2c_08.c". The address of my LCD is 0x50. Also, the LCD has command prefixes of 0xFE. I'm attempting to turn on the LCD with the command 0x41 and then just write "C" with 0x43. However, the LCD is not receiving the commands. The code I'm using is below.

I also have an oscilloscope hooked up to the Data and Clock lines. Through experimentation, I've noticed that with "WDTCTL = WDTPW + WDTHOLD; // Stop WDT" in the code, there is no activity on the Data or Clock line. However, with that line removed, I can see the address of the slave being sent over and over again.

Any help is greatly appreciated.

#include <msp430.h>

unsigned char *PTxData;                     // Pointer to TX data
unsigned char TXByteCtr;

const unsigned char TxData[] =              // Table of data to transmit
{
  0xFE,
  0x41,
  0x43};

int main(void)
{
  unsigned int i;

  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  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 + UCSWRST;            // Use SMCLK, keep SW reset
  UCB0BR0 = 12;                             // fSCL = SMCLK/12 = ~100kHz
  UCB0BR1 = 0;
  UCB0I2CSA = 0x50;                         // Slave Address is 048h
  UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
  UCB0IE |= UCTXIE;                         // Enable TX interrupt

  while (1)
  {
    for(i=0;i<10;i++);                      // 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

    UCB0CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition
    
    __bis_SR_register(LPM0_bits + GIE);     // Enter LPM0, enable interrupts
    __no_operation();                       // Remain in LPM0 until all data
                                            // is TX'd
    while (UCB0CTL1 & UCTXSTP);             // Ensure stop condition got sent
  }
}

//------------------------------------------------------------------------------
// 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_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
{
  switch(__even_in_range(UCB0IV,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
    {
      UCB0TXBUF = *PTxData++;               // Load TX buffer
      TXByteCtr--;                          // Decrement TX byte counter
    }
    else
    {
      UCB0CTL1 |= UCTXSTP;                  // I2C stop condition
      UCB0IFG &= ~UCTXIFG;                  // Clear USCI_B0 TX int flag
      __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
    }  
  default: break;
  }
}

  • You only changed the adress and the payload of the example, so I guess the code is not your problem, because the default parameters are ok (100 kHz clock is supported by every device). I think that your display is not responding and you're just missing the first try to address on your oscilloscope. With the watchdog enabled, the MSP gets reset about 30 times per second and tries over and over again. Just check the ACK bit (SDA low after the address bits have been sent).

    Are you sure about the wiring? Did you enable I2C mode (R1 jumper on most Newhaven LCDs)?

  • Hey Michael,

    I appreciate the response. I believe you could be correct. After running the code on the MSP430, both the Data and Clock lines stay low.


    I'm pretty confident in my LCD wiring. I did short R1 and I'm only using 4 pins on the LCD: Vcc, GND, SDA, SCL.

    I'm thinking I may need to add some delay within the code.

  • The code itself is fine. You don't need a delay between bytes of one single command. The most important thing is to check if the ACK bit is set by the slave. Do you have access to a storage oscilloscope? Or a logic analyzer?

  • I do have a digital storage oscilloscope at work. I may have to take my setup with me and investigate.. 

  • i am having msp430f5529 and oled i2c display(http://www.drotek.fr/shop/en/home/115-i2c-oled-display-module-arduino.html)...can i interface oled with msp430f5529?

**Attention** This is a public forum