TI中文支持网
TI专业的中文技术问题搜集分享网站

tm4c123 内部温度测量问题

产品用了TM4C123内部温度传感器用来测量温度,根据参考程序写的代码,代码如下,目前测下来的问题是测量出来的温度波动范围很大,每隔一秒采样一次,取了平均值后范围在20度到30度之间,有个别几次能够到80度以上,甚至能采集到147度。所以想请教一下可能是什么问题,是代码问题?亦或是电源质量不好影响参考电压导致采样不准?或者是计算温度时浮点计算溢出出问题了?我用的ucosIII所以没有打开浮点

void init_adc0(void)

{

   SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
   SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_ADC0);
   SysCtlPeripheralReset(SYSCTL_PERIPH_ADC0);

   ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);
   ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_END);

}

void get_tempurate(void)

{

    INT32U pui32ADC0Value[4];
    INT32U ui32TempValueC = 0;

   

     ADCSequenceEnable(ADC0_BASE, 3);
    ADCIntClear(ADC0_BASE, 3);
    ADCProcessorTrigger(ADC0_BASE, 3);
    while(!ADCIntStatus(ADC0_BASE, 3, false))
    {
    }
    ADCIntClear(ADC0_BASE, 3);
    ADCSequenceDataGet(ADC0_BASE, 3, &pui32ADC0Value[0]);

    ADCIntClear(ADC0_BASE, 3); 
    ADCProcessorTrigger(ADC0_BASE, 3);
    while(!ADCIntStatus(ADC0_BASE, 3, false))
   {
   }
   ADCIntClear(ADC0_BASE, 3);
   ADCSequenceDataGet(ADC0_BASE, 3, &pui32ADC0Value[1]);

   ADCIntClear(ADC0_BASE, 3); 
   ADCProcessorTrigger(ADC0_BASE, 3);
   while(!ADCIntStatus(ADC0_BASE, 3, false))
  {
  }
   ADCIntClear(ADC0_BASE, 3);
   ADCSequenceDataGet(ADC0_BASE, 3, &pui32ADC0Value[2]);

    ADCIntClear(ADC0_BASE, 3);
    ADCProcessorTrigger(ADC0_BASE, 3);
   while(!ADCIntStatus(ADC0_BASE, 3, false))
    {
   }
   ADCIntClear(ADC0_BASE, 3);
   ADCSequenceDataGet(ADC0_BASE, 3, &pui32ADC0Value[3]);

    ADCSequenceDisable(ADC0_BASE, 3);

    ui32TempValueC = (pui32ADC0Value[0] + pui32ADC0Value[1] + pui32ADC0Value[2] + pui32ADC0Value[3]) / 4;

     ui32TempValueC = (uint32_t)(147.5 – ((75.0*3.3 *(float)ui32TempValueC)) / 4096.0);

}

xyz549040622:

还是使用不当的问题,看看官方的例程,实际测试没有太大波动

//sensor.
//
// Copyright (c) 2010-2017 Texas Instruments Incorporated.All rights reserved.
// Software License Agreement
////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.
//// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package.
//
//*****************************************************************************
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_memmap.h"
#include "driverlib/adc.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"
//*****************************************************************************
//
//! \addtogroup adc_examples_list
//! <h1>ADC Temperature Sensor (temperature_sensor)</h1>
//!
//! This example shows how to setup ADC0 to read the internal temperature
//! sensor.
//!
//! NOTE: The internal temperature sensor is not calibrated.This example
//! just takes the raw temperature sensor sample and converts it using the
//! equation found in the LM3S9B96 datasheet.
//!
//! This example uses the following peripherals and I/O signals.You must
//! review these and change as needed for your own board:
//! - ADC0 peripheral
//!
//! The following UART signals are configured only for displaying console
//! messages for this example.These are not required for operation of the
//! ADC.
//! - UART0 peripheral
//! - GPIO Port A peripheral (for UART0 pins)
//! - UART0RX - PA0
//! - UART0TX - PA1
//!
//! This example uses the following interrupt handlers.To use this example
//! in your own application you must add these interrupt handlers to your
//! vector table.
//! - None.
//
//*****************************************************************************
//*****************************************************************************
//
// This function sets up UART0 to be used for a console to display information
// as the example is running.
//
//*****************************************************************************
void
InitConsole(void)
{//// Enable GPIO port A which is used for UART0 pins.// TODO: change this to whichever GPIO port you are using.//SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);//// Configure the pin muxing for UART0 functions on port A0 and A1.// This step is not necessary if your part does not support pin muxing.// TODO: change this to select the port/pin you are using.//GPIOPinConfigure(GPIO_PA0_U0RX);GPIOPinConfigure(GPIO_PA1_U0TX);//// Enable UART0 so that we can configure the clock.//SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);//// Use the internal 16MHz oscillator as the UART clock source.//UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);//// Select the alternate (UART) function for these pins.// TODO: change this to select the port/pin you are using.//GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);//// Initialize the UART for console I/O.//UARTStdioConfig(0, 115200, 16000000);
}
int main(void)
{uint32_t ui32ADC0Value[4];volatile uint32_t ui32TempAvg;volatile uint32_t ui32TempValueC;volatile uint32_t ui32TempValueF;SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);InitConsole();//// Display the setup on the console.//UARTprintf("ADC ->\n");UARTprintf("Type: Internal Temperature Sensor\n");UARTprintf("Samples: One\n");UARTprintf("Update Rate: 250ms\n");UARTprintf("Input Pin: Internal temperature sensor\n\n");//5分频,使用PLL,外部晶振16M,system时钟源选择 main osc。系统时钟40MHZSysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);//使能ADC0ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0);//We want to use ADC0, sample sequencer 1,//we want the processor to trigger the sequence and we want to use the highest priorityADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_TS);ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_TS);ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_TS);//Configure steps 0 - 2 on sequencer 1 to sample the temperature sensor (ADC_CTL_TS).ADCSequenceStepConfigure(ADC0_BASE,1,3,ADC_CTL_TS|ADC_CTL_IE|ADC_CTL_END);//Sample the temperature sensor (ADC_CTL_TS) and configure the interrupt flag (ADC_CTL_IE)//Tell the ADC logic that this is the last conversion on sequencer1 (ADC_CTL_END).ADCSequenceEnable(ADC0_BASE, 1);//enable ADC sequencer 1while(1){ADCIntClear(ADC0_BASE, 1);ADCProcessorTrigger(ADC0_BASE, 1);//trigger the ADC conversion with softwarewhile(!ADCIntStatus(ADC0_BASE, 1, false)){}//wait for the conversion to completeADCSequenceDataGet(ADC0_BASE, 1, ui32ADC0Value);ui32TempAvg = (ui32ADC0Value[0] + ui32ADC0Value[1] + ui32ADC0Value[2] + ui32ADC0Value[3] + 2)/4;//Since 2/4 = 1/2 = 0.5, 1.5 will be rounded to 2.0 with//the addition of 0.5. In the case of 1.0, when 0.5 is added to yield 1.5, this will be rounded//back down to 1.0 due to the rules of integer math.即四舍五入ui32TempValueC = (1475 - ((2475 * ui32TempAvg)) / 4096)/10;//TEMP = 147.5 – ((75 * (VREFP – VREFN) * ADCVALUE) / 4096)//VREFP – VREFN=3.3Vui32TempValueF = ((ui32TempValueC * 9) + 160) / 5;UARTprintf("Temperature = %d*C or %d*F\r\n", ui32TempValueC,ui32TempValueF);//F = ( C * 9)/5 +32}
}

xyz549040622:

回复 alex c:

PLL时钟参考频率必须在范围5 MHz 到 25 MHz 之间,你的这个4M的频率能倍频起来才怪了。

alex c:

回复 xyz549040622:

我没有使用PLL 我是外部16m晶振分频到4m

SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);    //clk = 4MZ

xyz549040622:

回复 alex c:

你试着主频配置为通用的80Mhz试试,老实说,降频使用,还真没试过。

user5096354:

回复 xyz549040622:

请问这个程序适合TM4C1294板子吗

xyz549040622:

回复 user5096354:

大同小异吧,可能某个函数会有出入的地方,对照着库函数修改下就好了。

user5096354:

回复 xyz549040622:

嗯嗯,谢谢,小白还有一个问题, 采样序列的采样数是8,这8具体是什么意思呢,是同时对8个通道采样?还是依次对1个通道进行8次采样?看了论坛上的一些说法,感觉还是不太明白,能不能赐教一下?

xyz549040622:

回复 user5096354:

你指的是哪个函数的哪个参数呢,这个8应该是adc的通道

user5096354:

回复 xyz549040622:

采样序列发生器0(Sample Sequencer0)的采样数是8,就是ADCSequenceStepConfigure函数的ui32Step参数,是同时对8个通道采样?还是依次对1个通道进行8次采样?非常感谢!

赞(0)
未经允许不得转载:TI中文支持网 » tm4c123 内部温度测量问题
分享到: 更多 (0)