打印
[DemoCode下载]

M051系列通过内部ADC通道测量内部温度

[复制链接]
1794|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
1.1 简介
微控制器广泛的应用在不同的环境温度下,Nuvoton NuMicro® Cortex®–M0 M051 系列内建温度传感器,此范例将说明如何使用ADC取得温度传感器的摄氏温度。
1.2 原理
ADC 将参考电压作为基准,将参考电压平均对应至数阶,阶数与ADC的解析度相关。在测量温度传感器电压前,必须先得知参考电压,才能将量测温度传感器的数值换算成电压。


M051 ADC可量测Band-gap电压,Band-gap电压是固定电压,M051的Band-gap电压为1.2V,透过公式1-1 可算出ADC 参考电压。

M051内建的温度传感器为负温度系数传感器,参考图1-1,当温度越低,电压越高。其中Gain 为负温度系数,Offset则为误差调整。由公式1-3可将温度传感器的电压转换为摄氏温度。实际温度传感器参数与Band-gap电压规格请参考M051的相关文件。


使用特权

评论回复
沙发
幸福小强|  楼主 | 2021-7-10 17:36 | 只看该作者
EC_M051_Measure_Internal_Temperature_Sensor_V1.00 (1).zip (1.49 MB)
/**************************************************************************//**
* [url=home.php?mod=space&uid=288409]@file[/url]     main.c
* @brief
*           Use ADC measure internal temperature sensor.
* @note
* Copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include "M051Series.h"

#define PLL_CLOCK       ((uint32_t)50000000)  //PLL clock setting     ,Unit : Hz
#define VBG             ((double)1.20)        //M051 Band-gap voltage ,Unit : Volt
#define Offset          ((uint32_t)724)       //Temperature sensor curve formula offset
#define Gain            ((double)-1.75)       //Temperature sensor curve formula gain

/*---------------------------------------------------------------------------*/
/* Global variables                                                          */
/*---------------------------------------------------------------------------*/
char ai8TemperatureUnit[] = "\u2103";         //Degree Celsies encode

/*---------------------------------------------------------------------------*/
/* Functions                                                                 */
/*---------------------------------------------------------------------------*/
void SYS_Init(void);
void UART0_Init(void);
void ADC_Example_InternalTemperature(void);

/*---------------------------------------------------------------------------
   Function:    SYS_Init
   Parameters:  None.
   Returns:     None.
   Description: System and periphial module clock setting.
---------------------------------------------------------------------------*/
void SYS_Init(void)
{

    /* Enable Internal RC 22.1184MHz clock */
    CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);

    /* Waiting for Internal RC clock ready */
    CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);

    /* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
    CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));

    /* Enable external XTAL 12MHz clock */
    CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);

    /* Waiting for external XTAL clock ready */
    CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);

    /* Set core clock as PLL_CLOCK from PLL */
    CLK_SetCoreClock(PLL_CLOCK);

    /* Enable UART module clock */
    CLK_EnableModuleClock(UART0_MODULE);

    /* Enable ADC module clock */
    CLK_EnableModuleClock(ADC_MODULE);

    /* Select UART module clock source */
    CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));

    /* ADC clock source is 22.1184MHz, set divider to 100, ADC clock is 22.1184/100 MHz */
    CLK_SetModuleClock(ADC_MODULE, CLK_CLKSEL1_ADC_S_HIRC, CLK_CLKDIV_ADC(100));

}

/*---------------------------------------------------------------------------
   Function:    UART0_Init
   Parameters:  None.
   Returns:     None.
   Description: Initialize UART0 module, setting buadrate is 115200 bps
---------------------------------------------------------------------------*/
void UART0_Init(void)
{
    /* Reset IP */
    SYS_ResetModule(UART0_RST);

    /* Configure UART0 and set UART0 Baudrate */
    UART_Open(UART0, 115200);
}

/*---------------------------------------------------------------------------
   Function:    ADC_Example_InternalTemperature
   Parameters:  None.
   Returns:     None.
   Description: Measure chip band-gap voltage through ADC, and estimate
                external reference voltage. Measure chip internal temperature,
                according to temperature sensor curve formula and comparison
                voltage of reference. Finally printf out the Celsius.
---------------------------------------------------------------------------*/
void ADC_Example_InternalTemperature(void)
{
    int32_t  i32ConversionData;
    double   dVref;
    double   dTempData;

    printf("+----------------------------------------------------------------------+\n");
    printf("|               ADC for temperature sensor example code                |\n");
    printf("+----------------------------------------------------------------------+\n");

    printf("\nIn this example, software will get value from temperature sensor.\n");

    /* Enable Temperature Sensor function */
    SYS->TEMPCR |= SYS_TEMPCR_VTEMP_EN_Msk;

    /* Set the ADC operation mode as continuous scan, input mode as single-end and
    enable the analog input channel 7 */
    ADC_Open(ADC, ADC_ADCR_DIFFEN_SINGLE_END, ADC_ADCR_ADMD_CONTINUOUS, BIT7);

    /* Configure the analog input source of channel 7 */
    ADC_CONFIG_CH7(ADC, ADC_ADCHER_PRESEL_INT_BANDGAP);

    /* Power on ADC module */
    ADC_POWER_ON(ADC);

    /* clear the A/D interrupt flag for safe */
    ADC_CLR_INT_FLAG(ADC, ADC_ADF_INT);

    /* start A/D conversion */
    ADC_START_CONV(ADC);

    while (1)
    {
        /* Wait conversion done */
        while (!ADC_GET_INT_FLAG(ADC, ADC_ADF_INT));

        /* Stop A/D conversion */
        ADC_STOP_CONV(ADC);

        /* clear the A/D interrupt flag for safe */
        ADC_CLR_INT_FLAG(ADC, ADC_ADF_INT);

        /* Calculate dVref by using conversion result of VBG */
        /* ConversionData = VBG * 4096 / Vref */
        i32ConversionData = ADC_GET_CONVERSION_DATA(ADC, 7);
        dVref = VBG * 4096 / (double)i32ConversionData;

        /* Delay */
        CLK_SysTickDelay(500000);

        /* Configure the analog input source of channel 7 */
        ADC_CONFIG_CH7(ADC, ADC_ADCHER_PRESEL_INT_TEMPERATURE_SENSOR);

        /* start A/D conversion */
        ADC_START_CONV(ADC);

        /* Wait conversion done */
        while (!ADC_GET_INT_FLAG(ADC, ADC_ADF_INT));

        /* Stop A/D conversion */
        ADC_STOP_CONV(ADC);

        /* clear the A/D interrupt flag for safe */
        ADC_CLR_INT_FLAG(ADC, ADC_ADF_INT);

        /* Calculate value from temperature sensor  */
        /* ConversionData = Vtemp(V) * 4096 / dVref */
        /* Vtemp(mV) = Gain * Temperature + Offset  */
        i32ConversionData = ADC_GET_CONVERSION_DATA(ADC, 7);
        dTempData = (((double)i32ConversionData * dVref / 4096) * 1000 - Offset) / Gain;
        printf("Conversion result of channel %d: 0x%X (%.2f %s)\n", 7, i32ConversionData, dTempData, ai8TemperatureUnit);

        /* Delay */
        CLK_SysTickDelay(500000);

        /* Configure the analog input source of channel 7 */
        ADC_CONFIG_CH7(ADC, ADC_ADCHER_PRESEL_INT_BANDGAP);

        /* start A/D conversion */
        ADC_START_CONV(ADC);
    }
}

/*---------------------------------------------------------------------------
   Function:    main
   Parameters:  None.
   Returns:     None.
   Description: main routine of the example.
---------------------------------------------------------------------------*/
int main(void)
{

    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Init System, IP clock and multi-function I/O */
    SYS_Init();

    /* Lock protected registers */
    SYS_LockReg();

    /* Init UART0 for printf */
    UART0_Init();

    printf("\nSystem clock rate: %d Hz\n", SystemCoreClock);

    /* Internal Temperature */
    ADC_Example_InternalTemperature();

    /* Disable ADC module */
    ADC_Close(ADC);

    /* Disable ADC IP clock */
    CLK_DisableModuleClock(ADC_MODULE);

    /* Disable External Interrupt */
    NVIC_DisableIRQ(ADC_IRQn);

    printf("\nExit ADC example code\n");

    while (1);

}
执行结果

使用特权

评论回复
板凳
huahuagg| | 2021-7-10 18:06 | 只看该作者
内部测温一般用于什么方面

使用特权

评论回复
地板
cyclefly| | 2021-7-12 15:19 | 只看该作者
前几天也是看到Band-gap电压,
ADC的参考电压不固定么?

感觉很多之前的定义和理解,都被刷新了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

112

主题

1446

帖子

2

粉丝