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 filestatic void __inline__delay(register unsigned int n){ __asm__ __volatile__ ( "1: \n" " dec %[n] \n" " jne 1b \n" : [n] "+r"(n));}// ADC10 interrupt service routineinterrupt(ADC10_VECTOR) ADC10_ISR (void){ __bic_SR_register_on_exit(CPUOFF); // Return to active mode}