关于MSP430FR5949内部温度采样的问题,望解答

关于MSP430FR5949内部温度采样的问题,望解答

此问题已被解答
All Replies
  • 秀才71分

    我用官方给的例子,测得的温度比较准确,官方AD基准选的1.2V,采样保持时间ADC12SHT0_8程序如下:

    /* --COPYRIGHT--,BSD_EX
    * Copyright (c) 2012, Texas Instruments Incorporated
    * All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions
    * are met:
    *
    * * Redistributions of source code must retain the above copyright
    * notice, this list of conditions and the following disclaimer.
    *
    * * Redistributions in binary form must reproduce the above copyright
    * notice, this list of conditions and the following disclaimer in the
    * documentation and/or other materials provided with the distribution.
    *
    * * Neither the name of Texas Instruments Incorporated nor the names of
    * its contributors may be used to endorse or promote products derived
    * from this software without specific prior written permission.
    *
    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
    * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
    * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
    * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    *
    *******************************************************************************
    *
    * MSP430 CODE EXAMPLE DISCLAIMER
    *
    * MSP430 code examples are self-contained low-level programs that typically
    * demonstrate a single peripheral function or device feature in a highly
    * concise manner. For this the code may rely on the device's power-on default
    * register values and settings such as the clock configuration and care must
    * be taken when combining code from several examples to avoid potential side
    * effects. Also see www.ti.com/grace for a GUI- and www.ti.com/msp430ware
    * for an API functional library-approach to peripheral configuration.
    *
    * --/COPYRIGHT--*/
    //******************************************************************************
    // MSP430FR59xx Demo - ADC12_B, Sample A10 Temp and Convert to oC and oF
    //
    // Description: A single sample is made on A10 with internal reference voltage
    // 1.2V. Software manually sets ADC12SC to start sample and conversion and
    // automatically cleared at EOC. It uses ADC12OSC to convert the sameple.
    // The Mainloop sleeps the MSP430 in LPM4 to save power until ADC conversion
    // is completed. ADC12_ISR forces exit from LPMx in on exit from interrupt
    // handler so that the mainloop can execute and calculate oC and oF.
    // ACLK = n/a, MCLK = SMCLK = default DCO ~ 1.045MHz, ADC12CLK = ADC12OSC
    //
    // Un-calibrated temperature measured from device to device will vary due to
    // slope and offset variance from device to device - please see datasheet.
    // Note: This example uses the TLV calibrated temperature to calculate
    // the temperature
    // (the TLV CALIBRATED DATA IS STORED IN THE INFORMATION SEGMENT, SEE DEVICE DATASHEET)
    //
    // MSP430FR5969
    // -----------------
    // /|\| XIN|-
    // | | |
    // --|RST XOUT|-
    // | |
    // |A10 |
    //
    // William Goh
    // Texas Instruments Inc.
    // February 2014
    // Built with IAR Embedded Workbench Version: 5.60 & Code Composer Studio V5.5
    //******************************************************************************
    #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

    unsigned int temp;
    volatile float temperatureDegC;
    volatile float temperatureDegF;

    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_8 + 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

    while(!(REFCTL0 & REFGENRDY)); // Wait for reference generator
    // to settle
    ADC12CTL0 |= ADC12ENC;

    while(1)
    {
    ADC12CTL0 |= ADC12SC; // 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;

    __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
    {
    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;
    }
    }

    我自己用的2.5V的基准,程序如下,不同的板子采样出来的温度值差别很大,有的为负值,这是怎么回事,程序如下:

    STATIC VOID Bsp_InitAD(VOID)
    {
    /* 初始化AD引脚 *///P1.0,P1.1
    P1SEL0 |= P1_ADI|P1_AC2;
    P1SEL1 |= P1_ADI|P1_AC2;
    P3SEL0 |= P3_AC1|P3_BIT1|P3_BIT2;
    P3SEL1 |= P3_AC1|P3_BIT1|P3_BIT2;
    //
    while(REFCTL0 & REFGENBUSY); // If ref generator busy, WAIT
    REFCTL0 |= REFVSEL_3; //调高后影响采样精度
    REFCTL0 |= REFON;
    //REFCTL0 |= REFON;//10.30
    ADC12CTL0 &=~ADC12ENC;

    ADC12CTL1 = ADC12SHP\
    |ADC12CONSEQ_1 \
    |ADC12SHS_0\
    |ADC12SSEL_0;

    ADC12CTL2 = ADC12RES_2;

    ADC12CTL3 = ADC12CSTARTADD_0|ADC12TCMAP;
    //电流 A0
    ADC12MCTL0 = ADC12VRSEL_1\
    |ADC12INCH_0;
    //电压AC2 A1
    ADC12MCTL1 = ADC12VRSEL_1\
    |ADC12INCH_1;
    //电压AC1 A12
    ADC12MCTL2 = ADC12VRSEL_1\
    |ADC12INCH_12;
    //基准1.25 A13
    ADC12MCTL3 = ADC12VRSEL_1\
    |ADC12INCH_13;
    //电池 A14
    ADC12MCTL4 = ADC12VRSEL_1\
    |ADC12INCH_14;
    //温度
    ADC12MCTL5 = ADC12VRSEL_1\
    |ADC12INCH_30\
    |ADC12EOS;


    ADC12CTL0 = ADC12ON\
    |ADC12MSC\
    |ADC12ENC\
    |ADC12SHT0_3

    }

    #pragma vector = TIMER2_A1_VECTOR //2500US采样单周期采样8个点
    __interrupt void Timer2_A1_ISR (void)
    {
    switch(__even_in_range(TA2IV, TA2IV_TAIFG))
    {
    case TA2IV_TAIFG:

    ST_UINT16 Wp = g_Sys.AD.AdNum;

    Wp = (Wp+10) & SYS_AD_DATA_SIZE;
    ADC12CTL0 |=ADC12SC;
    g_Sys.AD.CData[Wp] = ADC12MEM0;//电流
    g_Sys.AD.DData[Wp] = ADC12MEM1;//电场
    g_Sys.AD.TempPow = ADC12MEM4;//wendu
    g_Sys.AD.TempT = ADC12MEM5;//wendu

    g_Sys.AD.AdNum = Wp;
    break;
    }
    }

    温度计算程序:

    temperatureDegC = (float)(((long)g_Sys.AD.TempT*2 - CALADC12_12V_30C) * (85 - 30)) /
    (CALADC12_12V_85C - CALADC12_12V_30C) + 30.0f;

  • 状元43130分

    你的计算公式是有问题的。例程中基准电压1.2v,公式为:

    temperatureDegC = (float)(((long)temp - CALADC12_12V_30C) * (85 - 30)) /
    (CALADC12_12V_85C - CALADC12_12V_30C) + 30.0f;

    昵称:灰小子

    qq:1358611172

  • 秀才71分

    我选的基准为2.5V,所以我乘了2,实验发现AD的保持周期影响温度的AD值,基准调高后出来转换的电压确实不准确,如何解决,有2.5v基准的历程吗?

  • 秀才71分

    我选的基准为2.5V,所以我乘了2,实验发现AD的保持周期影响温度的AD值,基准调高后出来转换的电压确实不准确,如何解决,有2.5v基准的历程吗?

  • 秀才71分

    不那么费劲了,我把温度改为可以校准的了

  • 榜眼20702分

    不用乘以2啊,不同参考和温度的校准值放在芯片的不同位置。你要调用2.5V 30度的值,和1.2V 30度的类似。

    不过片内ADC的准确度有限,要比较准确的,要外接NTC电阻或者温度传感器芯片才好

    Regards,

    Holly

  • 秀才71分

    大神果然是大神,问题解决,不过AD采样的保持时间要设置为sh_8,这样采样出来的才准确。

  • 秀才71分

    Thankyou very much