Hi
I am using Msp430 FR6989. I have a simple code which is supposed to read the internal temperature sensor and display the results on the LCD. LCD is updated on timer overflow interrupts. it works fine for a few cycles bu then apparently the program counter is being kicked out of the main routine and ADC does not work anymore. however, timer interrupt keeps running.
I am very new in using the system so I was wondering if anybody has an idea why is this the case. Please find the code below.
thanks a lot in advance
Afshin
#include <msp430.h>
#define CALADC12_12V_30C *((unsigned int *)0x1A1A) // Temperature Sensor Calibration-30 C
//See device datasheet for TLV table memory mapping
#define CALADC12_12V_85C *((unsigned int *)0x1A1C) // Temperature Sensor Calibration-85 C
#define CielCounter 10000
const unsigned char lcd_num[10] = {
0xFC, // 0
0x60, // 1
0xDB, // 2
0xF3, // 3
0x67, // 4
0xB7, // 5
0xBF, // 6
0xE4, // 7
0xFF, // 8
0xF7, // 9
};
unsigned int temp;
volatile float temperatureDegC;
volatile float temperatureDegF;
// Timer A interrupt service routine
#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer_A1_ISR( void )
{
_DINT();
int den1, den2, rem1, quot, dummy;
den1=100;
den2=10;
switch(__even_in_range(TA0IV, TA0IV_TAIFG))
{
case TA0IV_NONE: break; // No interrupt
case TA0IV_TACCR1: break; // CCR1 not used
case TA0IV_TACCR2: break; // CCR2 not used
case TA0IV_3: break; // reserved
case TA0IV_4: break; // reserved
case TA0IV_5: break; // reserved
case TA0IV_6: break; // reserved
case TA0IV_TAIFG: // overflow
dummy= (int) (temperatureDegC*10);
quot=dummy/den1; /* Computes quotient */
rem1=dummy%den1;
// Display quot on Segment 36,37
LCDM19 = lcd_num[quot];
quot=rem1/den2;
rem1=rem1%den2;
// Display quot on " on Segment 28,29
LCDM15 = lcd_num[quot];
LCDM16=0x01; // decimal point
// Display rem1 on " on Segment 14,15
LCDM8 = lcd_num[rem1];
P1OUT ^=BIT0;
break;
default: break;
}
TA0CCR0=CielCounter;
_EINT();
}
void Init( void )
{
// init timer A
TA0CCR0=CielCounter;
//TA0CTL = TASSEL__ACLK | MC__CONTINUOUS | ID_1| TACLR | TAIE; // ACLK, contmode, clear TAR
TA0CTL = TASSEL__SMCLK | MC__CONTINUOUS| ID_3 | TACLR | TAIE; // SMCLK, continuous mode
P1DIR |= BIT0;
P1OUT |= BIT0;
// Enable interrupts
//_EINT();
}
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
// Initialize the shared reference module
// By default, REFMSTR=1 => REFCTL is used to configure the internal reference
while(REFCTL0 & REFGENBUSY); // If ref generator busy, WAIT
REFCTL0 |= REFVSEL_0 + REFON; // Enable internal 1.2V reference
/* Initialize ADC12_A */
ADC12CTL0 &= ~ADC12ENC; // Disable ADC12
ADC12CTL0 = ADC12SHT0_10 + ADC12ON; // Set sample time
ADC12CTL1 = ADC12SHP; // Enable sample timer
ADC12CTL3 = ADC12TCMAP; // Enable internal temperature sensor
ADC12MCTL0 = ADC12VRSEL_1 + ADC12INCH_30; // ADC input ch A30 => temp sense
ADC12IER0 = 0x001; // ADC_IFG upon conv result-ADCMEMO
LCDCPCTL0 = LCDS14 | LCDS15; // Initialize LCD segments
LCDCPCTL1 = LCDS28 | LCDS29 | LCDS30;
LCDCPCTL2 = LCDS36 | LCDS37;
// Disable the GPIO power-on default high-impedance mode
// to activate previously configured port settings
PM5CTL0 &= ~LOCKLPM5;
Init(); // initialize timer
// Initialize LCD_C
// ACLK, Divider = 1, Pre-divider = 16; 4-pin MUX
LCDCCTL0 = LCDDIV__1 | LCDPRE__16 | LCD4MUX | LCDLP | LCDSSEL;
// Enable charge pump and select internal reference for it
LCDCVCTL = VLCD_1 | VLCDREF_0 | LCDCPEN;
LCDCCPCTL = LCDCPCLKSYNC; // Clock synchronization enabled
LCDCMEMCTL = LCDCLRM; // Clear LCD memory
//Turn LCD on
LCDCCTL0 |= LCDON;
while(!(REFCTL0 & REFGENRDY)); // Wait for reference generator
// to settle
//ADC12CTL0 |= ADC12ENC;
while(1)
{
ADC12CTL0 |= ADC12ENC| ADC12SC; // enable and Sampling and conversion start
__bis_SR_register(LPM0_bits | GIE); // LPM4 with interrupts enabled
// __no_operation();
// Temperature in Celsius. See the Device Descriptor Table section in the
// System Resets, Interrupts, and Operating Modes, System Control Module
// chapter in the device user's guide for background information on the
// used formula.
temperatureDegC = (float)(((long)temp - CALADC12_12V_30C) * (85 - 30)) /
(CALADC12_12V_85C - CALADC12_12V_30C) + 30.0f;
// Temperature in Fahrenheit Tf = (9/5)*Tc + 32
temperatureDegF = temperatureDegC * 9.0f / 5.0f + 32.0f;
__delay_cycles(2000);
__no_operation(); // SET BREAKPOINT HERE
}
}
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=ADC12_VECTOR
__interrupt void ADC12ISR (void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(ADC12_VECTOR))) ADC12ISR (void)
#else
#error Compiler not supported!
#endif
{
_DINT();
switch(__even_in_range(ADC12IV, ADC12IV_ADC12RDYIFG))
{
case ADC12IV_NONE: break; // Vector 0: No interrupt
case ADC12IV_ADC12OVIFG: break; // Vector 2: ADC12MEMx Overflow
case ADC12IV_ADC12TOVIFG: break; // Vector 4: Conversion time overflow
case ADC12IV_ADC12HIIFG: break; // Vector 6: ADC12BHI
case ADC12IV_ADC12LOIFG: break; // Vector 8: ADC12BLO
case ADC12IV_ADC12INIFG: break; // Vector 10: ADC12BIN
case ADC12IV_ADC12IFG0: // Vector 12: ADC12MEM0 Interrupt
temp = ADC12MEM0; // Move results, IFG is cleared
__bic_SR_register_on_exit(LPM4_bits); // Exit active CPU
break;
case ADC12IV_ADC12IFG1: break; // Vector 14: ADC12MEM1
case ADC12IV_ADC12IFG2: break; // Vector 16: ADC12MEM2
case ADC12IV_ADC12IFG3: break; // Vector 18: ADC12MEM3
case ADC12IV_ADC12IFG4: break; // Vector 20: ADC12MEM4
case ADC12IV_ADC12IFG5: break; // Vector 22: ADC12MEM5
case ADC12IV_ADC12IFG6: break; // Vector 24: ADC12MEM6
case ADC12IV_ADC12IFG7: break; // Vector 26: ADC12MEM7
case ADC12IV_ADC12IFG8: break; // Vector 28: ADC12MEM8
case ADC12IV_ADC12IFG9: break; // Vector 30: ADC12MEM9
case ADC12IV_ADC12IFG10: break; // Vector 32: ADC12MEM10
case ADC12IV_ADC12IFG11: break; // Vector 34: ADC12MEM11
case ADC12IV_ADC12IFG12: break; // Vector 36: ADC12MEM12
case ADC12IV_ADC12IFG13: break; // Vector 38: ADC12MEM13
case ADC12IV_ADC12IFG14: break; // Vector 40: ADC12MEM14
case ADC12IV_ADC12IFG15: break; // Vector 42: ADC12MEM15
case ADC12IV_ADC12IFG16: break; // Vector 44: ADC12MEM16
case ADC12IV_ADC12IFG17: break; // Vector 46: ADC12MEM17
case ADC12IV_ADC12IFG18: break; // Vector 48: ADC12MEM18
case ADC12IV_ADC12IFG19: break; // Vector 50: ADC12MEM19
case ADC12IV_ADC12IFG20: break; // Vector 52: ADC12MEM20
case ADC12IV_ADC12IFG21: break; // Vector 54: ADC12MEM21
case ADC12IV_ADC12IFG22: break; // Vector 56: ADC12MEM22
case ADC12IV_ADC12IFG23: break; // Vector 58: ADC12MEM23
case ADC12IV_ADC12IFG24: break; // Vector 60: ADC12MEM24
case ADC12IV_ADC12IFG25: break; // Vector 62: ADC12MEM25
case ADC12IV_ADC12IFG26: break; // Vector 64: ADC12MEM26
case ADC12IV_ADC12IFG27: break; // Vector 66: ADC12MEM27
case ADC12IV_ADC12IFG28: break; // Vector 68: ADC12MEM28
case ADC12IV_ADC12IFG29: break; // Vector 70: ADC12MEM29
case ADC12IV_ADC12IFG30: break; // Vector 72: ADC12MEM30
case ADC12IV_ADC12IFG31: break; // Vector 74: ADC12MEM31
case ADC12IV_ADC12RDYIFG: break; // Vector 76: ADC12RDY
default: break;
}
_EINT();
}