MSP430 - ADC Interface - Digital Thermometer

Now that we have three digits being displayed, what can we do with them?

The first project that comes to mind is a digital thermometer. We will use the popular LM35 temperature sensor which outputs an increasing voltage as the temperature rises. The transfer function of the LM35 is a linear rise of 10mV per °C. Thus the output is 250mV at 25°C.

Before we interface the LM35 sensor to the MSP430G2553, we need to program the mcu to read an analog voltage via one of the input/output pins. We are already using P1.0 to P1.6 for the LED segment outputs. So we have P1.7 available at pin-15.

The best thing to do before applying the voltage out from the LM35 is to use an adjustable voltage for testing. With this, we can quickly verify that our program and voltage connections are working properly.

So we connect a variable resistor as a potentiometer or "pot" (a.k.a. potential divider) as shown in the diagram. A 10-turn precision pot will allow for much finer control.


Here is the test program:

Code:
//--------------------------------------------------------
// Project #2 - Multiplexed Seven-segment LED interface
// ADC Interface - Digital Thermometer
// 2013.06.18 - MrChips
//--------------------------------------------------------

#include "io430.h"

#define NUMBER_OF_DIGITS 3
#define DELAY 1000
#define TIMER_DELAY 630

char seg[16];
char d[5];
char digit;
short v;

// simple software delay
void delay(unsigned long d)
{
  unsigned long i;
  for (i = 0; i < d; i++);
}

void display_hex(unsigned short v)
{ // enter with 16-bit integer v
  // fill global array d[ ]
  short i;
  for (i = 0; i < 4; i++)
  {
     d[i] = v % 16;
     v = v/16;
  }
}

void display_BCD(unsigned short v)
{// enter with 16-bit integer v
 // fill global array d[ ]
  short i;
  for (i = 0; i < 5; i++)
  {
     d[i] = v % 10;
     v = v/10;
  }
}

#pragma vector = TIMER0_A0_VECTOR
__interrupt void myTimerISR(void)
{
  digit = ++digit % NUMBER_OF_DIGITS;   //use MOD operator
  P1OUT = ~seg[d[digit]];
  P2OUT = 1 << digit;
}

void init(void)
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
  
  // initialize Timer0_A
  TA0CCR0 = TIMER_DELAY;                  // set up terminal count
  TA0CTL = TASSEL_2 + ID_3 + MC_1;  // configure and start timer

  // enable interrupts
  TA0CCTL0_bit.CCIE = 1;   // enable timer interrupts
  __enable_interrupt();    // set GIE in SR
  
  P1DIR  = 0xFF;       // enable segment outputs
  P2DIR  = 0x0F;   // enable digit select
  
  // create 7-segment table
  seg[0]  = 0x3F;
  seg[1]  = 0x06;
  seg[2]  = 0x5B;
  seg[3]  = 0x4F;
  seg[4]  = 0x66;
  seg[5]  = 0x6D;
  seg[6]  = 0x7D;
  seg[7]  = 0x07;
  seg[8]  = 0x7F;
  seg[9]  = 0x67;
  seg[10] = 0x77;
  seg[11] = 0x7C;
  seg[12] = 0x39;
  seg[13] = 0x5E;
  seg[14] = 0x79;
  seg[15] = 0x71;
  
  digit = 0;
}

void initADC(void)
{
  // initialize 10-bit ADC
  ADC10CTL1 = INCH_7 + CONSEQ_2; // use P1.7 (channel 7)
  ADC10CTL0 |= ADC10SHT_3 + ADC10ON + MSC;
  ADC10AE0 |= BIT7; // enable analog input on channel 7
  ADC10CTL0 |= ADC10SC + ENC; // start conversions
}

void main( void )
{
 init();
 initADC();

 while (1)
 {
   v = ADC10MEM;
   display_BCD(v);
   delay(DELAY);
 }
 
}
Note:

1) I have used the program from the previous post as a template. Additions/changes are initADC( ), short v and DELAY, with appropriate changes in main( ).

I am not going to explain every line in the initADC( ) function. You can read about this in the MSP430G2553 User's Manual. If you have any question don't be afraid to ask.

2) The ADC is configured to cycle continuously on a single channel. I have added a global variable v. The 10-bit result is read from ADC10MEM and stored in v which is then displayed on the 3-digit LED display.

3) This is a 10-bit ADC. Hence the output range is 0 to 1023. With Vcc =3.6V, you should expect a reading of about 512 when the pot is set to about mid-point and the voltage at the pot center wiper is 1.8V. Since the display only shows three digits, the reading will wrap around when you exceed 999.

Vcc is likely to be somewhere between 3.4 to 3.6V.

4) Your readings should be stable, ± 1 count. If your readings are not stable, make sure you have 0.1μF and 1 to 10μF decoupling capacitors across your power rail, Vcc to GND.

Blog entry information

Author
MrChips
Views
5,049
Comments
2
Last update

More entries in General

More entries from MrChips

Share this entry

Top