MW22-01A/APP/Device/device_Other/device_heat.c

442 lines
12 KiB
C
Raw Permalink 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 "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-CH12PC3——电流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();
}