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 ;
}

