Files
FilmForge/Src/ntc.c
T

71 lines
2.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "ntc.h"
#include "gd32f4xx_adc.h"
#include "gd32f4xx_rcu.h"
#include "gd32f4xx_gpio.h"
#include "board_config.h"
#include <math.h>
/**
* @brief 配置 NTC 引脚(PC5 模拟输入)与 ADC0 常规通道。
*/
static void ntc_gpio_adc_config(void) {
/* 使能 GPIOC 与 ADC0 时钟 */
rcu_periph_clock_enable(NTC_GPIO_RCU);
rcu_periph_clock_enable(NTC_ADC_RCU);
/* PC5 模拟输入模式 */
gpio_mode_set(NTC_GPIO_PORT, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, NTC_GPIO_PIN);
/* ADC0 独立模式,常规通道软件触发、单次转换、右对齐 */
adc_sync_mode_config(ADC_SYNC_MODE_INDEPENDENT);
adc_special_function_config(NTC_ADC, ADC_CONTINUOUS_MODE, DISABLE);
adc_special_function_config(NTC_ADC, ADC_INSERTED_CHANNEL, DISABLE);
adc_external_trigger_config(NTC_ADC, ADC_ROUTINE_CHANNEL, EXTERNAL_TRIGGER_DISABLE);
adc_data_alignment_config(NTC_ADC, ADC_DATAALIGN_RIGHT);
adc_channel_length_config(NTC_ADC, ADC_ROUTINE_CHANNEL, 1U);
adc_routine_channel_config(NTC_ADC, 0U, NTC_ADC_CHANNEL, NTC_SAMPLETIME);
adc_enable(NTC_ADC);
adc_calibration_enable(NTC_ADC);
}
void ntc_init(void) {
ntc_gpio_adc_config();
}
/**
* @brief 触发一次转换并读取 12bit 原始值。
*/
static uint16_t ntc_read_raw_once(void) {
adc_flag_clear(NTC_ADC, ADC_FLAG_EOC);
adc_software_trigger_enable(NTC_ADC, ADC_ROUTINE_CHANNEL);
/* 等待转换完成(EOC) */
while (SET != adc_flag_get(NTC_ADC, ADC_FLAG_EOC)) {}
return (uint16_t)adc_routine_data_read(NTC_ADC);
}
float ntc_read_temperature(void) {
uint32_t sum = 0U;
/* 多次采样均值降噪 */
for (uint8_t i = 0; i < NTC_SAMPLE_COUNT; i++) {
sum += ntc_read_raw_once();
}
float adc_val = (float)sum / (float)NTC_SAMPLE_COUNT;
/* 分压点电压:上拉 R_PULL 在 VREF 侧,NTC 接 GND 侧 */
float voltage = adc_val * NTC_VREF / NTC_ADC_MAX;
/* 反解 NTC 阻值:V = VREF * R / (R_PULL + R) => R = R_PULL * V / (VREF - V) */
if (voltage <= 0.0f || voltage >= NTC_VREF) {
/* 开路/短路等异常,返回 -273.15 表示无效 */
return -273.15f;
}
float r_ntc = NTC_R_PULL * voltage / (NTC_VREF - voltage);
/* B 值公式:1/T = 1/T25 + ln(R/R25)/B */
float t_k = 1.0f / (1.0f / NTC_T25 + logf(r_ntc / NTC_R25) / (float)NTC_B_VALUE);
return t_k - 273.15f;
}