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.

Polling-based I2C with MSP430G2553

Other Parts Discussed in Thread: MSP430G2553

Hi all, I hve with me the MSP430G@ launchaped mounted with an MSP430G2553.
I want to interface an I2C slave with the MSP, allowing reads, and writes to the slave.
TI has provided I2C interrupt-based code; I'm interested in polling-based code.
I've searched online without any luck. I did however find a snippet, here, on this forum.

I haven't connected any device to MSP, since I wanted to be sure that the waveforms are being output correctly.
However, the waveforms are the same no matter what slave address I hard-code.

I've disconnected the jumper on P1.6 on the launchpad, and have connected pull-ups.

Here are the waveforms for slaves 0x55, and 0xAA.


The code is copied below.

what am I doing wrong?


#include <msp430.h>

/*
 * main.c
 */

#define BATT_SLAVE_ADDR    (0x6B)
//#define BATT_SLAVE_ADDR    (0x00)

int clock_1s;

static int I2C_start_and_write (unsigned char argData, unsigned char argAddress) ;
void ConfigClocks(void);
void ConfigLEDs(void);
void ConfigTimerA0(void);
void ConfigI2C(void);

int main(void) {
    WDTCTL = WDTPW | WDTHOLD;    // Stop watchdog timer

    ConfigClocks();
    ConfigLEDs();
    ConfigTimerA0();
    ConfigI2C();

    _BIS_SR(GIE);
    
    while(1)
    {
        if(clock_1s)
        {
            clock_1s = 0 ;
            I2C_start_and_write(0xFF, 0xAA);
        }
    }
}

void ConfigClocks(void)
{
    BCSCTL1 = CALBC1_1MHZ; // Set range
    DCOCTL = CALDCO_1MHZ; // Set DCO step + modulation
    BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO
    IFG1 &= ~OFIFG; // Clear OSCFault flag
    BCSCTL2 |= SELM_0 + DIVM_3 + DIVS_3; // MCLK = DCO/8, SMCLK = DCO/8
}

void ConfigLEDs(void)
{
    P1DIR = BIT0; // P1.0 output
    P1OUT = 0; // LED off
}


#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer0_AO (void)
{
    static int p ;

    clock_1s = 1 ;
    if(++p&1)
        P1OUT |= (1<<0) ;
    else
        P1OUT &= ~(1<<0) ;
    CCR0 +=12000;
}


void ConfigTimerA0(void)
{
    CCTL0 = CCIE;
    CCR0 = 12000;
    TACTL = TASSEL_1 + MC_2;
}

void ConfigI2C(void)
{
    P1SEL |= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
    P1SEL2|= BIT6 + BIT7;                     // 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 = BATT_SLAVE_ADDR;              // Set slave address
    UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
}

int I2C_start_and_write (unsigned char argData, unsigned char argAddress)
{
    int retVal__SAW = 0 ;        //default return 0

    // wait for the end of any previous activity on the bus
    while (UCB0CTL1 & UCTXSTP);

    // Set the slave address
    UCB0I2CSA = argAddress;

    // set UCTR for transmitter mode
    UCB0CTL1 |= UCTR ;

    // set UCTXSTT to generate a START condition
    // (the slave address is automatically sent after the START condition)
    UCB0CTL1 |=  UCTXSTT ;

    // wait until the START condition has been sent
    while ( !(IFG2 & UCB0TXIFG));

    // immediately write the data on the I2C bus
    UCB0TXBUF = argData;

    // wait for slave to acknowledge
    while (UCB0CTL1 & UCTXSTT);

    // if not acknowledge
    if (UCB0STAT & UCNACKIFG)
    {
        retVal__SAW = 1;
    }
    else
    {
        retVal__SAW = 2 ;
    }

    // Generate stop condition
    UCB0CTL1 |= UCTXSTP ;

    return retVal__SAW ;
}

**Attention** This is a public forum