[DemoCode下载] 利用ADC内部通道测量温度

[复制链接]
 楼主| 小明的同学 发表于 2024-4-21 15:46 | 显示全部楼层 |阅读模式
  1. /**************************************************************************//**
  2. * [url=home.php?mod=space&uid=288409]@file[/url]     main.c
  3. * @brief
  4. *           Use ADC measure internal temperature sensor.
  5. * @note
  6. * Copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
  7. *****************************************************************************/
  8. #include <stdio.h>
  9. #include "M051Series.h"

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

  14. /*---------------------------------------------------------------------------*/
  15. /* Global variables                                                          */
  16. /*---------------------------------------------------------------------------*/
  17. char ai8TemperatureUnit[] = "\u2103";         //Degree Celsies encode

  18. /*---------------------------------------------------------------------------*/
  19. /* Functions                                                                 */
  20. /*---------------------------------------------------------------------------*/
  21. void SYS_Init(void);
  22. void UART0_Init(void);
  23. void ADC_Example_InternalTemperature(void);

  24. /*---------------------------------------------------------------------------
  25.    Function:    SYS_Init
  26.    Parameters:  None.
  27.    Returns:     None.
  28.    Description: System and periphial module clock setting.
  29. ---------------------------------------------------------------------------*/
  30. void SYS_Init(void)
  31. {

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

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

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

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

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

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

  44.     /* Enable UART module clock */
  45.     CLK_EnableModuleClock(UART0_MODULE);

  46.     /* Enable ADC module clock */
  47.     CLK_EnableModuleClock(ADC_MODULE);

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

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

  52. }

  53. /*---------------------------------------------------------------------------
  54.    Function:    UART0_Init
  55.    Parameters:  None.
  56.    Returns:     None.
  57.    Description: Initialize UART0 module, setting buadrate is 115200 bps
  58. ---------------------------------------------------------------------------*/
  59. void UART0_Init(void)
  60. {
  61.     /* Reset IP */
  62.     SYS_ResetModule(UART0_RST);

  63.     /* Configure UART0 and set UART0 Baudrate */
  64.     UART_Open(UART0, 115200);
  65. }

  66. /*---------------------------------------------------------------------------
  67.    Function:    ADC_Example_InternalTemperature
  68.    Parameters:  None.
  69.    Returns:     None.
  70.    Description: Measure chip band-gap voltage through ADC, and estimate
  71.                 external reference voltage. Measure chip internal temperature,
  72.                 according to temperature sensor curve formula and comparison
  73.                 voltage of reference. Finally printf out the Celsius.
  74. ---------------------------------------------------------------------------*/
  75. void ADC_Example_InternalTemperature(void)
  76. {
  77.     int32_t  i32ConversionData;
  78.     double   dVref;
  79.     double   dTempData;

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

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

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

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

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

  91.     /* Power on ADC module */
  92.     ADC_POWER_ON(ADC);

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

  95.     /* start A/D conversion */
  96.     ADC_START_CONV(ADC);

  97.     while (1)
  98.     {
  99.         /* Wait conversion done */
  100.         while (!ADC_GET_INT_FLAG(ADC, ADC_ADF_INT));

  101.         /* Stop A/D conversion */
  102.         ADC_STOP_CONV(ADC);

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

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

  109.         /* Delay */
  110.         CLK_SysTickDelay(500000);

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

  113.         /* start A/D conversion */
  114.         ADC_START_CONV(ADC);

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

  117.         /* Stop A/D conversion */
  118.         ADC_STOP_CONV(ADC);

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

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

  127.         /* Delay */
  128.         CLK_SysTickDelay(500000);

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

  131.         /* start A/D conversion */
  132.         ADC_START_CONV(ADC);
  133.     }
  134. }

  135. /*---------------------------------------------------------------------------
  136.    Function:    main
  137.    Parameters:  None.
  138.    Returns:     None.
  139.    Description: main routine of the example.
  140. ---------------------------------------------------------------------------*/
  141. int main(void)
  142. {

  143.     /* Unlock protected registers */
  144.     SYS_UnlockReg();

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

  147.     /* Lock protected registers */
  148.     SYS_LockReg();

  149.     /* Init UART0 for printf */
  150.     UART0_Init();

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

  152.     /* Internal Temperature */
  153.     ADC_Example_InternalTemperature();

  154.     /* Disable ADC module */
  155.     ADC_Close(ADC);

  156.     /* Disable ADC IP clock */
  157.     CLK_DisableModuleClock(ADC_MODULE);

  158.     /* Disable External Interrupt */
  159.     NVIC_DisableIRQ(ADC_IRQn);

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

  161.     while (1);

  162. }


 楼主| 小明的同学 发表于 2024-4-21 15:46 | 显示全部楼层
21mengnan 发表于 2024-4-21 18:15 | 显示全部楼层
利用的温漂吗
您需要登录后才可以回帖 登录 | 注册

本版积分规则

158

主题

1637

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部