#include "board.h" #include "adc.h" #include "main.h" #include "sma_filter.h" #include "tim.h" InfoBlock_t *InfoBlock = (InfoBlock_t *)(VERSION_OFFSET); uint8_t RELAY_State[RELAY_COUNT]; static volatile uint8_t adc_lock = 0; static SMAFilter_t conn_temp_adc_filter[2]; void RELAY_Write(relay_t num, uint8_t state){ switch (num) { case RELAY_AUX0: HAL_GPIO_WritePin(RELAY1_GPIO_Port, RELAY1_Pin, state); break; case RELAY_AUX1: HAL_GPIO_WritePin(RELAY2_GPIO_Port, RELAY2_Pin, state); break; case RELAY3: HAL_GPIO_WritePin(RELAY3_GPIO_Port, RELAY3_Pin, state); break; case RELAY_DC: HAL_GPIO_WritePin(RELAY4_GPIO_Port, RELAY4_Pin, state); break; case RELAY_AC: HAL_GPIO_WritePin(RELAY5_GPIO_Port, RELAY5_Pin, state); break; case RELAY_CP: HAL_GPIO_WritePin(RELAY_CP_GPIO_Port, RELAY_CP_Pin, state); break; case RELAY_CC: HAL_GPIO_WritePin(RELAY_CC_GPIO_Port, RELAY_CC_Pin, state); break; case RELAY_DC1: HAL_GPIO_WritePin(RELAY_DC_GPIO_Port, RELAY_DC_Pin, state); break; default: break; } RELAY_State[num] = state; } uint8_t RELAY_Read(relay_t num){ return RELAY_State[num]; } uint8_t IN_ReadInput(inputNum_t input_n){ switch(input_n){ case IN_SW0: return HAL_GPIO_ReadPin(IN_SW0_GPIO_Port, IN_SW0_Pin); case IN_SW1: return HAL_GPIO_ReadPin(IN_SW1_GPIO_Port, IN_SW1_Pin); case IN0: return HAL_GPIO_ReadPin(IN0_GPIO_Port, IN0_Pin); case IN_ESTOP: return HAL_GPIO_ReadPin(IN_ESTOP_GPIO_Port, IN_ESTOP_Pin); case IN_FB1: return HAL_GPIO_ReadPin(IN_FB1_GPIO_Port, IN_FB1_Pin); case IN_CONT_FB_DC: return HAL_GPIO_ReadPin(IN_FB2_GPIO_Port, IN_FB2_Pin); case ISO_IN: return HAL_GPIO_ReadPin(ISO_IN_GPIO_Port, ISO_IN_Pin); default: return 0; } } /* Заглушка: температура платы не измеряется (нет реализации АЦП для канала). */ uint8_t GetBoardTemp(void){ return 0; } /** * @brief Force PC12 (HEATER) as GPIO output via CRH/ODR, overriding UART5 MspInit. * CubeMX assigns PC12 to UART5_TX; on the board it drives the heater relay. */ static void Heater_PinForceOutput(void) { const uint32_t pin_cfg = GPIO_SPEED_FREQ_LOW; /* MODE=10, CNF=00: GP output PP, 2 MHz */ __HAL_RCC_GPIOC_CLK_ENABLE(); MODIFY_REG(HEATER_GPIO_Port->CRH, (GPIO_CRH_MODE12 | GPIO_CRH_CNF12), (pin_cfg << GPIO_CRH_MODE12_Pos)); HEATER_GPIO_Port->BSRR = (uint32_t)HEATER_Pin << 16U; } void Init_Peripheral(){ Heater_PinForceOutput(); HAL_GPIO_WritePin(HEATER_GPIO_Port, HEATER_Pin, GPIO_PIN_RESET); HAL_ADCEx_Calibration_Start(&hadc1); ADC_ScanStart(); RELAY_Write(RELAY_AUX0, 0); RELAY_Write(RELAY_AUX1, 0); RELAY_Write(RELAY3, 0); RELAY_Write(RELAY_DC, 0); RELAY_Write(RELAY_AC, 0); RELAY_Write(RELAY_CP, 0); RELAY_Write(RELAY_CC, 0); RELAY_Write(RELAY_DC1, 0); SMAFilter_Init(&conn_temp_adc_filter[0]); SMAFilter_Init(&conn_temp_adc_filter[1]); } float pt1000_to_temperature(float resistance) { // Константы для PT1000 const float R0 = 1000.0; // Сопротивление при 0 °C const float C_A = 3.9083E-3f; float temperature = (resistance-R0) / ( R0 * C_A); return temperature; } float calculate_NTC_resistance(int adc_value, float Vref, float Vin, float R) { // Преобразуем значение АЦП в выходное напряжение float Vout = (adc_value / 4095.0) * Vref; // Проверяем, чтобы Vout не было равно Vin if (Vout >= Vin) { return -1; // Ошибка: Vout не может быть больше или равно Vin } // Вычисляем сопротивление термистора float R_NTC = R * (Vout / (Vin - Vout)); return R_NTC; } int16_t CONN_ReadTemp(uint8_t ch){ uint32_t adcValue = 0u; adcValue = ch ? adc_data.ntc2_raw : adc_data.ntc1_raw; int32_t adc_filtered = SMAFilter_Update(&conn_temp_adc_filter[ch ? 1u : 0u], (int32_t)adcValue); if((uint32_t)adc_filtered > 4000u) { return 20; //Термодатчик не подключен } float Vref = 3.3; // Напряжение опорное float Vin = 5.0; // Входное напряжение float R = 1000; // Сопротивление резистора в Омах float temp = pt1000_to_temperature(calculate_NTC_resistance((int)adc_filtered, Vref, Vin, R)); return (int16_t)temp; } int16_t GBT_ReadTemp(uint8_t ch){ return CONN_ReadTemp(ch); } void ADC_Select_Channel(uint32_t ch) { ADC_ChannelConfTypeDef conf = { .Channel = ch, .Rank = 1, .SamplingTime = ADC_SAMPLETIME_28CYCLES_5, }; if (HAL_ADC_ConfigChannel(&hadc1, &conf) != HAL_OK) { Error_Handler(); } } uint8_t ADC_TryLock(void) { uint32_t primask = __get_PRIMASK(); __disable_irq(); if (adc_lock != 0u) { if (primask == 0u) { __enable_irq(); } return 0u; } adc_lock = 1u; if (primask == 0u) { __enable_irq(); } return 1u; } void ADC_LockBlocking(void) { while (ADC_TryLock() == 0u) { /* wait in main context until ADC is free */ } } void ADC_Unlock(void) { uint32_t primask = __get_PRIMASK(); __disable_irq(); adc_lock = 0u; if (primask == 0u) { __enable_irq(); } }