temperature demo led display
Here a demo of displaying the Temperature on two digit seven segment LED display, using the CD4511 seven segment display/decoder/driver/latch. I used 6 pins of the MSP430, 4 data bits, two bits for digit select/latch. Have not created a schematic but you can look at a data sheet for the CD4511, I connect the BCD pins in parallel from both CD4511's to the MSP430, Latch pin acts as digit select for writing data.
I used the code from the temperature demo that came with the launchpad, modified it to output to a display.
* Code *
// MSP430G2231 internal temp senser read
// and display on 7 segment display via 4511 decoder/driver
#include <msp430x20x2.h>
#include <io.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
void Initializeports(void);
void ConfigureAdcTempSensor(void);
static void __inline__delay(register unsigned int n);
int display_led(int t);
long tempMeasured[8];
unsigned char tempMeasuredPosition=0;
long tempAverage,tempAverage2;
long tempCalibrated, tempDifference;
void main(void)
{
unsigned char i;
int tc = 0;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
Initializeports();
ConfigureAdcTempSensor();
__enable_interrupt(); // Enable interrupts.
/* Main Application Loop */
while(1)
{
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
/* Moving average filter out of 8 values to somewhat stabilize sampled ADC */
tempMeasured[tempMeasuredPosition++] = ADC10MEM;
if (tempMeasuredPosition == 8)
tempMeasuredPosition = 0;
tempAverage2 = 0;
for (i = 0; i < 8; i++)
tempAverage2 += tempMeasured[i];
tempAverage2 >>= 3; // Divide by 8 to get average
tempAverage=tempAverage2; //use temporary avarage to prevent ISRs from using intermediate values
tc++;
if (tc > 2000)
{
display_led( ((tempAverage - 630) * 761) / 1024 );
tc = 0;
}
}
}
int display_led(int t)
{
int msd, lsd, r1, r2, r3, r4;
// my binary to BCD conversion code, note code expects temp rang not to pass 99 degrees.
// this code can be expanded to do full 16 bit conversion
r2 = t / 10;
r1 = t - r2 * 10;
msd = r2;
lsd = r1;
P1OUT &= ~BIT4; // Select First digit
P1OUT = (BIT0 & msd) | (BIT1 & msd) | (BIT2 & msd) | (BIT3 & msd) | BIT5; // Output 4 bit BCD code
__inline__delay( 0xff );
P1OUT |= BIT4; // Latch data on first display
P1OUT &= ~BIT5; // Select Second digit
P1OUT = (BIT0 & lsd) | (BIT1 & lsd) | (BIT2 & lsd) | (BIT3 & lsd) | BIT4; // Output 4 bit BCD code
P1OUT |= BIT5; // Latch data
}
void Initializeports(void)
{
P1DIR |= 0x3f;
P1SEL = 0x00;
}
void ConfigureAdcTempSensor(void)
{
unsigned int i;
/* Configure ADC Temp Sensor Channel */
ADC10CTL1 = INCH_10 + ADC10DIV_3; // Temp Sensor ADC10CLK/4
ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE;
__inline__delay(0x1000); // Wait for ADC Ref to settle
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
tempCalibrated = ADC10MEM;
for (i=0; i < 8; i++)
tempMeasured[i] = tempCalibrated;
tempAverage = tempCalibrated;
}
// Delay Routine from mspgcc help file
static void __inline__delay(register unsigned int n)
{
__asm__ __volatile__ (
"1: \n"
" dec %[n] \n"
" jne 1b \n"
: [n] "+r"(n));
}
// ADC10 interrupt service routine
interrupt(ADC10_VECTOR) ADC10_ISR (void)
{
__bic_SR_register_on_exit(CPUOFF); // Return to active mode
}