I tried interfacing the inbuilt thermometer with the msp430fg4618 in the experimenter's board.
I connected the jumpers in PWR2 and then H1- 1 2 and 3 4 pins. I tried displaying the temperature in the lcd but I don't get anything. I am very sure that nothing is wrong in the additional functions that I have written apart from main() as those functions worked perfectly with other programs. Also when I touched some places in msp430f2013 then I get 0 degree celcius in the lcd.
Just see the main() part.
Here's the code
#include <msp430fg4618.h> //
#include <intrinsics.h> // Intrinsic functions
#include <stdint.h> // 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:1] 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 = UCSSEL_2 | 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)
// I can't find "BT_ADLY_500" anywhere in the family user guide.
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
}