laitimes

GD32 Development Guide Chapter 14 Internal Temperature Sensors

author:Embedded laboratory building

Development Environment:

MDK:Keil 5.30

Development board: GD32F207I-EVAL

MCU:GD32F207IK

14.1 Working principle of internal temperature sensor

The GD32 has an internal temperature sensor that can be used to measure the temperature (TA) in and around the CPU. The temperature sensor is internally connected to an ADCx_IN16 input channel, which converts the voltage output from the sensor to a digital value. The recommended sampling time for the analog input of the temperature sensor is 17.1μs. GD32's internal temperature sensor supports a temperature range of -40~125 degrees. The accuracy is relatively poor, about ±1.5°C.

Using the GD32 internal temperature sensor is as simple as setting up the internal ADC and activating its internal channels. The setup of the ADC has been covered in detail in the previous sections, so I won't go into it here. Let's take a look at 2 places related to temperature sensor settings.

In the first place, we want to use the GD32's internal temperature sensor, we must first activate the internal channel of the ADC, which is set here by the TSVREN bit (bit23) of the ADC_CTL1. Setting this bit to 1 enables the internal temperature sensor. Asserting ADC_CTL1 the ADC bit of the register, or an external trigger initiates ADC conversion.

In the second place, the internal temperature sensor of GD32 is fixed on channel 16 of the ADC, so after we set the ADC, we only need to read the value of channel 16, which is the voltage value returned by the temperature sensor. Based on this value, we can calculate the current temperature. The GD32 has a built-in temperature sensor, and the voltage of the temperature sensor can be read out through ADC_IN16 channel. A calculation formula is given:

Temperature (in ℃) = {(V25- Vsense) / Avg_Slope} + 25

  • The Vsense in the formula is the value read in the ADC_IN16. The unit is V.
  • Avg_Slope is the slope of temperature to ADC numerical conversion. Min=4.0 Typical=4.3 Max=4.6 The unit is mV/°C
  • V25 Min=1.34V Typical=1.43V Max=1.52V

Now, we can summarize the steps used by the GD32 internal temperature sensor, as follows:

1) Set up the ADC and turn on the internal temperature sensor.

As for how to set up the ADC, which was covered in the previous section, we have a similar setup to the previous section. The difference is that the previous temperature sensor reads the value of the external channel, while the internal temperature sensor is equivalent to connecting the channel port to the internal temperature sensor. So here, we want to turn on the internal temperature sensor function:

adc_tempsensor_vrefint_enable();           

2) Read the AD value of channel 16 and calculate the result.

After setting, we can read the voltage value of the temperature sensor, and when we get this value, we can calculate the temperature value using the above formula.

For example, read Vsense= 1.30V. Take the typical values of V25 and Avg_Slope, respectively,

The calculation is: (1.43 - 1.30)/0.0043 + 25 = 55.23

So the temperature is about 55°C.

  • The GD32 internal temperature sensor is connected to channel 16 of the ADC and used with the ADC to achieve temperature measurement;
  • The measuring range is –40~125°C, and the accuracy is ±1.5°C.
  • The temperature sensor generates a voltage that varies linearly with temperature and converts between 2V < VDDA < 3.6V.

14.2 Internal temperature sensor reading implementation

The internal ADC implementation code is simple and the configuration functions are as follows:

/*
    brief      Configure the ADC peripheral
    param[in]  none
    param[out] none
    retval     none
*/
void adc_config(void)
{
    /* enable GPIOC clock */
    rcu_periph_clock_enable(RCU_GPIOC);

    /* enable ADC0 clock */
    rcu_periph_clock_enable(RCU_ADC0);

    /* config ADC clock */
    rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV8);

    /* config the GPIO as analog mode */
    gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_3);

    /* ADC mode config */
    adc_mode_config(ADC_MODE_FREE);

    /* ADC continuous mode function disable */
    adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, DISABLE);

    /* ADC data alignment config */
    adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);

    /* ADC channel length config */
    adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1);

    /* ADC regular channel config */
    adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_16, ADC_SAMPLETIME_1POINT5);

    /* ADC trigger config */
    adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);

    /* ADC external trigger enable */
    adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);

    /* ADC temperature and Vrefint enable */
    adc_tempsensor_vrefint_enable();

    /* enable ADC interface */
    adc_enable(ADC0);
    delay_ms(1);

    /* ADC calibration and reset calibration */
    adc_calibration_enable(ADC0);

}           

The main function is also simple:

/*
    brief      main function
    param[in]  none
    param[out] none
    retval     none
*/
int main(void)
{
    uint32_t ad=0;  
    uint8_t i=0;

    //systick init
    sysTick_init();

    //usart init 115200 8-N-1
    com_init(COM1, 115200, 0, 1);

    //adc config
    adc_config();

    while(1)
    {      
        ad=0;
        for(i=0;i<50;i++)
        {

            adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);

            while(!adc_flag_get(ADC0,ADC_FLAG_EOC));//检查转换标志
            adc_flag_clear(ADC0, ADC_FLAG_EOC); // 清除结束标志

            ad=ad+adc_regular_data_read(ADC0);//ADC转换结果
        }
        ad=ad/50;
        printf("The current AD value = 0x%04X \r\n", ad); 
        printf("The current AD value = %f V \r\n",(float)ad / 4096 * 3.3); //实际电压
        printf("temperture =%f\r\n\r\n",(1.43-3.3/4096*ad)/0.0043+25);

        delay_ms(1000);
    }
}           

It is worth noting that the core code to get the internal temperature is the following lines:

adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
while(!adc_flag_get(ADC0,ADC_FLAG_EOC));//检查转换标志
adc_flag_clear(ADC0, ADC_FLAG_EOC); // 清除结束标志
ad=ad+adc_regular_data_read(ADC0);//ADC转换结果           

Just to prevent accidental errors, the average of 50 times is found here.

14.3 Experimental phenomena

After compiling the program, download it to the board, and you can see the temperature value output in the receiving area through the serial assistant.

GD32 Development Guide Chapter 14 Internal Temperature Sensors