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.

[参考译文] MSP430F5329:读取内部温度

Guru**** 2500885 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/720531/msp430f5329-reading-internal-temperature

器件型号:MSP430F5329

不确定我的行为是什么。 但我未正确读取内部温度。  

我使用的是2.5V 内部基准、我得到的 ADC 值为1374。  

查看器件描述符和
 
ADC_ref15_30_temp 2051

 ADC_ref15_85_temp 2435

ADC_ref20_30_temp 1547

 ADC_ref20_85_temp 1837

ADC_ref25_30_temp 1230

 ADC_ref25_85_temp 1458

乍一看、测量结果似乎是错误的、因为测量值介于30度和85度之间。 这可能是不正确的、因为它感觉触感很酷。 我想它更接近23-25°C。

进行数学运算

温度=(ADC - CAL_ADC_T30)*(((85 - 30) /(CAL_ADC_T85 - CAL_ADC_T30))+ 30

温度=(1374 - 1230)*(((55 /(1458 - 1230))+ 30 = 64.73摄氏度  

这不是正确的。 我会很热地触摸。  

我的第一个想法是内部参考错误、或者设置不正确。 但是、我使用内置分压器(通道11)使用相同的基准测量3.3V、并且工作正常。  

我正在读取一个序列的 ADC 值、每次启动一次。 我正在读取、通道0、1、2、3、 4、5 6、10和11。 通道0-6使用外部基准(3.3V)、10和11使用内部2.5V 基准。 通道2、3、4和11似乎运行良好。 通道0和1是电流测量值、我尚未开始测试、通道5和6是我尚未校准的温度传感器。 这就剩下了10个、我认为测试起来很容易、而不会影响硬件。

我每毫秒读取一次 ADC。 我累加8个样本、然后标记一个例程、在中断之外处理 ADC 值。  

ADC 中断读取数据并将其移动到结果数组中。

计时器 A0每毫秒中断一次、从结果数组获取数据并将其添加到累加器数组中、然后启动下一个 ADC 序列。 计数器递增。
当计数器达到8时、累加器值被移动到新的位置、累加器和计数器被清除为8、并且一个指示数据就绪的标志被置位。

似乎还可以 接收到的值除外。 有什么想法我做了什么错?  


静态常量 ADC12_A_configureMemoryParam CCH_I ={ADC12_A_MEMORY_0、
ADC12_A_INPUT_A0、
ADC12_A_VREFPS_AVCC、
ADC12_A_VREFNEG_AVSS、
ADC12_A_NOTENDO3DEXPERIENCE};
静态连接 ADC12_A_configureMemoryParam cDCH_I ={ADC12_A_MEMORY_1、
ADC12_A_INPUT_A1、
ADC12_A_VREFPS_AVCC、
ADC12_A_VREFNEG_AVSS、
ADC12_A_NOTENDO3DEXPERIENCE};
静态连接 ADC12_A_configureMemoryParam CCH_M2 ={ADC12_A_MEMORY_2、
ADC12_A_INPUT_A2、
ADC12_A_VREFPS_AVCC、
ADC12_A_VREFNEG_AVSS、
ADC12_A_NOTENDO3DEXPERIENCE};
静态连接 ADC12_A_configureMemoryParam CCH_M1 ={ADC12_A_MEMORY_3、
ADC12_A_INPUT_A3、
ADC12_A_VREFPS_AVCC、
ADC12_A_VREFNEG_AVSS、
ADC12_A_NOTENDO3DEXPERIENCE};
静态连接 ADC12_A_configureMemoryParam Cpk_M ={ADC12_A_MEMORY_4、
ADC12_A_INPUT_A4、
ADC12_A_VREFPS_AVCC、
ADC12_A_VREFNEG_AVSS、
ADC12_A_NOTENDO3DEXPERIENCE};
静态连接 ADC12_A_configureMemoryParam CTS_4 ={ADC12_A_MEMORY_5、
ADC12_A_INPUT_A5、
ADC12_A_VREFPS_AVCC、
ADC12_A_VREFNEG_AVSS、
ADC12_A_NOTENDO3DEXPERIENCE};
静态连接 ADC12_A_configureMemoryParam CTS_5 ={ADC12_A_MEMORY_6、
ADC12_A_INPUT_A6、
ADC12_A_VREFPS_AVCC、
ADC12_A_VREFNEG_AVSS、
ADC12_A_NOTENDO3DEXPERIENCE};
静态连接 ADC12_A_configureMemoryParam CTS_Ch ={ADC12_A_MEMORY_7、
ADC12_A_INPUT_TEMPSENSOR、// 10.
ADC12_A_VREFPS_INT、
ADC12_A_VREFNEG_AVSS、
ADC12_A_NOTENDO3DEXPERIENCE};
静态连接 ADC12_A_configureMemoryParam CV3_3 ={ADC12_A_MEMORY_8、
ADC12_A_INPUT_BATTERYMONITOR、//11
ADC12_A_VREFPS_INT、
ADC12_A_VREFNEG_AVSS、
ADC12_A_ENDO3DEXPERIENCE};



静态连接 ADC12_A_configureMemoryParam CTS_SLEEP ={ADC12_A_MEMORY_10、
ADC12_A_INPUT_TEMPSENSOR、
ADC12_A_VREFPS_INT、
ADC12_A_VREFNEG_AVSS、
ADC12_A_NOTENDO3DEXPERIENCE};

静态连接 ADC12_A_configureMemoryParam_cal ={ADC12_A_MEMORY_11、
ADC12_A_INPUT_BATTERYMONITOR、// 11.
ADC12_A_VREFPS_INT、
ADC12_A_VREFNEG_AVSS、
ADC12_A_NOTENDO3DEXPERIENCE};


void ADC_Configuration (void)
{
//初始化数据
ADC_Data[0]= 0;
ADC_Data[1]= 0;
ADC_Data[2]= 0;
ADC_Data[3]= 0;
ADC_Data[4]= 0;
ADC_Data[5]= 0;
ADC_Data[6]= 0;
ADC_Data[7]= 0;
ADC_Data[8]= 0;
ADC_Data_Counter = 0;


//确保硬件设置正确
P6SEL = 0x7F; //启用 A/D 通道输入

ADC12_A_disableConversions (ADC12_A_base、true);
ADC12_A_disable (ADC12_A_base);//配置时禁用。

//初始化对2.5V
Ref_setReferenceVoltage (REF_BASE、REF_VREF2_5V)的引用;
//启用芯片温度传感器
Ref_enableTempSensor (REF_BASE);
REFCTL0 |= 1;//强制它查看它是否不同。

//初始化 ADC12_A 模块
//
* ADC12_A 模块的基址
*使用内部 ADC12_A 位作为采样/保持信号来开始转换
*使用 MCLK 作为时钟源
*使用默认的1时钟分频
器*/
ADC12_A_init (ADC12_A_base、
ADC12_A_SAMPLEHOLDSOURCE_SC、
ADC12_A_CLOCKSOURCE_ADC12OSC、
ADC12_A_CLOCKDIVIDER_1);

// 12位
ADC12_A_setResolution (ADC12_A_base、ADC12_A_resolution_12位);

/*
ADC12_A 模块的基地址
*对于内存缓冲器0-7采样/保持、持续768个时钟周期
*对于内存缓冲器8-15采样/保持、持续4个时钟周期(默认)
*禁用多采样
*现在我想我们将测量所有内容、包括芯片
温度和3.3V 电源轨来查看它在运行期间的变化。
*
*注意:ADC12_A 的最小采样率可能为30us 或100us。
*本示例使用~154us 的采样时间来确保其正常工作。
*可以使用256个周期(51.2us)或512个周期(100.4us)、但
*得到的读数可能不太准确。
*
*采样时间>(Rs + 1800欧姆)* ln (2^(n+1)* 25pF + 800ns
*
*对于 CHARGE_MON1和 CHARGE_MON2以及 pack + mon、这意味着2.005us。 最大值
为* 5.4MHz 时钟为0.74us 太小、或8个时钟为1.48us 太小、
* 16为2.96us、这就足够了。
我们可以在1ms 内进行337个采样。
* 32是5.9us、大约为168us。
* 64是11us、在1us 的最佳情况下为84、在4.2MHz 的最坏情况下为0r
*是15.23us、在1ms 内为65个样本。 它为我们提供了大量裕度
*以使数据趋稳、并使 ADC 能够在足够
的时间*内完成操作、从而使1ms 计时器中断能够处理它。
/ADC12_A_setupSamplingTimer
(ADC12_A_base、
ADC12_A_CYCLEHOLD_64_CYCLES、// Low 0-7 Memory
ADC12_A_CYCLEHOLD_64_cycles、//高8-15内存
ADC12_A_MULTIPLESAMPLESENABLE);//正常

ADC12_A_enableReferenceBurst (ADC12_A_base);

//配置内存缓冲
器//
* ADC12_A 模块的基本地址
*配置内存缓冲器0
*将温度传感器映射到内存缓冲器0
* Vref+= Vref+(int) 2.5V
* Vref-= AVss
*内存缓冲器0不是序列的末尾
*/

ADC12_A_configureMemory (ADC12_A_base、(ADC12_A_configureMemoryParam *)&CCH_I);// 0x00 ADC12_A_configureParam
Memory (ADC12_A_base、(ADC12_A_configureMemoryParam *);// ADC12_ADC12_ADC12_ADC12_ADC12_A MemoryParam (ADC12_ADC12_ADC12_ADC12_ADC12_ADC12_ADC12_ADC12_A
)

;ADC12_ADC12_ADC12_ADC12_ADC12_ADC12_ADC12_ADC12_A MemoryParam);ADC12_ADC12_ADC12_ADC12_ADC12_ADC12_ADC12_ADC12_ADC12_ADC12_ADC12_A (ADC12_ADC12_ADC12_ADC12_ADC12_ADC12_ADC12_A





//此中断被睡眠状态使用不希望它在此模式下处于活动
状态 ADC12_A_disableInterrupt (ADC12_A_base、
ADC12IFG10);


ADC12_A_clearInterrupt (ADC12_A_base、
ADC12IFG8);

ADC12_A_enableInterrupt (ADC12_A_base、
ADC12IE8);


ADC12_A_ENABLE (ADC12_A_base);

ADC12_A_startConversion (ADC12_A_base、ADC12_A_MEMORY_0、ADC12_A_SEQOFCHANNELS);
}


#pragma vector=ADC12_vector
__interrupt void ADC12ISR (void)
{

uint16_t temp = ADC12IV;
add_trace_buf

(void);
(void)(void)(void);{uint16_t temp = ADC12IV);add_trate_break_translation_ree_translation (en_translation (en_translation);(
//向量0:无中断
情况2:中断; //向量2:ADC 溢出
情况4:中断; //向量4:ADC 时序溢出
//情况6:中断; //向量6:ADC12IFG0
情况6: //向量6:ADC12IFG0
//移动结果,IFG 被清除
//temperature sensor_adc = ADC12_A_getResults (ADC12_A_base、ADC12_A_MEMORY_0);
//退出活动 CPU
//_BIC_SR_REGISTER_ON_EXIT (LPM3_BITS);
中断;
案例8:中断; //向量8:ADC12IFG1
大小写10:break; //向量10:ADC12IFG2
情况12: //向量12:ADC12IFG3未使用?
结果[0]= ADC12MEM0; //移动结果,IFG 被清除
结果[1]= ADC12MEM1; //移动结果,IFG 被清除
结果[2]= ADC12MEM2; //移动结果,IFG 被清除
结果[3]= ADC12MEM3; //移动结果,IFG 被清除
中断;

// LPM0_EXIT;//退出活动 CPU,在此处设置断点
情况14:中断; //向量14:ADC12IFG4

案例16: //向量16:ADC12IFG5 //未使用?
结果[0]= ADC12MEM0; //移动结果,IFG 被清除
结果[1]= ADC12MEM1; //移动结果,IFG 被清除
结果[2]= ADC12MEM2; //移动结果,IFG 被清除
结果[3]= ADC12MEM3; //移动结果,IFG 被清除
结果[4]= ADC12MEM4; //移动结果,IFG 被清除
结果[5]= ADC12MEM5; //移动结果,IFG 被清除
// P1OUT ^= BIT2;

案例18: //向量18:ADC12IFG6未使用?
结果[0]= ADC12MEM0; //移动结果,IFG 被清除
结果[1]= ADC12MEM1; //移动结果,IFG 被清除
结果[2]= ADC12MEM2; //移动结果,IFG 被清除
结果[3]= ADC12MEM3; //移动结果,IFG 被清除
结果[4]= ADC12MEM4; //移动结果,IFG 被清除
结果[5]= ADC12MEM5; //移动结果,IFG 被清除
结果[6]= ADC12MEM6; //移动结果,IFG 被清除
LED1_OFF;
中断;

案例20:中断; //向量20:ADC12IFG7

案例22: //向量22:ADC12IFG8
//这是除睡眠之外的所有状态的近似中断。
ADC_DATA_READY = true;//用于检查
ADC_INTERRUPT_COUNTER++;//用于调试
结果[0]= ADC12MEM0; //移动结果,IFG 被清除
结果[1]= ADC12MEM1; //移动结果,IFG 被清除
结果[2]= ADC12MEM2; //移动结果,IFG 被清除
结果[3]= ADC12MEM3; //移动结果,IFG 被清除
结果[4]= ADC12MEM4; //移动结果,IFG 被清除
结果[5]= ADC12MEM5; //移动结果,IFG 被清除
结果[6]= ADC12MEM6; //移动结果,IFG 被清除
结果[7]= ADC12MEM7; //移动结果,IFG 被清除
结果[8]= ADC12MEM8; //移动结果,IFG 被清除
中断;

案例24:中断; //向量24:ADC12IFG9
情况26: //向量26:ADC12IFG10
//这是睡眠状态的中断
add_trace_buf (99);
TEMP_SENSOR_ADC = ADC12MEM10;

//我们仅在睡眠模式下执行此操作。 我们尚未进入 LPM3模式
//触发该中断时。
中断;
案例28: //向量28:ADC12IFG11
add_trace_buf (98);//用于 V3_3的校准。
{
uint16_t x;//修复有关易失性评估顺序的编译器警告
X = ADC12MEM10;
AVCC_ADC[AVCC_ADC_COUNT]= x;
}
AVCC_ADC_COUNT++;
break;
case 30:break; //向量30:ADC12IFG12
大小写32:break; //向量32:ADC12IFG13
case 34:break; //矢量34:ADC12IFG14
默认值:break;
}

//

由于计时器 A0和 ADC 中断紧密相连,我将
//将它们放在同一个文件中。 通常,它们将是单独


的//------------------------------------------------------------------------------------------------------------------------------------------------------
//此中断每毫秒执行一次。
//计时器 A0中断服务例程
#pragma vector=TIMER0_A0_vector
__interrupt void TIMER0_A0_ISR (void)
{

//add_trace_buf (101);
LED1_ON;
ADC_Data[0]+= Results[0]; //移动结果,IFG 被清除
ADC_Data[1]+= Result[1]; //移动结果、IFG 被清除
ADC_Data[2]+= Result[2]; //移动结果,IFG 被清除
ADC_Data[3]+= Result[3]; //移动结果,IFG 被清除
ADC_Data[4]+= Result[4]; //移动结果、IFG 被清除
ADC_Data[5]+= Results[5]; //移动结果,IFG 被清除
ADC_Data[6]+= Result[6]; //移动结果、IFG 被清除
ADC_Data[7]+= Results[7]; //移动结果、IFG 被清除
ADC_Data[8]+= Results[8]; //移动结果、IFG 被清零

//当 ADC12SC 触发一个序列时、连续的序列可由
// ADC12SC 位触发。 ADC12SC 必须在每个序列之后被软件清零
//以触发另一个序列。 当使用任何其它触发源时、ADC12ENC
//必须在每个序列之间切换。

//我们是否需要关闭和打开? 还是只需要将 ADC12SC 降低?
ADC12CTL0 &=~ADC12MSC;//关闭 ADC12
ADC12CTL0 |= ADC12MSC;//打开 ADC12

ADC12CTL0 &=~ADC12SC;
ADC12CTL0 |= ADC12SC;//开始转换-软件触发转换时间580uS

Timer_interrupt_counter++;//用于调试以查看我们是否丢失序列。
ADC_Data_Counter++;
如果(ADC_DATA_READY == false) DATA_NOT _READY_ERROR_COUNT++;//永远不会发生。 用于调试
ADC_DATA_READY = false;

if (ADC_Data_Counter = 8)//平均8次读取
{
ADC_chg_current8 = ADC_Data[0];//开始集成使用所有位的版本。
ADC_DSCH_current8 = ADC_Data[1];
ADC_CHARGE_MON28 = ADC_Data[2];
ADC_CHARGE_MON18 = ADC_Data[3];
ADC_packv8 = ADC_Data[4];
ADC_ts48 = ADC_Data[5];
ADC_ts58 = ADC_Data[6];
adc_tschip8 = adc_Data[7];
ADC_v3_38 = ADC_Data[8];
ADC_new_data_available = true;
ADC_Data_Counter = 0;

ADC_Data[0]= 0;
ADC_Data[1]= 0;
ADC_Data[2]= 0;
ADC_Data[3]= 0;
ADC_Data[4]= 0;
ADC_Data[5]= 0;
ADC_Data[6]= 0;
ADC_Data[7]= 0;
ADC_Data[8]= 0;

ADC_Sample_Counter++;
}

//其他计时功能基于1ms。

if (time_ms_counter!= 0) time_ms_counter--; //用于1ms 延迟函
数 if (bq34_CE_READ_ENABLE > 0) bq34_CE_READ_ENABLE--;//加电和退出睡眠
IF (bq769x_READ_ENABLE > 0) bq769x_READ_ENABLE--;//加电和退出睡眠
状态时使用 if (bq769x_READ_ENABLE > 0);//系统准备就绪> 0- //在加电和退出睡眠时使用

if (time_TO_READ_Data_Counter_MS!= 0) time_TO_READ_Data_Counter_MS-;
否则
{
Time_TO_READ_Data_Counter_MS = 333;
{
SI.Ready_Flags.TTRD =真; //TIME_TO_READ_Data = true;
LPM3_EXIT;
}
}
LED1_OFF;// 100us
}

void init_REF_calvalues (void)
{
TLV_getinfo (TLV_TAG_REFCAL、0、&bREFCAL_bytes、(uint16_t **)&pREFCAL);
}


//将 Ref 置于已知状态
void Ref_Init (void)
{
//必须在设置 ADC 前执行此操作。
ADC12_A_disable (ADC12_A_base);
ADC12_A_disable (ADC12_A_base);
ADC12_A_clearInterrupt (ADC12_A_base、0xFF);
//DAC12_A_disable (ADC12_A_base、DAC12_A_submodule_1);

Ref_DisableReferenceVoltage (REF_BASE);
while (Ref_isRefGenBusy (REF_BASE));
Ref_setTempVoltage (REF_BASE、REF_VREF2_5V);
Ref_DisableSensor (REF_BASE);
Ref_DisReferenceVoltageOutput (REF_BASE);
Ref_disableReferenceVoltage (REF_BASE);
}


 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    μs F5 UG (SLAU208O)第28.2.8节:"使用温度传感器时、采样周期必须大于30 μ s。"

    由于 ADC12OSC 的频率约为5MHz、因此64 (ADC)时钟的频率仅为13us 左右。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这很简单。 我在文档中遗漏了这一行内容。 看起来示例的上半部分始终为4个时钟、因此我认为64个时钟很慷慨。  

    30us 约为150个时钟、因此我将使用192个时钟。  

    不幸的是、昨天晚上我烧毁了我的硬件、所以在几天之后我才能再次进行测试。  

    谢谢、  

    基普