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.

[参考译文] MSP430FR5994:内部温度传感器未给出正确的值。

Guru**** 2391415 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/986413/msp430fr5994-internal-temperature-sensor-not-giving-correct-values

器件型号:MSP430FR5994

您好!

我们通过查看示例启用了内部温度、但我们没有获得预期的读数。

为了启用此 TS、我们使用了2.5V 基准的 TLV 校准点 ADC 初始部分附后供参考。

void AdcInit(void){

    ADC12_B_initParam FsiAdc;
    ADC12_B_configureMemoryParam CMOLG;
    ADC12_B_configureMemoryParam VDO;
    ADC12_B_configureMemoryParam TempSensor;
    DMA_initParam AdcDMA;

    FsiAdc.clockSourceDivider           = ADC12_B_CLOCKDIVIDER_1;
    FsiAdc.clockSourcePredivider        = ADC12_B_CLOCKPREDIVIDER__1;
    FsiAdc.clockSourceSelect            = ADC12_B_CLOCKSOURCE_ADC12OSC;
    FsiAdc.internalChannelMap           = ADC12_B_TEMPSENSEMAP;//ADC12_B_NOINTCH;
    FsiAdc.sampleHoldSignalSourceSelect = ADC12_B_SAMPLEHOLDSOURCE_SC;

    ADC12_B_init(ADC12_B_BASE,&FsiAdc);

    ADC12_B_enable(ADC12_B_BASE);

    ADC12_B_setupSamplingTimer(ADC12_B_BASE,
                               ADC12_B_CYCLEHOLD_64_CYCLES,
                               ADC12_B_CYCLEHOLD_4_CYCLES,
                               ADC12_B_MULTIPLESAMPLESENABLE);

    ADC12_B_setResolution(ADC12_B_BASE,
                          ADC12_B_RESOLUTION_12BIT);

    CMOLG.differentialModeSelect        = ADC12_B_DIFFERENTIAL_MODE_DISABLE;
    CMOLG.endOfSequence                 = ADC12_B_NOTENDOFSEQUENCE;
    CMOLG.inputSourceSelect             = ADC12_B_INPUT_A13;
    CMOLG.memoryBufferControlIndex      = ADC12_B_MEMORY_0;
    CMOLG.refVoltageSourceSelect        = ADC12_B_VREFPOS_EXTPOS_VREFNEG_EXTNEG;
    CMOLG.windowComparatorSelect        = ADC12_B_WINDOW_COMPARATOR_DISABLE;

    ADC12_B_configureMemory(ADC12_B_BASE,
                            &CMOLG);

    VDO.differentialModeSelect      = ADC12_B_DIFFERENTIAL_MODE_DISABLE;
    VDO.endOfSequence               = ADC12_B_NOTENDOFSEQUENCE;//ADC12_B_ENDOFSEQUENCE;
    VDO.inputSourceSelect           = ADC12_B_INPUT_A14;
    VDO.memoryBufferControlIndex    = ADC12_B_MEMORY_1;
    VDO.refVoltageSourceSelect      = ADC12_B_VREFPOS_EXTPOS_VREFNEG_EXTNEG;
    VDO.windowComparatorSelect      = ADC12_B_WINDOW_COMPARATOR_DISABLE;

    ADC12_B_configureMemory(ADC12_B_BASE,
                            &VDO);


    TempSensor.differentialModeSelect      = ADC12_B_DIFFERENTIAL_MODE_DISABLE;
    TempSensor.endOfSequence               = ADC12_B_ENDOFSEQUENCE;
    TempSensor.inputSourceSelect           = ADC12_B_INPUT_TCMAP;
    TempSensor.memoryBufferControlIndex    = ADC12_B_MEMORY_2;
    TempSensor.refVoltageSourceSelect      = ADC12_B_VREFPOS_EXTPOS_VREFNEG_EXTNEG;
    TempSensor.windowComparatorSelect      = ADC12_B_WINDOW_COMPARATOR_DISABLE;

    ADC12_B_configureMemory(ADC12_B_BASE,
                            &TempSensor);

 //   while(REFCTL0 & REFGENBUSY);            // If ref generator busy, WAIT
 //   REFCTL0 |= REFVSEL_2 + REFON;           // Enable i nternal 1.2V reference
 //   while(!(REFCTL0 & REFGENRDY));
   // while(Ref_A_isRefGenBusy (REF_A_BASE));
    Ref_A_enableReferenceVoltage (REF_A_BASE);
 //   Ref_A_setReferenceVoltage (REF_A_BASE,REFVSEL_2);
    Ref_A_enableTempSensor(REF_A_BASE);
//    Ref_A_disableTempSensor(REF_A_BASE);
  //  Ref_A_disableReferenceVoltage(REF_A_BASE);

    AdcDMA.channelSelect        = DMA_CHANNEL_2;
    AdcDMA.transferModeSelect   = DMA_TRANSFER_REPEATED_BLOCK;
    AdcDMA.transferSize         = 3;
    AdcDMA.transferUnitSelect   = DMA_SIZE_SRCWORD_DSTWORD;
    AdcDMA.triggerSourceSelect  = DMA_TRIGGERSOURCE_26;
    AdcDMA.triggerTypeSelect    = DMA_TRIGGER_RISINGEDGE;

    DMA_init(&AdcDMA);

    DMA_setSrcAddress(DMA_CHANNEL_2,
                      (uint32_t) &ADC12MEM0,
                      DMA_DIRECTION_INCREMENT);

    DMA_setDstAddress(DMA_CHANNEL_2,
                      (uint32_t) AdcRawCounts,
                      DMA_DIRECTION_INCREMENT);

    DMA_disableTransferDuringReadModifyWrite();
    DMA_enableRoundRobinPriority();
    DMA_enableInterrupt(DMA_CHANNEL_2);
    DMA_enableTransfers(DMA_CHANNEL_2);
    DMA_startTransfer(DMA_CHANNEL_2);

}
我们的目标是在-10至-40°C 的温度范围内获得正确的读数  

在5个器件上的室中读取的读数。

温度 设备1 设备2 设备3 设备4 设备5
-10 0.95 -4.1. -3.97 -2.36. -3.
-20 -9.53 -15.3 15.37 -13.06 -13.
-25. -14.29 -20.28 -20.7 -18.04 -18.
-30 -18.58. -25. -25. -22.52 -23.
-35. -22.62 -29.24 -29.82 -26.75 -27.
-40 -26.2 33.47. 33.88 -30.98 -31.
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    >  TempSensor.refVoltageSourceSelect   = ADC12_B_VREFPS_EXTPOS_VREFNEG_EXTNEG;

    我希望您需要使用温度传感器的内部基准(以匹配校准常数)、如下所示:

    >TempSensor.refVoltageSourceSelect     = ADC12_B_VREFPOS_INTBUF_VREFNEG_VSS;// VRSEL=1

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    e2e.ti.com/.../MSP430-Internal-Temperature-sensor-test-results.xlsx

    您好!

    正如建议的那样、我们通过启用2.5V 内部基准来获得结果。 结果已附加。

    此致、

    Pradeep Lokhande

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Pradeep、

    您是否对温度传感器偏移执行了建议的单点校准? 根据数据表、温度传感器的失调电压最高可达±30°C 如果没有校准步骤、您的温度读数看起来非常好。

    查看  MSP430FR599x、MSP430FR596x 混合信号微控制器数据表(修订版 D)、第60页。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    此外、您能否发布用于进行算术运算的代码? 我记得用整数进行公式、并注意到必须按正确的顺序执行运算("常用算术转换")。 我建议您从 这里的示例 msp430fr599x_ADC12_10.c 中的算术开始:

    https://dev.ti.com/tirex/explore/node?node=ABD7vflrIvcltwOC16GGBw__IOGqZri__LATEST

    该示例以浮点方式执行它、但这将帮助您区分(a) ADC 中的某个项和(b)算术中的某个项。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    我们尚未执行单点校准、因为它会增加制造的额外阶段。 为了克服这一问题、我们使用了 TLV 结构中提供的校准。 如果我们进行单点校准、我们需要为 MF 进行新设置。 我们的温度范围为-20C 至-40C、因此我们需要环境室对其进行校准。

    我们的假设是、所有器件的失调电压都将保持不变、并且不会有器件间的差异或会有轻微的变化。 因此、我们将为每个单元使用公共偏移。

    现在、对于算术点、我们使用了示例中给出的相同计算。 随附源代码供您参考。

    此致、

    Pradeep Lokhande

    #define FSI_MODE_NORMAL             ( 0U )  /* Normal Mode */
    #define FSI_MODE_LOW_TEMP           ( 1U )  /* Low Temperature Mode */
    
    #define TEMPERATURE_CUTOFF          ( -35 ) /* Shutdown/Cutoff tempearture */
    #define TEMPERATURE_HYSTERESIS      ( 5 )   /* Temperature Hysteresis */
    
    #define TEMPERATURE_OFFSET          ( 60 ) /* Offset to shift temperature at positive side */
    #define TEMPERATURE_THRESHOLD_LOW   ( TEMPERATURE_OFFSET + TEMPERATURE_CUTOFF ) /* Lower cutoff threshold */
    #define TEMPERATURE_THRESHOLD_HIGH  ( TEMPERATURE_THRESHOLD_LOW + TEMPERATURE_HYSTERESIS ) /* Upper threshold */
    
    #define TLV_CALADC12_12V_30C  *((unsigned int *)0x1A22)   /* Temperature Sensor Calibration-30 C */
    #define TLV_CALADC12_12V_85C  *((unsigned int *)0x1A24)   /* Temperature Sensor Calibration-85 C */
    
    extern uint16_t AmbTemp;
    static uint8_t FSI_Mode = FSI_MODE_NORMAL;
    /*---------------------------------------------------------------------------*/
    static uint16_t GetTemperatureValue( const uint16_t ADC_Value_p )
    {
        float TempInDegC;
    
        /* Covert ADC value in temperature in Centigrade */
        TempInDegC = (float)(((float)ADC_Value_p - TLV_CALADC12_12V_30C) * (85 - 30)) /
                (TLV_CALADC12_12V_85C - TLV_CALADC12_12V_30C) + 30.0f;
        /* Add temperature offset */
        TempInDegC += TEMPERATURE_OFFSET;
    
        return (uint16_t)TempInDegC;
    }
    /*---------------------------------------------------------------------------*/
    void MeasureTemperature( void )
    {
        uint16_t TempInDegC;
        /* Get current temperature value */
        TempInDegC = GetTemperatureValue( AmbTemp );
        /* Is FSI in Low temperature mode? */
        if( FSI_Mode == FSI_MODE_LOW_TEMP )
        {   /* Is temperature reached to upper threshold limit? */
            if( TempInDegC >= (uint16_t)TEMPERATURE_THRESHOLD_HIGH )
            {   /* Switch to Normal mode */
                FSI_Mode = FSI_MODE_NORMAL;
            }
        }
        else
        {   /* Is temperature reached below cutoff value? */
            if( TempInDegC < (uint16_t)TEMPERATURE_THRESHOLD_LOW )
            {   /* Switch to Low temperature mode */
                FSI_Mode = FSI_MODE_LOW_TEMP;
            }
        }
    }
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Pradeep、您好!

    此器件系列 ADC67上还有一个勘误表、该勘误表使批次追踪代码<= 87xxxxx 的任何器件上的温度 TLV 数据无效。  勘误文档的第3页显示了如何从封装标记中读取批次追踪代码。   

    您能检查一下吗?  

    谢谢、

    JD

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    在此测试中、我们使用了器件771xxxx、841xxxxx 和991xxxx。 我们已在其上执行测试的所有器件都附有图像。 图像中还标记了器件编号、其结果已提前与您共享。

    此致、

    Pradeep Lokhande

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    您能否确认一下、如果我们使用相同的991个 MCU、我们是否可以在所有器件之间使用恒定偏移。

    所有结果已与您共享。

    此致、

    Pradeep Lokhande

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Pradeep、您好!

    我在您的最新帖子中看不到任何照片、但如前所述、77xxx 和84xxx 器件需要外部校准。

    对于991xxx 批次、您只需使用校准值即可。   

    这意味着恒定偏移是什么?  按失调电压、您是指来自校准值的电压还是 ADC 计数?  温度传感器的线性度相当好、因此我应该看到校准数据的近似增量。  这实际上取决于您尝试的准确性。  

    最准确的方法是使用这两个数据点来找到温度传感器电压的"斜率"、并使用它、但我知道这种方法的数学密集度更高。   

    谢谢、

    JD

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    JD、您好!

    在这里、我的平均值是以度为单位的增量。 就像在-40*C 时一样,MCU 的读数为32*C,因此我们在这里得到8*C 的增量。 如果您的991个批次、我们是否会在所有器件中获得相同的差值? 如果是、我们可以将其用作度数的常数。

    对于87xxx 以下的其他器件、您能建议使用任何可靠的温度传感器器件进行单点校准。  

    此致、

    Pradeep Lokhande

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    请在我之前的邮件中提供您的输入。

    此外、让我们知道如何解读 TLV 结构中可用的批次跟踪代码。 我们希望在此批次追踪代码上输入 mf。

    此致、

    Pradeep Lokhande