Temperature LED demo version 2
This is my second Temperature demo using LED's, this time driven by the 74hc595 8-bit shift register.
Examples in this demo:
1. Using the 74hc595 to drive a LED.
2. LED truth table for selecting digits.
3. Multiplexing digits
4. Binary to decimal conversion.
Code:
// MSP430G2231 internal temp senser read
// and display on 7 segment display via two 74hc595 shift registers
#include <msp430x20x2.h>
#include <io.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
int ledtable[10] = { 0x7e, 0x30, 0x6d, 0x79, 0x33, 0x5b, 0x5f, 0x70, 0x7f, 0x7b };
void Initializeports(void);
void ConfigureAdcTempSensor(void);
static void __inline__delay(register unsigned int n);
int display_led(int t, int display);
long tempMeasured[8];
unsigned char tempMeasuredPosition=0;
long tempAverage,tempAverage2;
long tempCalibrated, tempDifference;
void main(void)
{
unsigned char i;
int tc = 0, msd, lsd, r1, r2, r3, r4, t, alt_digit = 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)
{
t = ((tempAverage - 630) * 761) / 1024 ;
tc = 0;
}
r2 = t / 10; //Binary to Decimal conversion for two digits.
r1 = t - r2 * 10;
msd = r2;
lsd = r1;
if (alt_digit == 0 )
{
display_led( msd, 0 );
alt_digit = 1;
}else{
display_led( lsd, 1 );
alt_digit = 0;
}
}
}
int display_led(int t, int display)
{
int j, i;
if (display == 0 )
{
j = (ledtable[t]<<1) | 0x0200;
}
if (display == 1 )
{
j = (ledtable[t]<<1) | 0x0100;
}
P1OUT &= ~BIT2;
for(i=0; i < 10; i++)
{
P1OUT &= ~BIT1;
if (j & 0x200)
{
P1OUT |= BIT0;
}else{
P1OUT &= ~BIT0;
}
P1OUT |= BIT1;
j = j<<1;
}
P1OUT |= BIT2;
}
void Initializeports(void)
{
P1DIR |= 0x07;
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
}