/*---------------------------------------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);
}
}