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.

[参考译文] MSP430F5418A:如何读取内部温度?

Guru**** 2510095 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/979410/msp430f5418a-how-can-i-read-the-internal-temperature

器件型号:MSP430F5418A

您好!

ADC12通道0-6用于其他 ADC 读数、因此我想在 ADC12MEM7上输出温度。

到目前为止 、已经使用了一个外部温度传感器。 我需要读取 MSP430的内部温度传感器。

在用户指南中:

28.2.8使用集成温度传感器
要使用片上温度传感器、请选择模拟输入通道 INCHx = 1010。 任何其他
配置就像选择了外部通道一样、包括基准选择和
转换存储器选择。

温度传感器是基准的一部分。 因此、对于具有的器件
REF 模块、除了输入通道选择 INCHx = 1010、还配置 ADC12REFON = 1
(对于 REFMSTR = 0)或 REFON = 1 (对于 REFMSTR = 1)需要启用温度传感器。
对于不包含 REF 模块的 MSP430F54xx (非 A)器件、选择温度
通过配置 INCHx = 1010自动启用所需的基准发生器
温度传感器。 任何其他配置都像选择了外部通道一样完成、包括
基准选择和转换存储器选择。

我尝试使用示例程序  msp430x54x_ADC12_10.c -但我没有获得任何类似于温度值的值...

请提供任何帮助。

谢谢、

梅希

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

    您好、Mechi、

    您能否分享 您获得的温度抗尖峰脉冲和 温度抗尖峰脉冲值?  

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

    您好、Aaron、

    感谢您的快速回复。

    以下是代码:

    //初始化 I/O 设备(I/O 端口的方向和输出值,A2D 转换)
    void InitDev ()
    {
    //...
    
    /* A/D 控制寄存器*/
    
    
    ADC12CTL0 = ADC12ON + ADC12MSC + ADC12SHT03 + ADC12REFON;//对32个 ADC12CLK 周期进行采样-针对温度打开 REF。
    //多个采样和转换。
    ADC12CTL1 = ADC12SHP + ADC12DIV_7 + ADC12SSEL_1 + ADC12CONSEQ_1;//序列转换、ADC12CLK:ACLK/8。
    
    /*设置转换存储器寄存器(以 A0开始并以 A1结束的序列。 *
    
    ADC12MCTL0 = ADC12INCH_2 + ADC12REF2_5V;// ADC12MEM0将读取 A2
    ADC12MCTL1 = ADC12INCH_3 + ADC12REF2_5V;// ADC12MEM1将读取 A3
    ADC12MCTL2 = ADC12INCH_1 + ADC12REF2_5V;// ADC12MC12MC12MEM2
    = ADC12_4 = ADC12REF_ADC12REF_5V;ADC12AMC1224_ADC12ADC12ADC12MCU24_ADC12ADC12_ADC12DC0 = ADC12MCTR2 = ADC12_ADC12MCTR2 = ADC12_ADC12MCTR2 = ADC12ADC12ADC12MC12
    // ADC12MEM4 -将读取 A4
    ADC12MCTL5 = ADC12INCH_5 + ADC12REF2_5V;// ADC12MEM5 -将读取 A5
    ADC12MCTL6 = ADC12INCH_6 + ADC12REF2_5V;// ADC12MEM6 -将读取
    温度 ADC12MCTL7 = ADC12INA6 + ADC12REF_5V;// ADC12MCA6 + ADC12REF_5V
    //最后一个通道的序列结束
    
    ADC12IE = 0x01;// A/D 中断使能
    }
    
    
    // A2D 中断-在序列中最后一个通道的转换完成时调用。
    //转换后读取通道数字值。
    #pragma vector=ADC12_vector
    __interrupt void Sampler (void)
    {
    while ((ADC12IFG & ADC12BUSY)=0);// ADC12IFG -中断标志
    
    SMP_ACC_0 += ADC12MEM0;
    SMP_ACC_1 += ADC12MEM1;
    SMP_ACC_2 += ADC12MEM2;
    SMP_ACC_3 += ADC12MEM3;
    SMP_ACC_4 += ADC12MEM4;
    SMP_ACC_5 += ADC12MEM5;
    SMP_ACC_6 += ADC12MEM6;
    SMP_ACC_7 += ADC12MEM7;//温度
    
    
    ADC12CTL0 &=~ADC12ENC; //禁用转换
    ADC12CTL0 &=~ADC12SC;//开始 A/D 转换
    }
    

    您是在关注我从另一个主题中提出的问题。

    在这里、该代码也适用于 IAR。 我返回到示例代码(如上所述)以查看所有步骤是否都正确完成。

    其他 A2D 通道(电压等用实际值读取)、但温度(ADC12MEM7)的值非常低。

    在示例中、转换代码为:

    //温度(单位:摄氏度)
    //((A10/4096*1500mV)- 894mV)*(1/3.66mV)=(A10/4096*410)- 244
    //=(A10 - 2438)*(410 / 4096)
    IntDegC =((temp - 2438)* 410)/4096;
    
    //华氏温度
    //((A10/4096*1500mV)- 829mV)*(1/2.033mV)=(A10/4096*738)- 408
    //=(A10 - 2264)*(738 / 4096)
    IntDegF =((temp - 2264)* 738)/ 4096; 

    因此最终的值非常低...

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

    我有时会在 ADC12MEM7中获得0xb、0xE 或0x7的读数-但不会更高

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

    使用 msp430x54x_ADC12_10.c 可以得到什么结果? (只需设置断点并查看变量即可。) 该实验将告诉您要查看的方向。

    --------

    ADC12MCTL7 = ADC12INCH_10 + ADC12REF2_5V + ADC12EOS; // ADC12MEM7 - will read A10 -temperature sensor

    The ADC12REF2_5V bit is in ADC12CTL0, not ADC12MCTLx. This requests SREF=4, which is, um, I'm not sure what it means exactly. I suspect you wanted:

    ADC12MCTL7 = ADC12INCH_10 + ADC12SREF_1 + ADC12EOS; // ADC12MEM7 - will read A10 -temperature sensor (VREF vs VSS)

    --------

    >ADC12IE= 0x01;

    这会设置 ADC12IE0、该值将在第一次转换完成后触发。 特别是对于这样一个慢的 ADC 时钟(ACLK/8、SHT=256)、这将是 ADC 达到 MCTL7之前很长的时间。 尝试:

    >ADC12IE = ADC12IE7;  //第8次转换后中断

    --------

    >  while( (ADC12IFG & ADC12BUSY) == 0);

    该测试是向后的、因此它要么根本不等待、要么将永远等待。 在上面更改 IE 后、您不需要此测试、但正确的形式是:

    >  while( (ADC12IFG & ADC12BUSY) != 0);

    --------

    // Temperature in Celsius
    // ((A10/4096*1500mV) - 894mV)*(1/3.66mV) = (A10/4096*410) - 244
    // = (A10 - 2438) * (410 / 4096)
    IntDegC = ((temp - 2438) * 410) / 4096;
    我不能完全确定所有这些常量的来源、但看起来您假设是1.5V 基准、但您似乎需要2.5V 基准。 对于您正在使用的基准、使用正确的校准常数也很重要。 [参考用户指南(SLAU208Q)第1.13.5.3节、或仅调整示例中的代码。]
    [编辑:固定段引用]
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的详细回答!

    我采纳了您的所有建议-但我仍然没有获得温度读数。

    我以循环方式运行示例(msp430x54x_ADC12_10.c)-并且我只获得0x00和0x12之间的值(值从0 - 5 - 10 - 16上升、然后返回到0)。

    BTW -用于计算华氏和摄氏温度的常量在示例本身中。

    再次感谢、

    梅希

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

    >BTW -用于计算华氏和摄氏温度的常量在示例本身中。

    我在示例中看到的是:

    >temperatureDegC=(float)(((long) temp - CALADC12_15V_30C)*(85 - 30))/
    >                  (CALADC12_15V_85C - CALADC12_15V_30C)+ 30.0f;

    有趣的常量在芯片中的位置(我不知道它们是什么)。

    --------

    在哪里可以看到小整数结果?

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

    e2e.ti.com/.../msp430x54x_5F00_adc12_5F00_10.c

    我附上了我遵循的示例。

    我在中断中从 ADC12MEM7读取的小值。 其他通道具有大得多的值...

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

    您附加的代码不使用 ADC12MEM7、而是 ADC12MEM0。 此外、算术看起来与此处的 TI (TiRex)版本不同:

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

    ----------

    我没有您的设备、但下面是我使用 F5529上的类似(非常相似)示例看到的情况:

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

    您显示的示例与我下载的示例完全不同...

    其中一个区别是这一行:

    /*初始化共享基准模块*/
    REFCTL0 |= REFMSTR + REFVSEL_0 + REFON;//启用内部1.5V 基准
    

    当我尝试您提到的样本时、根本没有读数。

    如何将温度读数传输到 ADC12MEM7 -这是我们器件中唯一可用的 ADC 通道?

    这是我尝试的-但是中断没有被调用:

    int main (void)
    {
    WDTCTL = WDTPW + WDTHOLD; //停止 WDT
    
    //初始化共享基准模块*/
    REFCTL0 |= REFMSTR + REFVSEL_0 + REFON;//启用内部1.5V 基准
    
    //初始化 ADC12_A */
    ADC12CTL0 = ADC12SHT0_8 + ADC12ON + ADC12REFON; //设置采样时间
    ADC12CTL1 = ADC12SHP; //启用采样计时器
    ADC12MCTL7 = ADC12SREF_1 + ADC12INCH_10;// ADC 输入通道 A10 =>温度感测
    ADC12IE = ADC12IE7;// 0x0001 // conv result-ADCMEMO
    
    _ delay_cycles 时的 ADC_IFG (75); //延迟以使 Ref 稳定
    //基于默认 DCO 频率。
    //请参阅数据表以了解典型的趋稳情况
    //时间。
    ADC12CTL0 |= ADC12ENC;
    
    while (1)
    {
    ADC12CTL0 &=~ADC12SC;
    ADC12CTL0 |= ADC12SC; //采样和转换开始
    
    _bis_SR_register (LPM4_bits + GIE); //启用中断的 LPM4
    __no_operation();
    
    //温度(单位:摄氏度)。 请参阅中的器件描述符表部分
    //系统复位、中断、和运行模式、系统控制模块
    //器件用户指南中的一章、了解有关的背景信息
    //使用的公式。
    TemperatureDegC=(float)(((long) temp - CALADC12_15V_30C)*(85 - 30))/
    (CALADC12_15V_85C - CALADC12_15V_30C)+ 30.0f;
    
    //华氏温度 TF =(9/5)*TC + 32
    TemperatureDegF = temperatureDegC * 9.0f / 5.0f + 32.0f;
    
    __no_operation(); //在此处设置断点
    }
    #if
    
    defined (__TI_Compiler_version__)|| defined (__IAR_systems_ICC__)
    #pragma vector=ADC12_vector
    __interrupt void ADC12ISR (void)
    #elif defined (__GNU__)
    void __attribute__((interrupt (ADC12_vector)#if Compiler
    
    (void)(void))#defineer!
    #endif
    {
    switch (__even_in_range (ADC12IV、34))
    {
    case 0:break; //向量0:无中断
    情况2:中断; //向量2:ADC 溢出
    情况4:中断; //向量4:ADC 时序溢出
    情况6: //向量6:ADC12IFG0
    温度= ADC12MEM7; //移动结果,IFG 被清除
    _BIC_SR_REGISTER_ON_EXIT (LPM4_BITS);//退出活动 CPU
    中断;
    案例8:中断; //向量8:ADC12IFG1
    大小写10:break; //向量10:ADC12IFG2
    大小写12:break; //向量12:ADC12IFG3
    case 14:break; //向量14:ADC12IFG4
    情况16:中断; //向量16:ADC12IFG5
    情况18:中断; //向量18:ADC12IFG6
    案例20:中断; //向量20:ADC12IFG7
    case 22:break; //向量22:ADC12IFG8
    case 24:break; //向量24:ADC12IFG9
    大小写26:break; //向量26:ADC12IFG10
    case 28:break; //向量28:ADC12IFG11
    case 30:break; //向量30:ADC12IFG12
    大小写32:break; //向量32:ADC12IFG13
    case 34:break; //向量34:ADC12IFG14
    默认值:break;
    }
    } 

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

    好消息-我终于在 ADC 中读取了温度读数(请参阅下面的代码)。

    现在、我必须确定正确的转换。 有许多不同的方程(正如我们在不同的样本中看到的...)。 我正在读取的值大约为0x08AE。数据表中应该有一个针对温度的 TLV 映射-但我找不到它。

    //初始化 I/O 设备(I/O 端口的方向和输出值,4-20mA 输出和 A2D 转换)
    void InitDev()
    {...
    
    (笑声)
    
    /* A/D 控制寄存器*/
    /*初始化共享基准模块*/
    REFCTL0 |= REFMSTR + REFVSEL_0 + REFON;//启用内部1.5V 基准
    
    
    ADC12CTL0 = ADC12ON + ADC12MSC + ADC12SHT03 + ADC12REFON;//对32个 ADC12CLK 周期进行采样-针对温度打开 REF。
    //多个采样和转换。
    ADC12CTL1 = ADC12SHP + ADC12DIV_7 + ADC12SSEL_1 + ADC12CONSEQ_1;//序列转换、ADC12CLK:ACLK/8。
    
    /*设置转换存储器寄存器(以 A0开始并以 A1结束的序列。 *
    
    ADC12MCTL0 = ADC12INCH_2 + ADC12REF2_5V;// ADC12MEM0将读取 VE_REF-(GND_420)至 VE_REF+(VCC)范围内的 A2 (VCC -3V)。
    ADC12MCTL1 = ADC12INCH_3 + ADC12REF2_5V;// ADC12MEM1将读取 VE_REF-(GND_420)至 VE_REF+(VCC)范围内的 A3 (VDD- 5V 除以2)。
    ADC12MCTL2 = ADC12INCH_1 + ADC12REF2_5V;// ADC12MEM2将读取 VE_REF-(GND_420)至 VE_REF+(VCC)范围内的 A1 (SnS_Vin -除以11)。
    ADC12MCTL3 = ADC12INCH_0 + ADC12REF2_5V;// ADC12MEM3 -将读取 VE_REF-(GND_420)至 VE_REF+(VCC)范围内的 A0 (SnS_Heater)。
    ADC12MCTL4 = ADC12INCH_4 + ADC12REF2_5V;// ADC12MEM4 -将在 VE_REF-(GND_420)至 VE_REF+(VCC)范围内读取 A4 (SnS_12v -因数为0.203187)。
    ADC12MCTL5 = ADC12INCH_5 + ADC12REF2_5V;// ADC12MEM5 -将在 VE_REF-(GND_420)至 VE_REF+(VCC)范围内读取 A5 (SnS_HV -介于1和2.6V 之间)。
    ADC12MCTL6 = ADC12INCH_6 + ADC12REF2_5V;// ADC12MEM6 -将在 VE_REF-(GND_420)至 VE_REF+(VCC)范围内读取 A6 (SnS_HV -介于1和2.6V 之间)。
    ADC12MCTL7 = ADC12INCH_10 + ADC12SREF_1 + ADC12EOS;// ADC12MEM7 -将读取 A10 -温度传感器
    //最后一个通道的序列结束
    
    ADC12IE = 0x0F;//所有8个通道的 A/D 中断使能
    ...
    
    。} 

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

    我使用了你所指出的例子中的公式-一切都运转良好。 感谢您的所有帮助。