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.

MSP430F2272: Trouble with I2C

Part Number: MSP430F2272

As the title states. I am trying to get I2C working on an MSP430F2272 and am having a little trouble getting off the ground. Starting with what is essentially reformatted example code, I am simply trying to send a message in Master mode. The micro is sending something, but the data is nowhere near the I2C standard (see screen shot). I suspect I am missing something simple. Any help would be appreciated.

Thank You!


Jason

void Initialize( void )
{

    WDTCTL = WDTPW + WDTHOLD;                 // Stop Watchdog Timer
    
    P3SEL |= 0x06;                            // 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;
    


} // Initialize



void SetSector( void )
{

    UCB0I2CSA = 0x70;                  // Set slave address to Mux    
    UCB0CTL1 &= ~UCSWRST;                   // Clear SW reset, resume operation
    IE2 |= UCB0TXIE;                        // Enable TX interrupt                        //Do we need this to Tx???
    
    UCB0CTL1 |= UCTXSTT;                    // I2C TX, start condition                    //3
    UCB0TXBUF = 0x01;                    // Write DAC control byte
    UCB0CTL1 |= UCTXSTP;                    // I2C stop condition
    IFG2 &= ~UCB0TXIFG;                     // Clear USCI_B0 TX int flag
    UCB0CTL1 |= UCSWRST;                    // Enable SW reset


} //SetSector

  • Hello Jason,

    It looks like you are using neither interrupt driven I2C nor applying the correct polling I2C method here.

    If you do not want to use the interrupt driven approach with an ISR to send out the bytes, then you do not need enable the TX interrupt or clear the flag.

    For I2C if you want to use a polling method, in order to ensure the Stop Condition is sent properly after sending out your data byte you should poll for TX flag and wait for that to get triggered prior to issuing the I2C stop condition:

    while(!(IFG2 & UCB0TXIFG));
    UCB0CTL1 |= UCTXSTP; // I2C stop condition

    It also looks like you are missing the UCTR flag to start the transmission as well, which you should use in addition to the UCTXSTT flag:

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

    See if these fixes helps with your issue.

  • Hi Ralph,

    That got me a good start Byte (and an excited customer, thank you! ) but the data byte seems to still be getting corrupted. I've tried:

    -Loading the Tx Buffer Earlier

    -Adding the Tx Flag Delay before loading the Tx Buffer (See commented out line)

    The latest Code:



    void Initialize( void )
    {

        int StartupLoop = 0;


        WDTCTL = WDTPW + WDTHOLD;                 // Stop Watchdog Timer
        
        for(StartupLoop = 10000; StartupLoop > 1; StartupLoop--)
        {
            _nop();
        }
        
        P3DIR |= 0x80;                            //Set ~Comm_Reset as output
        P3OUT |= P3_COMM_RESET_N;
        
        P3SEL |= 0x06;                            // 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;


    }


    void SetSector( void )
    {

        UCB0I2CSA = 0x70;                      // Set slave address to Mux    
        UCB0CTL1 &= ~UCSWRST;                   // Clear SW reset, resume operation
        UCB0CTL1 |= UCTR + UCTXSTT;                // I2C TX, start condition                    //3

    //    while(!( IFG2 & UCB0TXIFG ));        //wait for Tx flag.        Is this Needed?
        
        UCB0TXBUF = 0x01;            // Write control byte    

        while(!( IFG2 & UCB0TXIFG ));        //wait for Tx flag.
        
        UCB0CTL1 |= UCTXSTP;                    // I2C stop condition
        UCB0CTL1 |= UCSWRST;                    // Enable SW reset
    }

  • Hi Jason,

    Hmm, perhaps the SW Reset may be triggering too fast...

    Try:

    UCB0CTL1 |= UCTXSTP; // I2C stop condition
    while (UCB0CTL1 & UCTXSTP); // This is to ensure stop condition got sent
    UCB0CTL1 |= UCSWRST; // Enable SW reset

    Also while on the topic, it can be a good practice to use the "while (UCB0CTL1 & UCTXSTP); " line just before starting I2C TX as well just to be sure it's in a good state.

**Attention** This is a public forum