打印
[DemoCode下载]

利用ADC内部通道测量温度

[复制链接]
899|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
/**************************************************************************//**
* [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);

}


使用特权

评论回复
沙发
小明的同学|  楼主 | 2024-4-21 15:46 | 只看该作者

使用特权

评论回复
板凳
21mengnan| | 2024-4-21 18:15 | 只看该作者
利用的温漂吗

使用特权

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

本版积分规则

139

主题

1469

帖子

2

粉丝