锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

STM32f103 ADC+DMA采集NTC热敏电阻温度10K(3950)

时间:2023-02-02 04:00:00 150kntc电阻576kohm电阻电阻58cntc47k3950温度电阻

利用ADC DMA采集 计算,查表(T-R表:百度)在这里插入图片描述

/*---------------------------------------ntc.h-------------------------------*/ /*定义结构:温度、电阻值*/ typedef struct{ 
            int    temperature;//单位:°C    float  resistance;//单位:Ω }NTC_10KTYPE;  #define NTC_LIST_MAX_SIZE (sizeof(ntc_10k_table) / sizeof(ntc_10k_table[0]))/*表的长度*/ #define ADC_REFERENCE_VOLTAGE (float)3.3/*adc 电压基准*/  #define ADC1_CONVERSION_CHANNEL_NUM 10 /*ADC采集通道的数量*/   #define ADC1_BAT_VOL_PORT GPIOA #define ADC1_BAT_VOL_PIN GPIO_Pin_0 #define ADC1_BAT_VOL_CHANNEL ADC_Channel_0  #define ADC1_BAT_OUT_CURRENT_PORT GPIOA #define ADC1_BAT_OUT_CURRENT_PIN GPIO_Pin_1 #define ADC1_BAT_OUT_CURRENT_CHANNEL ADC_Channel_1  #define ADC1_12V_VOL_PORT GPIOA #define ADC1_12V_VOL_PIN GPIO_Pin_2 #define ADC1_12V_VOL_CHANNEL ADC_Channel_2

#define ADC1_CHARGE_CURRENT_PORT GPIOA
#define ADC1_CHARGE_CURRENT_PIN GPIO_Pin_3
#define ADC1_CHARGE_CURRENT_CHANNEL ADC_Channel_3

#define ADC1_CHARGE_A_VOL_PORT GPIOA
#define ADC1_CHARGE_A_VOL_PIN GPIO_Pin_4
#define ADC1_CHARGE_A_VOL_CHANNEL ADC_Channel_4

#define ADC1_CHARGE_B_VOL_PORT GPIOA
#define ADC1_CHARGE_B_VOL_PIN GPIO_Pin_5
#define ADC1_CHARGE_B_VOL_CHANNEL ADC_Channel_5

#define ADC1_MOTOR_VOL_PORT GPIOA
#define ADC1_MOTOR_VOL_PIN GPIO_Pin_6
#define ADC1_MOTOR_VOL_CHANNEL ADC_Channel_6

#define ADC1_MOTOR_CURRENT_PORT GPIOA
#define ADC1_MOTOR_CURRENT_PIN GPIO_Pin_7
#define ADC1_MOTOR_CURRENT_CHANNEL ADC_Channel_7

#define ADC1_BAT_NTC_PORT GPIOC
#define ADC1_BAT_NTC_PIN GPIO_Pin_5
#define ADC1_BAT_NTC_CHANNEL ADC_Channel_15

#define ADC1_PCB_NTC_PORT GPIOC
#define ADC1_PCB_NTC_PIN GPIO_Pin_4
#define ADC1_PCB_NTC_CHANNEL ADC_Channel_14

extern u16 g_adc_converted_value[20];


void adc_sampling_init(void);
void adc_sampling_start(void);
float read_battery_ntc(void);

/*---------------------------------------ntc.c----------------------------------------------------------------*/
/*定义一个结构体类型数组:(温度-阻值)表 温度按降序填*/
const NTC_10KTYPE  ntc_10k_table[] = { 
        
125,332.07, 	
124,340.96, 	
123,350.12,  	
122,359.57, 	
121,369.32, 	
120,379.37, 		
119,389.77, 
118,400.5,
117,411.58,
116,423.02,	
115,434.84, 	
114,447.04, 	
113,459.65,
112,472.68,
111,486.14,
110,500.05,
109,514.38,
108,529.2,
107,544.5,
106,560.32,
105,576.67,
104,593.58,
103,611.06,
102,629.13,
101,647.83,
100,667.17,
99,687.22,
98,707.99,
97,729.49,
96,751.76,
95,774.82,
94,798.71,
93,823.47,
92,849.12,
91,875.7,
90,903.26,
89,931.76,
88,961.31,
87,991.94,
86,1023.7,
85,1056.6,
84,1090.8,
83,1126.2,
82,1163,
81,1201.2,
80,1240.8,
79,1282.1,
78,1325,
77,1369.5,
76,1415.9,
75,1464,
74,1514.1,
73,1566.1,
72,1620.3,
71,1676.6,
70,1735.2,
69,1796.2,
68,1859.5,		
67,1925.5, 		
66,1994.2,	
65,2065.7, 	
64,2140.1, 	
63,2217.7, 	
62,2298.5, 	
61,2382.7, 	
60,2470.4, 	
59,2562.1, 	
58,2657.6, 	
57,2757.3, 	
56,2861.3, 	
55,2969.8, 	
54,3083,  	
53,3201.2, 	
52,3324.7, 	
51,3453.6, 	
50,3588.2, 	
49,3728.8, 	
48,3875.7, 	
47,4029.2, 	
46,4189.7, 	
45,4357.4, 	
44,4532.9, 		
43,4716.4, 		
42,4908.3, 	
41,5109.2, 	
40,5319.4, 	
39,5539.4, 	
38,5769.8,
37,6011.1,
36,6263.9,	
35,6528.7, 	
34,6806.2, 	
33,7097,	
32,7402,
31,7721.8, 	
30,8057.2, 	
29,8409.1, 	
28,8778.3, 	
27,9165.9, 	
26,9572.8, 	
25,10000,	
24,10449, 	
23,10920, 	
22,11415, 	
21,11936,  	
20,12483, 	
19,13058, 	
18,13662, 	
17,14297, 	
16,14965, 	
15,15667,	
14,16405, 	
13,17181, 	
12,17997, 	
11,18856, 	
10,19760, 	
9,20716, 	
8,21724,  	
7,22788, 	
6,23910,	
5,25095, 	
4,26346, 	
3,27669, 	
2,29066, 	
1,30544, 	
0,32108, 	
-1,33738, 	
-2,35456, 		
-3,37267, 	
-4,39175, 	
-5,41185, 	 
-6,43303, 	
-7,45535,	
-8,47885, 	
-9,50360, 		
-10,52966,
-11,55736,
-12,58659,
-13,61745,
-14,65003,
-15,68443,
-16,72075,
-17,75910,
-18,79961,
-19,84239, 		
-20,88758, 	
-21,93644,
-22,98839, 
-23,104370,
-24,110250, 
-25,116530, 	
-26,123210,
-27,130350,
-28,137960,
-29,146100,
-30,154800,
-31,164000, 	
-32,173810, 	
-33,184290, 	
-34,195490,
-35,207460, 	
-36,220260, 	
-37,233950, 	
-38,248610,	
-39,264320,	
-40,281160, 	
};

u16 g_adc_converted_value[20]={ 
        0};/*定义数组存放ADC转换后的adc值*/

/**--------------functiion Info--------------------------------------------------------------------------------- **@functiion name: adc_sampling_init **@author: **@data: **@param:void **@param:void **@return:void **@descriptions: adc + dma 初始化ADC+DMA ** **--------------------------------------------------------------------------------------------------------**/
void adc_sampling_init(void)
{ 
        
		ADC_InitTypeDef   ADC_InitStructure;
		DMA_InitTypeDef   DMA_InitStructure;
		GPIO_InitTypeDef  GPIO_InitStructure;
	  

		/*clock*/
		RCC_ADCCLKConfig(RCC_PCLK2_Div6);/*ADCCLK = PCLK2/6*/

		RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1  | RCC_APB2Periph_ADC2,ENABLE);
	
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
		GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD
														| RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE);
	
		RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

		/*adc gpio configuration*/
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
		GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	
		GPIO_InitStructure.GPIO_Pin = ADC1_BAT_VOL_PIN;
		GPIO_Init(ADC1_BAT_VOL_PORT, &GPIO_InitStructure);
		GPIO_PinLockConfig(ADC1_BAT_VOL_PORT, ADC1_BAT_VOL_PIN);
	
		GPIO_InitStructure.GPIO_Pin = ADC1_BAT_OUT_CURRENT_PIN;
		GPIO_Init(ADC1_BAT_OUT_CURRENT_PORT, &GPIO_InitStructure);
		GPIO_PinLockConfig(ADC1_BAT_OUT_CURRENT_PORT, ADC1_BAT_OUT_CURRENT_PIN);
		
		GPIO_InitStructure.GPIO_Pin = ADC1_12V_VOL_PIN;
		GPIO_Init(ADC1_12V_VOL_PORT, &GPIO_InitStructure);
		GPIO_PinLockConfig(ADC1_12V_VOL_PORT, ADC1_12V_VOL_PIN);
		
		GPIO_InitStructure.GPIO_Pin = ADC1_CHARGE_CURRENT_PIN;
		GPIO_Init(ADC1_CHARGE_CURRENT_PORT, &GPIO_InitStructure);
		GPIO_PinLockConfig(ADC1_CHARGE_CURRENT_PORT, ADC1_CHARGE_CURRENT_PIN);
		
		GPIO_InitStructure.GPIO_Pin = ADC1_CHARGE_A_VOL_PIN;
		GPIO_Init(ADC1_CHARGE_A_VOL_PORT, &GPIO_InitStructure);
		GPIO_PinLockConfig(ADC1_CHARGE_A_VOL_PORT, ADC1_CHARGE_A_VOL_PIN);
		
		GPIO_InitStructure.GPIO_Pin = ADC1_CHARGE_B_VOL_PIN;
		GPIO_Init(ADC1_CHARGE_B_VOL_PORT, &GPIO_InitStructure);
		GPIO_PinLockConfig(ADC1_CHARGE_B_VOL_PORT, ADC1_CHARGE_B_VOL_PIN);
	
		GPIO_InitStructure.GPIO_Pin = ADC1_MOTOR_VOL_PIN;
		GPIO_Init(ADC1_MOTOR_VOL_PORT, &GPIO_InitStructure);
		GPIO_PinLockConfig(ADC1_MOTOR_VOL_PORT, ADC1_MOTOR_VOL_PIN);
		
		GPIO_InitStructure.GPIO_Pin = ADC1_MOTOR_CURRENT_PIN;
		GPIO_Init(ADC1_MOTOR_CURRENT_PORT, &GPIO_InitStructure);
		GPIO_PinLockConfig(ADC1_MOTOR_CURRENT_PORT, ADC1_MOTOR_CURRENT_PIN);
			
		GPIO_InitStructure.GPIO_Pin = ADC1_BAT_NTC_PIN;
		GPIO_Init(ADC1_BAT_NTC_PORT, &GPIO_InitStructure);
		GPIO_PinLockConfig(ADC1_BAT_NTC_PORT, ADC1_BAT_NTC_PIN);
		
		GPIO_InitStructure.GPIO_Pin = ADC1_PCB_NTC_PIN;
		GPIO_Init(ADC1_PCB_NTC_PORT, &GPIO_InitStructure);
		GPIO_PinLockConfig(ADC1_PCB_NTC_PORT, ADC1_PCB_NTC_PIN);
		
		/*dma channel1 configuration */
		DMA_DeInit(DMA1_Channel1);  

		DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(ADC1->DR);  

		DMA_InitStructure.DMA_MemoryBaseAddr = (u32)g_adc_converted_value;  
 
		DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  

		DMA_InitStructure.DMA_BufferSize = ADC1_CONVERSION_CHANNEL_NUM;  

		DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  

		DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 

		DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; 

		DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;  

		DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; /*DMA 自动轮询 只需软件触发一次*/

		DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; 

		DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; 
		DMA_Init(DMA1_Channel1,&DMA_InitStructure); 
		

		/*adc configuration*/
		ADC_DeInit(ADC1);
		ADC_StructInit(&ADC_InitStructure);
		ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
		ADC_InitStructure.ADC_ScanConvMode = ENABLE;
		ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
		ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
		ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
		ADC_InitStructure.ADC_NbrOfChannel = ADC1_CONVERSION_CHANNEL_NUM;
		ADC_Init(ADC1, &ADC_InitStructure);
		
		ADC_RegularChannelConfig(ADC1,ADC1_BAT_VOL_CHANNEL,1,ADC_SampleTime_239Cycles5);
		ADC_RegularChannelConfig(ADC1,ADC1_BAT_OUT_CURRENT_CHANNEL,2,ADC_SampleTime_239Cycles5);
		ADC_RegularChannelConfig(ADC1,ADC1_12V_VOL_CHANNEL,3,ADC_SampleTime_239Cycles5);
		ADC_RegularChannelConfig(ADC1,ADC1_CHARGE_CURRENT_CHANNEL,4,ADC_SampleTime_239Cycles5);
		ADC_RegularChannelConfig(ADC1,ADC1_CHARGE_A_VOL_CHANNEL,5,ADC_SampleTime_239Cycles5);
		ADC_RegularChannelConfig(ADC1,ADC1_CHARGE_B_VOL_CHANNEL,6,ADC_SampleTime_239Cycles5);
		ADC_RegularChannelConfig(ADC1,ADC1_MOTOR_VOL_CHANNEL,7,ADC_SampleTime_239Cycles5);
		ADC_RegularChannelConfig(ADC1,ADC1_MOTOR_CURRENT_CHANNEL,8,ADC_SampleTime_239Cycles5);
		ADC_RegularChannelConfig(ADC1,ADC1_BAT_NTC_CHANNEL,9,ADC_SampleTime_239Cycles5);
		ADC_RegularChannelConfig(ADC1,ADC1_PCB_NTC_CHANNEL,10,ADC_SampleTime_239Cycles5);
		
		ADC_DMACmd(ADC1,ENABLE);
		ADC_Cmd(ADC1,ENABLE);
		
		ADC_ResetCalibration(ADC1);
		while (ADC_GetResetCalibrationStatus(ADC1)){ 
        };
		
		ADC_StartCalibration(ADC1);	
		while (ADC_GetCalibrationStatus(ADC1)){ 
        }
		ADC_ClearFlag(ADC1,ADC_FLAG_EOC);

}



/**--------------functiion Info--------------------------------------------------------------------------------- **@functiion name: adc_sampling_start **@author: **@data: **@param:void **@param:void **@return:void **@descriptions: adc + dma 软件触发adc采集 ** **--------------------------------------------------------------------------------------------------------**/
void adc_sampling_start(void)
{ 
        
		ADC_ClearFlag(ADC1,ADC_FLAG_EOC);
		ADC_SoftwareStartConvCmd(ADC1,ENABLE);
		DMA_Cmd(DMA1_Channel1,ENABLE);
}

/**--------------functiion Info--------------------------------------------------------------------------------- **@functiion name: read_battery_ntc **@author: **@data: **@param:void **@param:void **@return:void **@descriptions: read battery temperature(ntc) 查表求温度 ** **--------------------------------------------------------------------------------------------------------**/
float read_battery_ntc(void)
{ 
        
     float gather_now_voltage=0;
     float ntc_now_resistance=0;
     int index=0;
     
		/*采集得到Va点电压 Va=gather_now_voltage*/
		gather_now_voltage=g_adc_converted_value[8]*ADC_REFERENCE_VOLTAGE/4096;
	  if(gather_now_voltage==0){ 
        gather_now_voltage=0.01;}
		/*求出热敏电阻的阻值 我这里Vcc电压和adc基准电压相等 r2=10k=10000*/
		ntc_now_resistance=(ADC_REFERENCE_VOLTAGE-gather_now_voltage)/(gather_now_voltage/10000);/*r=u/i*/
	
		/*根据热敏电阻阻值查表得出温度*/
		
		for(index=0; index<NTC_LIST_MAX_SIZE; index++)
		{ 
        
      	if(ntc_10k_table[index].resistance >= ntc_now_resistance)/*查到该温度表索引为 index*/
      	{ 
        
         	float min_resistance = (float)ntc_10k_table[(index>0) ? index-1 : 0].resistance;/*得出下区间电阻值*/
         
         	float max_resistance = (float)ntc_10k_table[index].resistance;/*得出上区间电阻值*/
         
         	float d1 = (float)(max_resistance - min_resistance) / 10;/*将该区间的阻值分为10等分*/
         
         	float d2 = (float)(((ntc_now_resistance - min_resistance) / d1) *(1/ 10));/*得出n份*0.1°C*/
        
         	/*以上四步是求小数点温度*/
         	return (float)ntc_10k_table[index].temperature + d2;
      	}
		}
   
		return (0.0);
}





/*--------------------------------------main-------------------------------------------*/
#include "ntc.h"

float  temperature=0;

/*本代码只提供一种思路*/
int main(void)
{ 
         
	delay_init();	

	adc_sampling_init();
	
	adc_sampling_start();/*开始触发DMA 自动轮询采集ADC*/
	
	delay_ms(20);

	/***主循环***/
	while (1)
	{ 
        
	 
	  temperature=read_battery_ntc(); **/*温馨提示:如若放在定时器中查表 注意查表需要时间(具体时间没测过) 定时器频率别开太快*/**
	  delay_ms(100);
		
	}
}
锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章