#include "device_heat.h" #include "gd32f4xx.h" #include "ptz_struct.h" #include "agent_hyt.h" #include "pdebug.h" #include "cpu.h" /* * 温度采集使用的ADC1 */ #define HC4051_S0_PIN GPIO_PIN_14 #define HC4051_S0_PORT GPIOB #define HC4051_S1_PIN GPIO_PIN_15 #define HC4051_S1_PORT GPIOB #define HEAT_PIN GPIO_PIN_12 #define HEAT_PORT GPIOA #define R_constant 10.0 //千欧姆——分压电阻值 // #define R_25 10000.0//热敏电阻常温下的电阻值 // #define Ntc_B 3435.0//常量B // #define Kelvin_temp 273.15+25//常温——开尔文温度 //NTC电流 static float Ntc_current(uint16_t data) { static float curr; curr = ((float)data / 4096.0 * 3.3)/R_constant; return curr; } //NTC电压 static float Ntc_voltage(uint16_t data) { static float voltage; voltage = 3.3 - ((float)data / 4096.0 * 3.3); return voltage; } //NTC电阻 static float Ntc_resis(uint16_t data) { static float resis,curr,voltage; curr = Ntc_current(data); voltage = Ntc_voltage(data); resis = voltage / curr * 1000.0;//因为电流值放大了1000倍 return resis; } /*! \brief ADC1初始化,电压,电流,NTC温度采集 \param[in] none \param[out] none \retval none \note LH @2022.07.21 */ void ADC1_Init() { //配置引脚时钟 rcu_periph_clock_enable(RCU_GPIOC); rcu_periph_clock_enable(RCU_GPIOB); //引脚复用,PC2——电压ADC1-CH12,PC3——电流ADC1-CH13 gpio_mode_set(GPIOC,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,GPIO_PIN_2); gpio_mode_set(GPIOC,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,GPIO_PIN_3); /* H_NTC-PB0 ,V_NTC-PB1 */ // gpio_mode_set(GPIOB,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,GPIO_PIN_0); gpio_mode_set(GPIOB,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,GPIO_PIN_1); rcu_periph_clock_enable(RCU_ADC1); //总线时钟20分频=6MHZ adc_clock_config(ADC_ADCCK_PCLK2_DIV4); /***********************************************/ //对齐方式 ADC_INSERTED_CHANNEL adc_data_alignment_config(ADC1,ADC_DATAALIGN_RIGHT); //扫描模式 adc_special_function_config(ADC1,ADC_SCAN_MODE,ENABLE); //外部触发关闭 adc_external_trigger_config(ADC1,ADC_REGULAR_CHANNEL,DISABLE); //采集通道数 adc_channel_length_config(ADC1,ADC_INSERTED_CHANNEL, 3); //通道注入顺序 adc_inserted_channel_config(ADC1, 0, ADC_CHANNEL_13, ADC_SAMPLETIME_480);//电流 adc_inserted_channel_config(ADC1, 1, ADC_CHANNEL_12, ADC_SAMPLETIME_480);//电压 adc_inserted_channel_config(ADC1, 2, ADC_CHANNEL_9, ADC_SAMPLETIME_480); adc_enable(ADC1); adc_calibration_enable(ADC1); /* 初始化分时复用IO */ gpio_mode_set(HC4051_S0_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, HC4051_S0_PIN); gpio_output_options_set(HC4051_S0_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, HC4051_S0_PIN); gpio_mode_set(HC4051_S1_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, HC4051_S1_PIN); gpio_output_options_set(HC4051_S1_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, HC4051_S1_PIN); /* 初始化加热引脚 */ gpio_mode_set(HEAT_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, HEAT_PIN); gpio_output_options_set(HEAT_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, HEAT_PIN); } /*! \brief 初始化分时复用控制引脚和加热使能引脚 \param[in] none \param[out] none \retval none \note psx @2025.07.31 */ void heat_Init() { rcu_periph_clock_enable(RCU_GPIOA); rcu_periph_clock_enable(RCU_GPIOB); /* 初始化分时复用IO */ gpio_mode_set(HC4051_S0_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, HC4051_S0_PIN); gpio_output_options_set(HC4051_S0_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, HC4051_S0_PIN); gpio_mode_set(HC4051_S1_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, HC4051_S1_PIN); gpio_output_options_set(HC4051_S1_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, HC4051_S1_PIN); gpio_bit_reset(HC4051_S0_PORT, HC4051_S0_PIN); gpio_bit_reset(HC4051_S1_PORT, HC4051_S1_PIN); /* 初始化加热引脚 */ gpio_mode_set(HEAT_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, HEAT_PIN); gpio_output_options_set(HEAT_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, HEAT_PIN); } /*! \brief 分时复用温度采集选择为H_NTC */ static void choose_H_NTC(void) { gpio_bit_reset(HC4051_S0_PORT, HC4051_S0_PIN); gpio_bit_reset(HC4051_S1_PORT, HC4051_S1_PIN); } /*! \brief 分时复用温度采集选择为V_NTC */ static void choose_V_NTC(void) { gpio_bit_set(HC4051_S0_PORT, HC4051_S0_PIN); gpio_bit_reset(HC4051_S1_PORT, HC4051_S1_PIN); } /*! \brief 分时复用温度采集选择为EXT_NTC1 */ static void choose_EXT_NTC1(void) { gpio_bit_reset(HC4051_S0_PORT, HC4051_S0_PIN); gpio_bit_set(HC4051_S1_PORT, HC4051_S1_PIN); } /*! \brief 分时复用温度采集选择为EXT_NTC2 */ static void choose_EXT_NTC2(void) { gpio_bit_set(HC4051_S0_PORT, HC4051_S0_PIN); gpio_bit_set(HC4051_S1_PORT, HC4051_S1_PIN); } typedef void(*pctr) (void); pctr choose_ntc_func[4] = {&choose_H_NTC, &choose_V_NTC, &choose_EXT_NTC1, &choose_EXT_NTC2}; /*! \brief 启动加热 */ static void startHeat() { gpio_bit_set(HEAT_PORT, HEAT_PIN); } /*! \brief 关闭加热 */ static void closeHeat() { gpio_bit_reset(HEAT_PORT, HEAT_PIN); } //电压采集 static void ptz_Voltage_collect_adc1_task() { static uint32_t adc1_v[5]; static unsigned char adc1_num; int j,k; float tem; float curadc1; uint16_t value_V; adc1_v[adc1_num] = ADC_IDATA1(ADC1); // adc1_v[adc1_num] = (float)value_V / 4096.0 * 11 *3.3;//(float)value_V;// adc1_num++; if (adc1_num >= 5) { adc1_num = 0; for (j = 0; j < 5-1; j++) {//采样值由小到大排列 for (k = 0; k < 5-j-1; k++) { if (adc1_v[k] > adc1_v[k+1]) { tem = adc1_v[k]; adc1_v[k] = adc1_v[k+1]; adc1_v[k+1] = tem; } } } for (uint8_t i = 1; i < 5 - 1; i++) { curadc1 = curadc1 + adc1_v[i]; } curadc1 = curadc1 /((float)(5 - 2));//去掉一个最大值和一个最小值求平均值 g_ptz.Voltage = (float)curadc1 / 4096.0 * 11 *3.3;; memset(adc1_v,0,sizeof(adc1_v)); } } //电流采集 static void ptz_Current_collect_adc1_task() { static uint32_t adc1_i[5]; static unsigned char adc1_num; int j,k; float tem; float curadc0; uint16_t value_I; adc1_i[adc1_num] = ADC_IDATA0(ADC1); adc1_num ++; if (adc1_num >= 5) { adc1_num = 0; for (j = 0; j < 5-1; j++) {//采样值由小到大排列 for (k = 0; k < 5-j-1; k++) { if (adc1_i[k] > adc1_i[k+1]) { tem = adc1_i[k]; adc1_i[k] = adc1_i[k+1]; adc1_i[k+1] = tem; } } } for (uint8_t i = 1; i < 5 - 1; i++) { curadc0 = curadc0 + adc1_i[i]; } curadc0 = curadc0 /((float)(5 - 2));//去掉一个最大值和一个最小值求平均值 g_ptz.electric_current = ((float)curadc0 / 4096.0 * 3.3) / 0.25; // memset(adc1_i, 0, sizeof(adc1_i)); } } typedef struct _heat_data { float ext_ntc1; float ext_ntc2; float ntcT; } heat_data; heat_data m_heatData; //NTC温度计算,开尔文温度 static float Ntc_temp(uint16_t adc_data, float Ntc_B) { float R_ntc;//实际电阻 double temp,K,j,l,m;//实际温度 R_ntc = Ntc_resis(adc_data); K = R_ntc/10000.0; j = log(K);//log e为底数 l = j / Ntc_B; m = 1.0 /298.15; temp = 1/(l+m); // temp = 1/(j / Ntc_B + 1/Kelvin_temp); return (float)temp; } //温度采集并加热 static void ptz_heat_collect_adc1_task() { static uint32_t adc1_T[4][5]; static uint8_t adc1_num = 0; static uint8_t ntc_num = 0; adc1_T[ntc_num][adc1_num] = ADC_IDATA2(ADC1); if (++ntc_num < 4) { choose_ntc_func[ntc_num](); return; } ntc_num = 0; choose_ntc_func[ntc_num](); if (++adc1_num < 5) { return; } adc1_num = 0; uint32_t temp; uint32_t adc_data = 0; /* 采集H_NTC温度 */ for (int j = 0; j < 5-1; j++) {//采样值由小到大排列 for (int k = 0; k < 5-j-1; k++) { if (adc1_T[0][k] > adc1_T[0][k+1]) { temp = adc1_T[0][k]; adc1_T[0][k] = adc1_T[0][k+1]; adc1_T[0][k+1] = temp; } } } for(uint8_t i = 1; i < 5 - 1; i++) { adc_data += adc1_T[0][i]; } adc_data = adc_data / 3; g_ptz.H_boad_temp = (short int)(Ntc_temp(adc_data, 3450.0f) - 273.15 + 0.5); adc_data = 0; /* 采集V_NTC温度 */ for (int j = 0; j < 5-1; j++) { for (int k = 0; k < 5-j-1; k++) { if (adc1_T[1][k] > adc1_T[1][k+1]) { temp = adc1_T[1][k]; adc1_T[1][k] = adc1_T[1][k+1]; adc1_T[1][k+1] = temp; } } } for(uint8_t i = 1; i < 5 - 1; i++) { adc_data += adc1_T[1][i]; } adc_data = adc_data / 3; g_ptz.V_boad_temp = (short int)(Ntc_temp(adc_data, 3450.0f) - 273.15 + 0.5); adc_data = 0; /* 采集EXT_NTC1温度 */ for (int j = 0; j < 5-1; j++) { for (int k = 0; k < 5-j-1; k++) { if (adc1_T[2][k] > adc1_T[2][k+1]) { temp = adc1_T[2][k]; adc1_T[2][k] = adc1_T[2][k+1]; adc1_T[2][k+1] = temp; } } } for(uint8_t i = 1; i < 5 - 1; i++) { adc_data += adc1_T[2][i]; } adc_data = adc_data / 3; m_heatData.ext_ntc1 = (short int)(Ntc_temp(adc_data, 3950.0f) - 273.15 + 0.5); adc_data = 0; /* 采集EXT_NTC2温度 */ for (int j = 0; j < 5-1; j++) { for (int k = 0; k < 5-j-1; k++) { if (adc1_T[3][k] > adc1_T[3][k+1]) { temp = adc1_T[3][k]; adc1_T[3][k] = adc1_T[3][k+1]; adc1_T[3][k+1] = temp; } } } for(uint8_t i = 1; i < 5 - 1; i++) { adc_data += adc1_T[3][i]; } adc_data = adc_data / 3; m_heatData.ext_ntc2 = (short int)(Ntc_temp(adc_data, 3950.0f) - 273.15 + 0.5); adc_data = 0; //判定是否需要加热 if (g_ptz.H_boad_temp < -20 || g_ptz.V_boad_temp < -20 || m_heatData.ext_ntc1 < -20 || m_heatData.ext_ntc2 < -20) { startHeat(); } else if (g_ptz.H_boad_temp > -10 && g_ptz.V_boad_temp > -10 && m_heatData.ext_ntc1 > -10 && m_heatData.ext_ntc2 > -10) { closeHeat(); } } /*! \brief 采集并加热任务 */ static char ptz_heat_data_collect_task() { static uint16_t ntc_num = 0; while (1) { adc_software_trigger_enable(ADC1, ADC_INSERTED_CHANNEL); // OSTimeDlyHMSM(0u, 0u, 0u, 1u); while (!adc_flag_get(ADC1, ADC_FLAG_EOC)) { OSTimeDlyHMSM(0u, 0u, 0u, 1u); } adc_flag_clear(ADC1, ADC_FLAG_EOC); ptz_Voltage_collect_adc1_task(); ptz_Current_collect_adc1_task(); ptz_heat_collect_adc1_task(); OSTimeDlyHMSM(0u, 0u, 0u, 100u); } } static OS_STK task_heat_data_collect_stk[TASK_PTZ_HEAT_DATA_COLLECT_STK_SIZE]; static void creat_heat_task_data_collect(void) { CPU_INT08U task_err; CPU_INT08U name_err; task_err = OSTaskCreateExt((void (*)(void *)) ptz_heat_data_collect_task, (void *) 0, (OS_STK *)&task_heat_data_collect_stk[TASK_PTZ_HEAT_DATA_COLLECT_STK_SIZE - 1], (INT8U ) TASK_PTZ_HEAT_DATA_COLLECT_PRIO, (INT16U ) TASK_PTZ_HEAT_DATA_COLLECT_PRIO, (OS_STK *)&task_heat_data_collect_stk[0], (INT32U ) TASK_PTZ_HEAT_DATA_COLLECT_STK_SIZE, (void *) 0, (INT16U )(OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR)); #if (OS_TASK_NAME_EN > 0) OSTaskNameSet(TASK_PTZ_HEAT_DATA_COLLECT_PRIO, "ptz_heat_data_collect_task", &name_err); #endif if ((task_err == OS_ERR_NONE) && (name_err == OS_ERR_NONE)) { pdebug(DEBUG_LEVEL_INFO,"create ptz_heat_data_collect_task success\r\n"); } else { pdebug(DEBUG_LEVEL_FATAL,"create ptz_heat_data_collect_task failed\r\n"); } } void Init_ptz_heat_data_collect_task() { ADC1_Init(); heat_Init(); creat_heat_task_data_collect(); }