Last week, I mentioned that in order for the I2C bus to function correctly when using the MSP430 Launchpad you might need to remove the jumper on P1.6. This is because P1.6 is the SCL pin and the connected LED may cause the output voltage to stray from the desired logic voltage levels. In this post, I will show a couple of examples of using the MSP430 Launchpad as an I2C master to communicate with slave devices. The library code can be downloaded towards the end.

The I2C code I am using is adapted from the I2C Explorer project on 43oh forum. In both examples, the MCU is configured as I2C master. For more detailed background information on implementing I2C on MSP430G2 devices, you can check out this TI Wiki. Also you can refer to TI’s MSP430x2xx Family User’s Guide for more details. The code examples included here are built under TI’s Code Composer Studio V5.1 for MSP430G2231. But the same code can be used with any chips within the MSP430G2 family that supports the I2C functionality by simply changing the header file in the include statement.

My first example shows how to set the output frequency of the programmable oscillator LTC6904. If you are interested in the Arduino implementation, you can check out this post from last year. The full code listings can be found at the end.

#include <msp430g2231.h>
#include "i2c.h"

unsigned char i2cAddress = 0x17;

void setFreq() //~4158 Hz
  unsigned int oct = 2;
  unsigned int dac = 1;

  unsigned int reg = oct << 12 | dac << 2;

  unsigned char high = (reg >> 8) & 0xff;
  unsigned char low = reg & 0xff;

  i2c_write8(i2cAddress << 1);

void main(void) {


As you can see, the implementation is pretty straightforward. The I2C communication begins by initiating a start condition. The slave 7-bit address is then followed. Note that the LSB indicates whether the operation is a read or write. In our case, we wanted to write to the configuration register and thus the address was simply left shifted by one leaving the LSB zero. Then the desired register content was sent over in two writes, first the high byte and then the low byte. Finally, a stop condition is issued to indicate the end of the communication.

The following table compares the I2C library calls used here with those in the standard Arduino library:

Arduino MSP430G2
Write to address Wire.beginTransmission(I2C addr); i2c_start();
i2c_write8(I2C addr << 1);
Write data Wire.write(data byte); i2c_write8(data byte);
Read from address Wire.requestFrom(I2C addr, number of bytes); i2c_start();
i2c_write8(I2C addr << 1 | 1);
*note that the number of bytes is determined by the number of reads followed
Read data; i2c_read8(0x0);
End communication Wire.endTransmission(); i2c_stop();

The second example shows how to interface with a digital thermometer DS7505. The code listed below are translated from the Arduino library I created earlier. You can check the table above to see how the I2C communications are implemented.

#include <msp430g2231.h>
#include "i2c.h"

//Resolution Definition
//R1 R0
unsigned char RES_09 = 0x0; // 9 bit res;
unsigned char RES_10 = 0x1; //10 bit res;
unsigned char RES_11 = 0x2; //11 bit res;
unsigned char RES_12 = 0x3; //12 bit res;

//Fault Tolerance Configuration
//F1 F0
unsigned char FT_1 = 0x0; //fault tolerance consecutive out of limits 1
unsigned char FT_2 = 0x1; //fault tolerance consecutive out of limits 2
unsigned char FT_4 = 0x2; //fault tolerance consecutive out of limits 4
unsigned char FT_6 = 0x3; //fault tolerance consecutive out of limits 6

//Register Pointer Definition
//P1 P0
unsigned char P_TEMP = 0x0; //temperature
unsigned char P_CONF = 0x1; //configuration
unsigned char P_THYST = 0x2; //Thyst
unsigned char P_TOS = 0x3; //Tos

//command set
unsigned char CMD_RECALL_DATA = 0xB8;
unsigned char CMD_COPY_DATA = 0x48;
unsigned char CMD_POR = 0x54;

unsigned char Resolution;
unsigned char A2, A1, A0;
unsigned char I2CAddr;
unsigned char ConfigByte;

float t;

//set configuration byte
//bit 7: NVB (NV Memory Status), read-only
//bit 6: R1 (Conversion Resolution Bit 1)
//bit 5: R0 (Conversion Resolution Bit 0)
//bit 4: F1 (Thermostat Fault Tolerance Bit 1)
//bit 3: F0 (Thermostat Fault Tolerance Bit 0)
//bit 2: POL (Thermostat Output Polarity)
//bit 1: TM (Thermostat Operating Mode)
//bit 0: SD (Shutdown)
void DS7505_setConfigRegister(unsigned char configByte)
	i2c_write8(I2CAddr << 1);

//get temperature in Celsius
float DS7505_getTemp(unsigned char regPdef)
  float temp = 0.0;
  float s = 1.0;

  unsigned char h = 0, l = 0;

  i2c_write8(I2CAddr << 1);

  i2c_write8(I2CAddr << 1  | 1);
  h = i2c_read8(0x0);
  l = i2c_read8(0x0);

  if (h & 0x80 == 0x80) {
    s = -1.0;
    h = h & 0x7f;
  else {
    s = 1.0;

  temp = s * 0.5 * ((l & 0x80 )>> 7) + 0.25 * ((l & 0x40 )>> 6)+ 0.125 * ((l & 0x20 )>> 5) + 0.0625 * ((l & 0x10 )>> 4) + (float) h;

  return temp;

//Initialize DS7505
//a2, a1, a0 are either HIGH (1) or LOW (0) depending
//on the pin setup.
//res: temperature resolution. 9, 10, 11, 12 (default is 12)
void DS7505_init(unsigned char a2, unsigned char a1, unsigned char a0, unsigned char res)
  A2 = a2;
  A1 = a1;
  A0 = a0;
  Resolution = res;
  ConfigByte = 0;

  I2CAddr = 0x48 | (A2 << 2 | A1 << 1 | A0);

  switch (Resolution)
  case 9:
    ConfigByte = RES_09 << 5;
  case 10:
    ConfigByte = RES_10 << 5;
  case 11:
    ConfigByte = RES_11 << 5;
  case 12:
    ConfigByte = RES_12 << 5;
    ConfigByte = RES_12 << 5;


float getTemp()
	 t =  9.0/5.0 * DS7505_getTemp(P_TEMP) + 32.0;
	return t;

void main(void) {

	DS7505_init(0, 0, 0, 12);

	while (1) {


MSP430G2231 I2C library: msp430g2231_i2c_lib.tar.gz
I2C example (LTC6904): I2C_LTC6904_2231.tar.gz
I2C example (DS7505): I2C_DS7505_2231.tar.gz

More Examples

Reading SHT21 Using TI MSP430 LaunchPad
Interfacing DS3232 RTC With MSP430G2452

Be Sociable, Share!