高级会员
- 积分
- 907
- 金钱
- 907
- 注册时间
- 2011-10-19
- 在线时间
- 196 小时
|
发表于 2018-9-17 16:14:59
|
显示全部楼层
稍微优化下代码:
[mw_shl_code=c,true]#define NTC_ADC_CHN ADC_Channel_10
// adc位数
#define ADC_BIT_COUNT 12
#define ADC_MAX ((1U << ADC_BIT_COUNT) - 1)
// 分压电阻阻值(K Ohms)
#define Rs 10.0
static float _temp;
// 热敏电阻的温度电阻表
static const struct
{
float t; // 温度
float r; // 阻值
} _rtTab[] =
{
{-40, 277.2},
{-38, 250.1},
{-36, 224.0},
{-34, 199.6},
{-32, 177.3},
{-30, 157.2},
{-28, 139.4},
{-26, 123.7},
{-24, 110.0},
{-22, 97.90},
{-20, 87.43},
{-18, 78.44},
{-16, 70.53},
{-12, 57.33},
{-8 , 46.89},
{-4 , 38.53},
{0 , 31.77},
{2 , 28.82},
{4 , 26.16},
{6 , 23.77},
{8 , 21.62},
{10 , 19.68},
{15 , 15.62},
{25 , 10.00},
{30 , 8.064},
{35 , 6.538},
{40 , 5.327},
{50 , 3.592},
{60 , 2.472},
{70 , 1.735},
{90 , 0.908},
{100, 0.674},
};
static void _TempInit(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
_temp = 0;
#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
/* ADCCLK = PCLK2/2 */
RCC_ADCCLKConfig(RCC_PCLK2_Div2);
#else
/* ADCCLK = PCLK2/4 */
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
#endif
/* Enable peripheral clocks --------------------------------------------------*/
/* Enable ADC1 and GPIO_LED clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2 | RCC_APB2Periph_GPIOC, ENABLE);
/* Configure analog input -------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* ADC2 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC2, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC2, NTC_ADC_CHN, 1, ADC_SampleTime_239Cycles5);
/* Enable ADC2 */
ADC_Cmd(ADC2, ENABLE);
/* Enable ADC2 reset calibration register */
ADC_ResetCalibration(ADC2);
/* Check the end of ADC2 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC2));
/* Start ADC2 calibration */
ADC_StartCalibration(ADC2);
/* Check the end of ADC2 calibration */
while(ADC_GetCalibrationStatus(ADC2));
}
/**
* 线性插值
* @param x1 第1点的x坐标
* @param y1 第1点的y坐标
* @param x2 第2点的x坐标
* @param y2 第2点的y坐标
* @param x 待插值点的x坐标
* @return 待插值点的y坐标
*/
static float _Interpolate(float x1, float y1, float x2, float y2, float x)
{
float y;
y = y1 + (x - x1) * (y2 - y1) / (x2 - x1);
return y;
}
float BspLcd_TempMeasure(void)
{
uint32_t adc;
size_t i, n;
float rt;
/* ADC2 regular channel14 configuration */
ADC_RegularChannelConfig(ADC2, NTC_ADC_CHN, 1, ADC_SampleTime_239Cycles5);
adc = 0;
n = 4;
/* Start ADC2 Software Conversion */
ADC_SoftwareStartConvCmd(ADC2, ENABLE);
for(i = 0; i < n; i++)
{
while(ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC) != SET);
ADC_ClearFlag(ADC2, ADC_FLAG_EOC);
adc += ADC_GetConversionValue(ADC2);
}
/* Start ADC2 Software Conversion */
ADC_SoftwareStartConvCmd(ADC2, DISABLE);
adc /= n;
// debug("adc: %lu\r\n", adc);
rt = Rs * adc / (ADC_MAX - adc);
if(rt >= _rtTab[0].r)
{
_temp = _rtTab[0].t;
debug("Rt too large: %.2f(Kohm)!\r\n", rt);
return _temp;
}
else if(rt <= _rtTab[ARRAY_SIZE(_rtTab) - 1].r)
{
_temp = _rtTab[ARRAY_SIZE(_rtTab) - 1].t;
debug("Rt too small: %.2f(Kohm)!\r\n", rt);
return _temp;
}
for(i = 0; i < ARRAY_SIZE(_rtTab); i++)
{
if(rt > _rtTab.r)
{
_temp = _Interpolate(_rtTab[i -1].r, _rtTab[i -1].t, _rtTab.r, _rtTab.t, rt);
break;
}
}
return _temp;
}
[/mw_shl_code] |
|