This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/MSP430FR2433: Having difficulty reading temp sensor using ADC as part of larger program

Part Number: MSP430FR2433

Tool/software: Code Composer Studio

I have successfully run the C example "msp430fr243x_adc10_16.c." When trying to incorporate into my larger code however, I cannot read from the temp sensor. I can get values, but they are incorrect. I have checked all the relevant PMM and ADC registers for both programs and the registers are identical during the crucial part of reading from the ADC. There must be somewhere where the ADC falls out of its normal operation. I have attempted to put some pieces of code into the example that functions to try to see what would break it and have been unsuccessful in finding what would break the ADC. Most of my code uses registers, but I'm not opposed to using driverlib if someone has a good solution using it. Is there a good way to reset the crucial parts in order to use the ADC for temperature reading? Are there any common ways to cause the ADC to become unusable for temperature reading?

Thanks,

Don

  • Which parts did you adopt?

    adc10_16 does the ADCSC in a timer; how are you starting it now?

    I suppose you got rid of the "LPM forever" statement; what did you replace it with?

    Are you still starting up the Reference Generator (including TSENSOREN)?
  • All parts were adopted for my code with exception to the timer. The enable and start conversion bits are set immediately following the reference settling. That should answer the second question as well. LPM forever is simply non-existent. I want to collect the temperature value and then move on with the program. Reference generator is being started including TSENSOREN.

    The overall structure of the code is to run initializers on startup (including ADC initialization), go into LPM3 mode waiting for an interrupt over P2.4. Once an interrupt is received, the MSP430 waits for SPI commands to tell it what to do next. Reading temperature is one of these commands. Below is the initialization code, the read temperature code, and the ADC interrupt.

    void InitializeADC(void){
        // Configure ADC10
        ADCCTL0 |= ADCSHT_2 | ADCON;                             // ADCON, S&H=16 ADC clks
        ADCCTL1 |= ADCSHP;                                       // ADCCLK = MODOSC; sampling timer
        ADCCTL2 |= ADCRES;                                       // 10-bit conversion results
    }

    int Temperature(void)
    {
        ADCCTL0 &= ~(ADCSHT_2|ADCON); //initial setting off
    
        ADCCTL0 |= ADCSHT_8 | ADCON;                                    //  ADC ON, 64 ADCCLK cycles per sample
        ADCCTL1 |= ADCSHP;                                              //  sampling timer (already set)
        ADCCTL2 |= ADCRES;                                              //  10-bit conversion results (already set)
        ADCMCTL0 |= ADCSREF_1 | ADCINCH_12;                             //  A12 --> Temperature Sensor
        ADCIE |=ADCIE0;                                                 //  Enable the Interrupt
    
        // Configure reference and temp sensor
        PMMCTL0_H = PMMPW_H;                                            //  Unlock the PMM registers
    
        PMMCTL2 |= TSENSOREN;
        if (referenceV==1){
            PMMCTL2 |= INTREFEN;                                        //  Enable reference and temperature sensor
            __delay_cycles(400);                                        //  Delay for reference settling
        }
    
        ADCCTL0 |= ADCENC | ADCSC;                                      //  Sampling and ADC conversion begin
        __bis_SR_register(LPM0_bits | GIE);                             //  LPM0 with interrupts enabled (uses interrupt defined in ADC section)
    
        ADCCTL0 &= ~(ADCENC | ADCSC);                                    //  returned from interrupt,turn off ADC
        ADCIE &= ~ADCIE0;                                               //  disable ADC interrupt
        ADCMCTL0 &= ~ADCINCH_12;                                        //  A122 ADC input unselected
    
        //reseting initial settings
        ADCCTL0 &= ~ADCSHT_8;
        ADCCTL0 |= ADCSHT_2;
        ADCMCTL0 &= ~ADCSREF_1; //reference voltage
    
        //turn off reference
        PMMCTL2 &= ~(TSENSOREN);
        if (referenceV==1){
            PMMCTL2 &= ~(INTREFEN);                                //  disable reference and temperature sensor
            __delay_cycles(400);                                               //  Delay for reference settling
        }
        PMMCTL0_H &= ~PMMPW_H;                                             //  Lock the PMM registers
    
        int Cal30C = CALADC_15V_30C;
        int Cal85C = CALADC_15V_30C;
        //int value = (ADC_Result-CALADC_15V_30C)*(85-30)/(CALADC_15V_85C-CALADC_15V_30C)+30;
        int value = (ADC_Result-Cal30C)*(85-30)/(Cal85C-Cal30C)+30;
        return value;
    }
    // ADC interrupt service routine
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=ADC_VECTOR
    __interrupt void ADC_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
            switch(__even_in_range(ADCIV,ADCIV_ADCIFG))
                {
                    case ADCIV_NONE:
                        break;
                    case ADCIV_ADCOVIFG:
                        break;
                    case ADCIV_ADCTOVIFG:
                        break;
                    case ADCIV_ADCHIIFG:
                        break;
                    case ADCIV_ADCLOIFG:
                        break;
                    case ADCIV_ADCINIFG:
                        break;
                    case ADCIV_ADCIFG:                                         //   Our Case
                        ADC_Result = ADCMEM0;
                        __bic_SR_register_on_exit(LPM0_bits);            //   Clear CPUOFF bit from LPM0
                        break;
                    default:
                        break;
        }
    }

     

  • Typo alert:
    > int Cal85C = CALADC_15V_30C;
    This sets up a divide-by-0. Try:
    > int Cal85C = CALADC_15V_85C;
  • Hey Donald,

    Are you still having issues?

    Thanks,

    Mitch
  • Hi Mitch,

    No issues. I somehow missed Bruce's answer above. I discovered the same typo he found and it has been performing fine since. I've marked his answer above as resolving the issue.

    Donald
  • Hi Bruce,

    I missed your answer somehow when you posted it. I found the same typo a while back and it's been working fine since. Thanks for your help!

    Donald

**Attention** This is a public forum