Jump to content
43oh

I2c in msp430fg4618


Recommended Posts

I wish to interface the digital compass with msp430fg4618 for which I need to use I2C.

 

Do you have a sample code for I2c? Don't show me the ti sample code. I need something else other than that with some good explanations or good comments. I know about I2C so you need not send any link related to I2C. I just would like to know how to do it in msp430fg4618 with some clear explanation.

 

If you have done I2C before I would be really happy if you could share it with me.

 

Actually I tried I2c using that ti sample code but the problem is when I view the clock signal ,which should come from the msp, in the oscilloscope I don't get any wave at all so I believe that something is wrong with the code.

 

 

Thanks in advance. :D:D:D:D

Link to post
Share on other sites

Here's the code for sensing the thermometer (which is inbuilt in msp430fg4618/f2013 experimenter's board). What I have done is getting the data from the thermometer through I2c and then I have displayed in the lcd. (I have even given the jumper connection perfectly).

 

I tried this code but I always get 0 deg celcius in the LCD display no matter what happens.

 

Just see the main() function. All other things are just definition of functions that I have used in the main() function. Also I am sure that nothing is wrong with all these additional functions because these functions work perfectly with other programs. I am just doubtful about the main() function.

 

 


#include  //
#include  // Intrinsic functions
#include  // Integers of defined sizes
#define SLAVE_ADDRESS 0x48 // I2C address of thermometer
//#define LED P5OUT_bit.P5OUT_1 // Output pin for LED (active high)
// Pin is output low by default


#define	LCDDIGITS	7					// Number of digits in display
#define LCDMEMS		11					// LCD memories used (3-13)
// Pointer to LCD memory used: allows use of array LCDMem[]
uint8_t * const LCDMem = (uint8_t *) &LCDM3;
// LCD segment definitions (SoftBaugh SBLCDA4)
#define SEG_A   BIT0					//  AAAA
#define SEG_B   BIT1					// F    B
#define SEG_C   BIT2					// F    B
#define SEG_D   BIT3					//  GGGG
#define SEG_E   BIT6					// E    C
#define SEG_F   BIT4					// E    C
#define SEG_G   BIT5					//  DDDD
#define SEG_H   BIT7					// colon, point etc
// Patterns for hexadecimal characters
const uint8_t LCDHexChar[] = {
SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F,			// "0"
SEG_B | SEG_C,											// "1"
SEG_A | SEG_B | SEG_D | SEG_E | SEG_G,					// "2"
SEG_A | SEG_B | SEG_C | SEG_D | SEG_G,					// "3"
SEG_B | SEG_C | SEG_F | SEG_G,							// "4"
SEG_A | SEG_C | SEG_D | SEG_F | SEG_G,					// "5"
SEG_A | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G,			// "6"
SEG_A | SEG_B | SEG_C,									// "7"
SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G,	// "8"
SEG_A | SEG_B | SEG_C | SEG_D | SEG_F | SEG_G,			// "9"
SEG_A | SEG_B | SEG_C | SEG_E | SEG_F | SEG_G,			// "A"
SEG_C | SEG_D | SEG_E | SEG_F | SEG_G,					// "b"
SEG_A | SEG_D | SEG_E | SEG_F,							// "C"
SEG_B | SEG_C | SEG_D | SEG_E | SEG_G,					// "d"
SEG_A | SEG_D | SEG_E | SEG_F | SEG_G,					// "E"
SEG_A | SEG_E | SEG_F | SEG_G,							// "F"
};
// More useful patterns
const uint8_t LCDhexChar = SEG_C | SEG_E | SEG_F | SEG_G;
const uint8_t LCDAMChar = SEG_A | SEG_B | SEG_C | SEG_E | SEG_F | SEG_G;
const uint8_t LCDPMChar = SEG_A | SEG_B | SEG_E | SEG_F | SEG_G;
const uint8_t LCDMinusChar = SEG_G;
const uint8_t LCDCChar = SEG_A | SEG_D | SEG_E | SEG_F;
const uint8_t LCDEChar = SEG_A | SEG_D | SEG_E | SEG_F | SEG_G;
const uint8_t LCDHChar = SEG_B | SEG_C | SEG_E | SEG_F | SEG_G;
const uint8_t LCDhChar = SEG_C | SEG_E | SEG_F | SEG_G;
const uint8_t LCDLChar = SEG_D | SEG_E | SEG_F;
const uint8_t LCDOChar = SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F;
const uint8_t LCDoChar = SEG_C | SEG_D | SEG_E | SEG_G;
const uint8_t LCDrChar = SEG_E | SEG_G;
const uint8_t LCDdegChar = SEG_A | SEG_B | SEG_F | SEG_G;
const uint8_t LCDBlankChar = 0;
// Segments of "digit 10", half-digit on right plus special symbols
#define	ONESEG		BIT3			// '1' (only one logical segment)
#define	DOLLARSEG	BIT4			// '$'
#define	ERRORSEG	BIT5			// 'E' marker
#define	MINUSSEG	BIT6			// '-' marker
#define	MEMSEG		BIT7			// 'M' marker
//----------------------------------------------------------------------
// Initialize SBLCDA4
//----------------------------------------------------------------------
void LCDInit (void)
{
int i;
for(i = 0; i < LCDMEMS; ++i) {		// Clear LCD memory used
	LCDMem[i] = 0;
}
P5SEL = BIT4|BIT3|BIT2;				// Select COM[3] function
LCDAPCTL0 = LCDS4|LCDS8|LCDS12|LCDS16|LCDS20|LCDS24;
							// Enable LCD segs 4-27 (4-25 used)
LCDAVCTL0 = 0;				// No charge pump, everything internal
LCDACTL = LCDFREQ_128 | LCD4MUX | LCDSON | LCDON;
							// ACLK/128, 4mux, segments on, LCD_A on
}
//----------------------------------------------------------------------
// Display word in hexadecimal, 4 digits followed by 'h' (or 'H')
//----------------------------------------------------------------------

uint32_t UintToBCD (uint16_t UIntValue)
{
uint32_t converted;
uint8_t i;

converted = 0;
for (i = 0; i < 16; ++i) {
	converted = __bcd_add_long (converted, converted);
	if ((UIntValue & BITF) != 0) {
		converted = __bcd_add_long (converted, 1);
	}
	UIntValue <<= 1;
}
return converted;
}


void DisplayHex (uint16_t HexValue)
{
uint8_t i;						// Index for LCD array

LCDMem[0] = LCDhChar;			// 'h' for hexadecimal on right
for (i = 1; i <= 4; ++i) {		// Display 4 hex digits
	LCDMem[i] = LCDHexChar[HexValue & 0x000F];
	HexValue >>= 4;				// Move next nibble into position
}
while (i < LCDDIGITS) {			// Clear more significant digits
	LCDMem[i++] = LCDBlankChar;	//   of numerical display
}
}
//----------------------------------------------------------------------
// Display unsigned, 16-bit integer (uint16_t)
// Convert to BCD and display
// Leading zeros suppressed; BCD value does not exceed 5 digits
//----------------------------------------------------------------------
void DisplayUint (uint16_t UintValue)
{
uint8_t i;							// Index for LCD array
uint32_t BCDValue;					// Value converted bin to BCD

BCDValue = UintToBCD (UintValue);	// Convert binary to BCD
i = 0;								// Index for LCD memories
do {								// Store pattern for next digit
	LCDMem[i++] = LCDHexChar[bCDValue & 0x000F];
	BCDValue >>= 4;					// Move next nibble down
} while (BCDValue > 0);				// (Always display first digit)
while (i < LCDDIGITS) {				// Clear more significant digits
	LCDMem[i++] = LCDBlankChar;		//   of numerical display
}
}
//----------------------------------------------------------------------
// Display unsigned, 32-bit integer (uint32_t) up to 19,999,999
// Convert to BCD if it fits and display with leading zeros suppressed
//----------------------------------------------------------------------
void DisplayUlint (uint32_t UlintValue)
{
uint8_t i;							// Index for LCD array
uint32_t BCDValue;					// Value converted bin to BCD

if (UlintValue <= 9999999) {
	BCDValue = UlintToBCD (UlintValue);	// Convert binary to BCD
	i = 0;							// Index for LCD memories
	do {							// Store pattern for next digit
		LCDMem[i++] = LCDHexChar[bCDValue & 0x000F];
		BCDValue >>= 4;				// Move next nibble down
	} while (BCDValue > 0);			// (Always display first digit)
	while (i < LCDDIGITS) {		// Clear more significant digits
		LCDMem[i++] = LCDBlankChar;	//   of numerical display
	}
	LCDMem[10] = LCDBlankChar;		// Special segment for "1"
} else if (UlintValue <= 19999999) {	// Needs special treatment
	BCDValue = UlintToBCD (UlintValue);	// Convert binary to BCD
	for (i = 0; i < LCDDIGITS; ++i) {
		LCDMem[i] = LCDHexChar[bCDValue & 0x000F];
		BCDValue >>= 4;				// Move next nibble down
	}
	LCDMem[10] = ONESEG;			// Special segment for "1"
} else {
	LCDMem[10] = LCDBlankChar;		// Special segment for "1"
}
}
//----------------------------------------------------------------------
// Display signed, 16-bit integer (int16_t)
// Strip sign, convert unsigned value to BCD and display
// Leading zeros suppressed; BCD value does not exceed 5 digits
//----------------------------------------------------------------------
void DisplayInt (int16_t IntValue)
{
uint8_t i;							// Index for LCD array
uint32_t BCDValue;					// Value converted bin to BCD
enum {plus, minus} sign;

if (IntValue >= 0) {				// Keep track of sign
	sign = plus;
} else {
	sign = minus;
	IntValue = -IntValue;			// Conversion needs IntValue>=0
}
BCDValue = UintToBCD (IntValue);	// Convert binary to BCD
i = 0;								// Index for LCD memories
do {								// Store pattern for next digit
	LCDMem[i++] = LCDHexChar[bCDValue & 0x000F];
	BCDValue >>= 4;					// Move next nibble down
} while (BCDValue > 0);				// (Always display first digit)
if (sign == minus) {
	LCDMem[i++] = LCDMinusChar;		// Prepend minus sign
}
while (i < LCDDIGITS) {				// Clear more significant digits
	LCDMem[i++] = LCDBlankChar;		//   of numerical display
}
}
//----------------------------------------------------------------------
// Display temperature (-99.9 to 999.9 deg C) to 0.1 degree celsius
// Leave far right character blank to get decimal point in correct place
//----------------------------------------------------------------------
void DisplayDeciCels (int16_t Temperature)
{
uint8_t i;							// Index for LCD array
uint32_t BCDValue;					// Value converted bin to BCD
enum {plus, minus} sign;

if (Temperature >= 0) {				// Keep track of sign
	sign = plus;
	if (Temperature > 9999) {		// Bring value within range;
		Temperature = 9999;			//   only 4 characters available
	}								//   to show positive values
} else {
	sign = minus;
	Temperature = -Temperature;		// Conversion needs value >= 0
	if (Temperature > 999) {		// Only 3 characters available
		Temperature = 999;			//   to show negative values
	}
}									//   (lose one for - sign)
BCDValue = UintToBCD (Temperature);	// Convert binary to BCD
i = 0;								// Index for LCD memories
LCDMem[i++] = LCDBlankChar;			// Leave rightmost space blank
LCDMem[i++] = LCDCChar;				// Show 'C'
LCDMem[i++] = LCDdegChar;			// Show degree sign
// Least significant digit is tenths with decimal point
LCDMem[i++] = LCDHexChar[bCDValue & 0x000F] | SEG_H;
BCDValue >>= 4;						// Move next nibble down
do {								// Store pattern for next digit
	LCDMem[i++] = LCDHexChar[bCDValue & 0x000F];
	BCDValue >>= 4;					// Move next nibble down
} while (BCDValue > 0);				// (Always display units digit)
if (sign == minus) {
	LCDMem[i++] = LCDMinusChar;		// Prepend minus sign
}
while (i < LCDDIGITS) {				// Clear more significant digits
	LCDMem[i++] = LCDBlankChar;		//   of numerical display
}
}
//----------------------------------------------------------------------
// Display temperature (-99.99 to 999.99 deg C) to 0.01 degree celsius
//----------------------------------------------------------------------
void DisplayCentiCels (int16_t Temperature)
{
uint8_t i;							// Index for LCD array
uint32_t BCDValue;					// Value converted bin to BCD
enum {plus, minus} sign;

if (Temperature >= 0) {				// Keep track of sign
	sign = plus;					// Value always fits on display
} else {
	sign = minus;
	Temperature = -Temperature;		// Conversion needs value >= 0
	if (Temperature > 9999) {		// Only 4 characters available
		Temperature = 9999;			//   to show negative values
	}
}									//   (lose one for - sign)
BCDValue = UintToBCD (Temperature);	// Convert binary to BCD
i = 0;								// Index for LCD memories
LCDMem[i++] = LCDCChar;				// Show 'C'
LCDMem[i++] = LCDdegChar;			// Show degree sign
LCDMem[i++] = LCDHexChar[bCDValue & 0x000F];	// Hundredths
BCDValue >>= 4;						// Move next nibble down
// Next significant digit is tenths with decimal point
LCDMem[i++] = LCDHexChar[bCDValue & 0x000F] | SEG_H;
BCDValue >>= 4;						// Move next nibble down
do {								// Store pattern for next digit
	LCDMem[i++] = LCDHexChar[bCDValue & 0x000F];
	BCDValue >>= 4;					// Move next nibble down
} while (BCDValue > 0);				// (Always display units digit)
if (sign == minus) {
	LCDMem[i++] = LCDMinusChar;		// Prepend minus sign
}
while (i < LCDDIGITS) {				// Clear more significant digits
	LCDMem[i++] = LCDBlankChar;		//   of numerical display
}
}
//----------------------------------------------------------------------
// Display line of hyphens ----- across LCD to show that it is alive
//----------------------------------------------------------------------
void DisplayLine (void)
{
uint8_t i;							// Index for LCD array

for (i = 0;	i < LCDDIGITS; ++i) {	// Step through digits
	LCDMem[i] = LCDMinusChar;		//   of numerical display
}
}

//----------------------------------------------------------------------
// Display "HELLO" on LCD (need a less clumsy routine?)
//----------------------------------------------------------------------
void DisplayHello (void)
{
uint8_t i;							// Index for LCD array

LCDMem[0] = LCDOChar;
LCDMem[1] = LCDLChar;
LCDMem[2] = LCDLChar;
LCDMem[3] = LCDEChar;
LCDMem[4] = LCDHChar;
for (i = 5;	i < LCDDIGITS; ++i) {	// Step through digits
	LCDMem[i] = LCDBlankChar;		//   of numerical display
}
}
//----------------------------------------------------------------------
// Initialize ports for board: pins are outputs driven low by default
// Many of these will be overwritten by LCD initialization later
//----------------------------------------------------------------------
void PortsInit (void)
{
// Port 1: 0 = SW1, 1 = SW2, others used for Chipcon (not placed)
P1OUT = 0;
P1DIR = 0xFF & ~(BIT0|BIT1);		// P1.0,1 input, others output
// Port 2: 1 = LED2, 2 = LED1, 3 = mic power, 4 = UCA0TXD, 5 = UCA0RXD
P2OUT = 0;
P2DIR = 0xFF & ~BIT5;				// P2.5 must be input
// Port 3: 0-3 = comms with F2013, 5 = buzzer (active low)
P3OUT = BIT1 | BIT2 | BIT5;			// F2013 might tie 1,2 high;
P3DIR = 0xFF;						//   P3.5 high for buzzer off
// Port 4: 2-5 used for Chipcon (not placed)
P4OUT = 0;
P4DIR = 0xFF;
// Port 5: 1 = LED4, 2-4 = COM1-3 for LCD
P5OUT = 0;
P5DIR = 0xFF;
// Port 6: All except 6 used for opamp external components
P6OUT = 0;
P6DIR = 0xFF;
// Port 7: 4-7 = LCD segments
P7OUT = 0;
P7DIR = 0xFF;
// Port 8: LCD segments
P8OUT = 0;
P8DIR = 0xFF;
// Port 9: LCD segments
P9OUT = 0;
P9DIR = 0xFF;
// Port 10: 0-5 = LCD segments
P10OUT = 0;
P10DIR = 0xFF;
}





void main (void)
{
volatile uint16_t i; // Loop counter to stabilize FLL+
int16_t Temperature; // Value received over I2C
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
FLL_CTL0 = XCAP14PF; // 14pF load caps; 1MHz default
do { // Wait until FLL has locked
for (i = 0x2700; i > 0; --i) { // One loop should be enough
} // Delay for FLL+ to lock

//IFG1_bit.OFIFG = 0; // Attempt to clear osc fault flag

IFG1&=~OFIFG;
} while (IFG1 & OFIFG != 0); // Repeat if not yet clear
PortsInit (); // Initialize ports
LCDInit (); // Initialize SBLCDA4
DisplayHello (); // Display HELLO on LCD
P3SEL = BIT1 | BIT2; // Route pins to USCI_B for I2C
// 7-bit addresses (default), single master , master mode , I2C , synch
UCB0CTL0 = UCMST | UCMODE_3 | UCSYNC;
// Clock from SMCLK , receiver (default), hold in reset
UCB0CTL1 = UCSSEL1 | UCSWRST;
UCB0BR1 = 0; // Upper byte of divider word
UCB0BR0 = 10; // Clock = SMCLK / 10 = 100 KHz
UCB0I2COA = 0; // Ignore genl call; own address = 0
UCB0CTL1 &= ~UCSWRST; // Release from reset
// Set up basic timer for interrupts at 2Hz (500ms)
BTCTL = BTHOLD | BT_ADLY_500; // Hold , period = 500ms from ACLK
BTCNT2 = 0; // Clear counter
BTCTL &= ~BTHOLD; // Start basic timer

//IE2_bit.BTIE = 1; // Enable basic timer interrupts

IE2|= BTIE;
for (; { // Transfers triggered by BT
__low_power_mode_3 (); // Wait for BT (needs only ACLK)

//LED = 1; // Show start of activity

P5OUT= BIT1;
UCB0I2CSA = SLAVE_ADDRESS; // Slave to be addressed
UCB0CTL1 |= UCTXSTT; // Send Start and slave address
while (( UCB0CTL1 & UCTXSTT) != 0) {
} // Wait for address to be sent
if (( UCB0STAT & UCNACKIFG) != 0) { // Address NOT acknowledged?
UCB0CTL1 |= UCTXSTP; // Send Stop condition and finish
} else { // Address acknowledged: receive
while (IFG2 & UCB0RXIFG == 0) {
} // Wait for first byte
Temperature = UCB0RXBUF << 8; // MSB of temperature
UCB0CTL1 |= UCTXSTP; // Send Stop condition after byte
while (IFG2 & UCB0RXIFG == 0) {
} // Wait for second byte
Temperature |= UCB0RXBUF; // LSB of temperature
DisplayCentiCels (Temperature); // Display temp to 0.01oC
}
P5OUT &= ~BIT1; // Show end of activity
}
}
// ----------------------------------------------------------------------
// ISR for basic timer: return to main routine
// ----------------------------------------------------------------------
#pragma vector = BASICTIMER_VECTOR
__interrupt void BASICTIMER_ISR (void) // Acknowledged automatically
{
__low_power_mode_off_on_exit(); // Return to start new I2C message
}

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...