Temperature measurement with STM32 thermistor

Posted by johndale on Fri, 21 Jan 2022 03:59:17 +0100

1, Hardware

STM32F103C8T6, thermistor sensor, OLED.

2, Introduction of thermistor sensor

A DO output port outputs digital quantity, and outputs 0 or 1 according to whether the external temperature exceeds the threshold of the sensor; An AO port outputs analog quantity. The detection of temperature shall be realized through analog quantity conversion.

3, Code implementation

In order to convert the analog quantity read by the single chip microcomputer into temperature, the following steps need to be taken: 1. Convert the read value to voltage; 2. Voltage to resistance 3. Calculate the actual temperature according to the formula.

1. ADC read. How to read ADC can be seen from the previous article on reading photoresist. The process is similar, but the pins are different. The code is as follows.

//Initialize ADC
//Here we only take the regular channel as an example
//We will open channels 0 ~ 3 by default                                                   
void  temp_Adc_Init(void)
{     
    ADC_InitTypeDef ADC_InitStructure; 
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE );      //Enable ADC1 channel clock
 

    RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //Set ADC frequency division factor 6 72m / 6 = 12, and the maximum ADC time cannot exceed 14M

    //PA1 as analog channel input pin                         
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;        //Analog input pin
    GPIO_Init(GPIOA, &GPIO_InitStructure);    

    ADC_DeInit(ADC1);  //Reset ADC1 and reset all registers of peripheral ADC1 to the default value

    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;    //ADC working mode: ADC1 and ADC2 work in independent mode
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;    //Analog to digital conversion works in single channel mode
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;    //Analog to digital conversion works in single conversion mode
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;    //The conversion is initiated by software rather than an external trigger
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;    //ADC data right alignment
    ADC_InitStructure.ADC_NbrOfChannel = 6;    //The number of ADC channels that perform rule conversion sequentially
    ADC_Init(ADC1, &ADC_InitStructure);    //According to ADC_ Initializes the register of the peripheral ADCx with the parameters specified in initstruct

    ADC_Cmd(ADC1, ENABLE);    //Enables the specified ADC1
    ADC_ResetCalibration(ADC1);    //Enable reset calibration  
    while(ADC_GetResetCalibrationStatus(ADC1));    //Wait until reset calibration is complete
    ADC_StartCalibration(ADC1);     //Turn on AD calibration
    while(ADC_GetCalibrationStatus(ADC1));     //Wait until calibration is complete
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);        //Enable the software conversion startup function of the specified ADC1
}
//Obtain ADC value
//ch: channel value 0 ~ 3
u16 temp_Get_Adc(u8 ch)   
{
      //Set the rule group channel, a sequence and sampling time of the specified ADC
    ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );    //ADC1,ADC channel, sampling time 239.5 cycles                      
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);        //Enable the software conversion startup function of the specified ADC1    
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//Wait for the conversion to end
    return ADC_GetConversionValue(ADC1);           //Returns the last conversion result of ADC1 rule group
}

u16 temp_Get_Adc_Average(u8 ch,u8 times)
{
    u32 temp_val=0;
    u8 t;
    for(t=0;t<times;t++)
    {
        temp_val+=temp_Get_Adc(ch);
        Delay_ms(5);
    }
    return temp_val/times;
}

2. Sampling value to voltage and resistance

For voltage calculation, the STM32F103C8T6 I use uses 12 bit ADC sampling, so the maximum sampling value is 2 ^ 12 = 4096, while the voltage of the single chip microcomputer is 3.3v, so the read voltage = the read sampling value / 4096 * 3.3V.

Find the resistance, as shown in the figure

vcc = 3.3V, the voltage of the thermistor is calculated above, and the current resistance value of the thermistor can be known by calculating the ratio

The code is as follows

//Analog to resistance
float temp_Get_R(u16 adct)
{
	//MCU 3.3v power supply = = "3v", calculate the voltage first
	float v1 = (float)(adct*3.3)/4096;//Voltage on ntc
	float v2 = 3.3 - v1;
	float r = (v1/v2)*10;
	
	return r;
}

3. Temperature calculation

According to the Kelvin formula, the current Kelvin temperature Tn can be directly obtained as follows: B=(lnR25 - lnRntc)/(1/T25 - 1/Tn)

Among them, the single chip microcomputer cannot use math h. So the logarithmic function should be implemented by itself.

Parameter introduction:

B. It is a coefficient related to the coefficient of thermistor itself (Baidu said it was provided by the manufacturer), 3435 (just ask the seller)

R25 is the resistance of the pull-up resistor,

Rntc is the resistance of the thermistor calculated above

T25: Kelvin temperature at 25 ℃, i.e. 298.15K

Tn: actual Kelvin temperature calculated at this time (C=Tn-273.15)

The code is as follows

Some parameters defined in header price

#define T25 298.15 / / application of voltage to temperature formula
#define R25 10
#define B	3435
//The calculation of ln(x) is realized
double myln(double a)
{
   int N = 15;//The first 15 + 1 items are taken to estimate
   int k,nk;
   double x,xx,y;
   x = (a-1)/(a+1);
   xx = x*x;
   nk = 2*N+1;
   y = 1.0/nk;
   for(k=N;k>0;k--)
   {
     nk = nk - 2;
     y = 1.0/nk+xx*y;
     
   }
   return 2.0*x*y;
}

float Get_Kelvin_Temperature(u16 t)
{
	float N1,N2,N3,N4;
	float Rntc = temp_Get_R(t);
	N1 = (myln(R25)-myln(Rntc))/B;
	N2 = 1/T25 - N1;
	N3 = 1/N2;
	N4 = N3-273.15;//Kelvin to Celsius
	
	return N4;
}

4. Main function

float temp2 = Get_Kelvin_Temperature(adct);
u16 t = (u16)temp2;
OLED_ShowNum(1,7,t,4);//The working range is 20-80

4, Physical condition

T is the temperature measured by thermistor 12 degrees

Temperature is the temperature measured by DHT11 before, 12 degrees. The error between the two is very small, which shows that ok the family....

 

Topics: Single-Chip Microcomputer stm32 ARM