diff --git a/MATLAB/MCU_STM32_Matlab/stm32_matlab_conf.c b/MATLAB/MCU_STM32_Matlab/stm32_matlab_conf.c
index 4ace5cb..546224f 100644
--- a/MATLAB/MCU_STM32_Matlab/stm32_matlab_conf.c
+++ b/MATLAB/MCU_STM32_Matlab/stm32_matlab_conf.c
@@ -16,6 +16,7 @@ MCU_CortexMemoryTypeDef MCU_CORTEX_MEM;
// MCU PERIPH INIT
void Initialize_Periph_Sim(void)
{
+ uwTick = hmcu.SystemClock / (MCU_CORE_CLOCK / 1000);
Init_TIM_SIM();
Init_ADC_SIM();
}
diff --git a/MATLAB/MCU_STM32_Matlab/stm32f4xx_matlab_conf.json b/MATLAB/MCU_STM32_Matlab/stm32f4xx_matlab_conf.json
index b1970f0..489a2f4 100644
--- a/MATLAB/MCU_STM32_Matlab/stm32f4xx_matlab_conf.json
+++ b/MATLAB/MCU_STM32_Matlab/stm32f4xx_matlab_conf.json
@@ -15,7 +15,6 @@
"Initialize_Periph_Sim()"
],
"PeriphSimulation": [
- "uwTick = hmcu.SystemClock / (MCU_CORE_CLOCK / 1000)",
"Simulate_Periph_Sim()"
],
"PeriphDeinit": [
diff --git a/MATLAB/MCU_Wrapper/mcu_wrapper_conf.h b/MATLAB/MCU_Wrapper/mcu_wrapper_conf.h
index 8f592c0..ab4f3d5 100644
--- a/MATLAB/MCU_Wrapper/mcu_wrapper_conf.h
+++ b/MATLAB/MCU_Wrapper/mcu_wrapper_conf.h
@@ -55,7 +55,7 @@
// INPUT/OUTPUTS PARAMS START
#define IN_PORT_NUMB 2
#define ADC_PORT_1_WIDTH 6
-#define IN_PORT_2_WIDTH 1
+#define IN_PORT_2_WIDTH 16
#define OUT_PORT_NUMB 3
#define THYR_PORT_1_WIDTH 6
diff --git a/MATLAB/app_wrapper/app_init.c b/MATLAB/app_wrapper/app_init.c
index 705b1e2..c399266 100644
--- a/MATLAB/app_wrapper/app_init.c
+++ b/MATLAB/app_wrapper/app_init.c
@@ -24,6 +24,7 @@ void app_init(void) {
MX_TIM8_Init();
MX_TIM5_Init();
MX_ADC3_Init();
+ UPP_SetDefault(1, 1);
UPP_Init();
UPP_PreWhile();
diff --git a/MATLAB/app_wrapper/app_io.c b/MATLAB/app_wrapper/app_io.c
index 6a06c4e..97e301b 100644
--- a/MATLAB/app_wrapper/app_io.c
+++ b/MATLAB/app_wrapper/app_io.c
@@ -8,7 +8,7 @@
float dbg[16];
-#define PIN_READ(_verbname_) (_verbname_##_GPIO_Port->ODR & (_verbname_##_Pin)) ? 0 : 1
+#define PIN_READ(_verbname_) (_verbname_##_GPIO_Port->ODR & (_verbname_##_Pin)) ? 1 : 0
void Write_Thyristors(real_T* Buffer, int ind_port)
{
@@ -66,6 +66,7 @@ void app_readInputs(const real_T* Buffer) {
ADC_Set_Channel_Value(ADC3, 10, ReadInputArray(0,5));
alpha_dbg = ReadInputArray(1, 0);
+ upp.call->go = ReadInputArray(1, 1);
// USER APP INPUT END
}
@@ -83,19 +84,19 @@ void app_writeOutputBuffer(real_T* Buffer) {
int nn = 0;
//WriteOutputArray(upp.hangle.htim->Instance->CNT, 2, nn++);
- //WriteOutputArray((long long)(upp.hangle.htim->Instance->CCR1) - upp.hangle.htim->Instance->CNT, 2, nn++);
- //WriteOutputArray((long long)(upp.hangle.htim->Instance->CCR2) - upp.hangle.htim->Instance->CNT, 2, nn++);
- //WriteOutputArray((long long)(upp.hangle.htim->Instance->CCR3) - upp.hangle.htim->Instance->CNT, 2, nn++);
+ WriteOutputArray((long long)(upp.hangle.htim->Instance->CCR1) - upp.hangle.htim->Instance->CNT, 2, nn++);
+ WriteOutputArray((long long)(upp.hangle.htim->Instance->CCR2) - upp.hangle.htim->Instance->CNT, 2, nn++);
+ WriteOutputArray((long long)(upp.hangle.htim->Instance->CCR3) - upp.hangle.htim->Instance->CNT, 2, nn++);
//WriteOutputArray(dbg[0], 2, nn++);
//WriteOutputArray(dbg[1], 2, nn++);
//WriteOutputArray(dbg[2], 2, nn++);
- //WriteOutputArray(upp.hpwm.AllPhases[PHASE_A_POS].State, 2, nn++);
- //WriteOutputArray(upp.hpwm.AllPhases[PHASE_A_NEG].State, 2, nn++);
- //WriteOutputArray(upp.hpwm.AllPhases[PHASE_B_POS].State, 2, nn++);
- //WriteOutputArray(upp.hpwm.AllPhases[PHASE_B_NEG].State, 2, nn++);
- //WriteOutputArray(upp.hpwm.AllPhases[PHASE_C_POS].State, 2, nn++);
- //WriteOutputArray(upp.hpwm.AllPhases[PHASE_C_NEG].State, 2, nn++);
+ WriteOutputArray(upp.hpwm.AllPhases[PHASE_A_POS].State, 2, nn++);
+ WriteOutputArray(upp.hpwm.AllPhases[PHASE_A_NEG].State, 2, nn++);
+ WriteOutputArray(upp.hpwm.AllPhases[PHASE_B_POS].State, 2, nn++);
+ WriteOutputArray(upp.hpwm.AllPhases[PHASE_B_NEG].State, 2, nn++);
+ WriteOutputArray(upp.hpwm.AllPhases[PHASE_C_POS].State, 2, nn++);
+ WriteOutputArray(upp.hpwm.AllPhases[PHASE_C_NEG].State, 2, nn++);
// USER APP OUTPUT END
}
\ No newline at end of file
diff --git a/MATLAB/app_wrapper/app_wrapper.c b/MATLAB/app_wrapper/app_wrapper.c
index 78882d0..3941387 100644
--- a/MATLAB/app_wrapper/app_wrapper.c
+++ b/MATLAB/app_wrapper/app_wrapper.c
@@ -9,7 +9,15 @@
void app_step(void)
{
// USER APP STEP START
+ UPP_While();
+
+ static uint32_t uwTickPrev = 0;
+ if (uwTickPrev != uwTick)
+ {
+ uwTickPrev = uwTick;
+ UPP_Tick();
+ }
// USER APP STEP END
}
diff --git a/MATLAB/upp_r2023.slx b/MATLAB/upp_r2023.slx
index 2f48cc2..1685338 100644
Binary files a/MATLAB/upp_r2023.slx and b/MATLAB/upp_r2023.slx differ
diff --git a/UPP/AllLibs/Modbus b/UPP/AllLibs/Modbus
index 3aa2797..e0ce0e6 160000
--- a/UPP/AllLibs/Modbus
+++ b/UPP/AllLibs/Modbus
@@ -1 +1 @@
-Subproject commit 3aa279736d9383a06613f72d7b7462f0f23d7d4d
+Subproject commit e0ce0e6dbf35d035175d30971442bc8d99f3bdd7
diff --git a/UPP/AllLibs/PeriphGeneral b/UPP/AllLibs/PeriphGeneral
index 1cc886a..272642b 160000
--- a/UPP/AllLibs/PeriphGeneral
+++ b/UPP/AllLibs/PeriphGeneral
@@ -1 +1 @@
-Subproject commit 1cc886aa8dc5c2fcfdad93a21207793b2cd85fab
+Subproject commit 272642b310043355b0af95e0410afbbcb74d17b7
diff --git a/UPP/Core/Configs/memspi_config.h b/UPP/Core/Configs/memspi_config.h
index 54ed13b..aa1cde8 100644
--- a/UPP/Core/Configs/memspi_config.h
+++ b/UPP/Core/Configs/memspi_config.h
@@ -16,7 +16,7 @@
******************************************************************************/
#ifndef __SPI_MEMORY_CONFIG_H_
#define __SPI_MEMORY_CONFIG_H_
-#include "upp_config.h"
+#include "upp_defs.h"
/////////////////////////---USER SETTINGS---/////////////////////////
diff --git a/UPP/Core/Configs/modbus_config.h b/UPP/Core/Configs/modbus_config.h
index dcae48e..0851d68 100644
--- a/UPP/Core/Configs/modbus_config.h
+++ b/UPP/Core/Configs/modbus_config.h
@@ -19,7 +19,7 @@
******************************************************************************/
#ifndef _MODBUS_CONFIG_H_
#define _MODBUS_CONFIG_H_
-#include "upp_config.h"
+#include "upp_defs.h"
// Общие параметры
#define MODBUS_DEVICE_ID 1 ///< Адрес устройства в сети Modbus
diff --git a/UPP/Core/Configs/modbus_data.c b/UPP/Core/Configs/modbus_data.c
index 1626ce8..b1cb836 100644
--- a/UPP/Core/Configs/modbus_data.c
+++ b/UPP/Core/Configs/modbus_data.c
@@ -22,6 +22,9 @@
#include "modbus_inputregs.h"
#include "modbus_devid.h"
+/* DEFINE DATA FOR MODBUS */
+MB_DataStructureTypeDef MB_DATA = {0};; ///< Coils & Registers
+MB_DataInternalTypeDef MB_INTERNAL;
/**
* @brief Check is address valid for certain array.
@@ -78,6 +81,10 @@ MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, u
{
*pRegs = MB_Set_Register_Ptr(&MB_DATA.HoldRegs, Addr - R_HOLDING_ADDR); // указатель на выбранный по Addr регистр
}
+ else if(MB_Check_Address_For_Arr(Addr, Qnt, R_HOLDING_PRVT_PARAMS_ADR, R_HOLDING_PRVT_PARAMS_QNT) == ET_NO_ERRORS)
+ {
+ *pRegs = MB_Set_Register_Ptr(&MB_INTERNAL, Addr - R_HOLDING_PRVT_PARAMS_ADR); // указатель на выбранный по Addr регистр
+ }
// if address doesnt match any array - return illegal data address response
else
{
diff --git a/UPP/Core/Configs/modbus_data.h b/UPP/Core/Configs/modbus_data.h
index 848006b..985af13 100644
--- a/UPP/Core/Configs/modbus_data.h
+++ b/UPP/Core/Configs/modbus_data.h
@@ -50,20 +50,24 @@
#ifndef _MODBUS_DATA_H_
#define _MODBUS_DATA_H_
-
+
+#include "upp_defs.h"
+#include "upp_control.h"
#include "stdint.h"
//--------------SIZES OF DATA---------------
+#define R_HOLDING_PRVT_PARAMS_ADR 555
+#define R_HOLDING_PRVT_PARAMS_QNT (sizeof(UPP_PrvtParams_t)/sizeof(uint16_t))
// DEFINES FOR INPUT REGISTERS ARRAYS
#define R_INPUT_ADDR 0 ///< Начальный адрес входных регистров
-#define R_INPUT_QNT 16 ///< Количество входных регистров
+#define R_INPUT_QNT (sizeof(UPP_PUI_Values_t)/sizeof(uint16_t)) ///< Количество входных регистров
// DEFINES FOR HOLDING REGISTERS ARRAYS
#define R_HOLDING_ADDR 0 ///< Начальный адрес регистров хранения
-#define R_HOLDING_QNT 16 ///< Количество регистров хранения
+#define R_HOLDING_QNT (sizeof(UPP_PUI_Params_t)/sizeof(uint16_t)) ///< Количество регистров хранения
// DEFINES FOR COIL ARRAYS
#define C_COILS_ADDR 0 ///< Начальный адрес коилов
@@ -89,7 +93,7 @@
*/
typedef struct //MB_DataInRegsTypeDef
{
- uint16_t in[16];
+ UPP_PUI_Values_t pui;
}MB_DataInRegsTypeDef;
@@ -98,7 +102,7 @@ typedef struct //MB_DataInRegsTypeDef
*/
typedef struct //MB_DataInRegsTypeDef
{
- uint16_t out[16];
+ UPP_PUI_Params_t pui_params;
}MB_DataHoldRegsTypeDef;
@@ -153,6 +157,13 @@ typedef struct // tester modbus data
extern MB_DataStructureTypeDef MB_DATA;
+typedef struct
+{
+ UPP_FuncCalls_t FuncCalls;
+ UPP_PrvtParams_t param;
+}MB_DataInternalTypeDef;
+extern MB_DataInternalTypeDef MB_INTERNAL;
+
#endif //_MODBUS_DATA_H_
/////////////////////////////////////////////////////////////
diff --git a/UPP/Core/Configs/mylibs_config.h b/UPP/Core/Configs/mylibs_config.h
index 89c6755..a9dbd71 100644
--- a/UPP/Core/Configs/mylibs_config.h
+++ b/UPP/Core/Configs/mylibs_config.h
@@ -10,7 +10,7 @@
*************************************************************************/
#ifndef __MYLIBS_CONFIG_H_
#define __MYLIBS_CONFIG_H_
-#include "upp_config.h"
+#include "upp_defs.h"
// user includes
/**
diff --git a/UPP/Core/Configs/upp_config.h b/UPP/Core/Configs/upp_config.h
index 1208474..706225f 100644
--- a/UPP/Core/Configs/upp_config.h
+++ b/UPP/Core/Configs/upp_config.h
@@ -27,39 +27,58 @@
#define TEMP_1 0
#define TEMP_2 1
-/* Дефайны для базовых величин */
-#define PM_U_BASE 1216.0
-#define PM_I_BASE 53.0
-/* Дефайны для настройки мониторинга питания */
-#define PM_ADC_PERIOD_MKS 10
-#define PM_ZERO_CROSS_HYSTERESIS_V 10
-#define PM_ZERO_CROSS_DEBOUNCE_10US 2.5*100 // (2.5 * 100 = 2.5 мс)
-
-
-
-
-/* Рассчитанные дефайны */
-#define PM_ADC_PERIOD (180*PM_ADC_PERIOD_MKS)-1
-
-/* Общие для всего проекта структуры*/
/**
- * @brief Состояния полуволны
+ * @addtogroup UPP_DEFAULT_PARAMS Default params for external flash
+ * @ingroup UPP_CONFIG
+ * @brief Дефолтные параметры для внешней памяти. Они применятся по команде или по ошибке
+ * @{
*/
-typedef enum {
- UPP_WAVE_UNKNOWED = 0,
- UPP_WAVE_POSITIVE,
- UPP_WAVE_NEGATIVE
-} UPP_HalfWave_t;
-
+/* Параметры ПУИ */
+#define PUI_Iref_PERCENT_DEFAULT 150
+#define PUI_Tnt_MS_DEFAULT 300
+#define PUI_Umin_PERCENT_DEFAULT 80
+#define PUI_Umax_PERCENT_DEFAULT 120
+#define PUI_Imax_PERCENT_DEFAULT 99
+#define PUI_Imin_PERCENT_DEFAULT 7
+#define PUI_TiMax_US_DEFAULT 5000
+#define PUI_Tdelay_SECONDS_DEFAULT 30
+#define PUI_Interlace_EN_DEFAULT 5000
+
+/* Параметры АЦП */
+#define ADC_U_MAX_V_DEFAULT 1216.0
+#define ADC_I_MAX_A_DEFAULT 53.0
+#define ADC_U_ZERO_DEFAULT 2048
+#define ADC_I_ZERO_DEFAULT 2048
+
+/* Параметры определения перехода через ноль */
+#define ZERO_CROSS_HYSTERESIS_V_DEFAULT 10.0
+#define ZERO_CROSS_DEBOUNCE_10US_DEFAULT 2.5*100 // (2.5 * 100 = 2.5 мс)
+
+/* Параметры ШИМ для тиристоров */
+#define PWM_THYR_FREQUENCY_HZ_DEFAULT 20000
+#define PWM_THYR_PULSE_NUMBER_DEFAULT 20
+
+/** //UPP_DEFAULT_PARAMS
+ * @}
+ */
+
+
/**
- * @brief Названия Фаз
+ * @addtogroup UPP_COMPILED_PARAMS Fixed params
+ * @ingroup UPP_CONFIG
+ * @brief Параметры устанавливаемые на этапе компиляции. Без перепрошивки их не поменять
+ * @{
*/
-typedef enum {
- UPP_PHASE_A = 0,
- UPP_PHASE_B = 1,
- UPP_PHASE_C = 2,
- UPP_PHASE_UNKNOWN = 3
-} UPP_Phase_t;
+#define PM_U_NOM_V 690
+#define PM_I_NOM_V 5
+#define PM_F_NOM_HZ 50
+
+#define PM_ADC_PERIOD_MKS 10 ///< Период опроса АЦП в мкс
+/* Частоты таймеров в МГц*/
+#define ADC_TIM8_FREQ_MZH 180 ///< Частота тиков таймера АЦП
+#define PWM_TIM1_FREQ_MHZ 180 ///< Частота тиков таймера ШИМ (1-4 каналы)
+#define PWM_TIM3_FREQ_MHZ 90 ///< Частота тиков таймера ШИМ (5-6 каналы)
+#define ANGLE_TIM2_FREQ_MHZ 90 ///< Частота тиков таймера отсчета угла открытия тиристоров
#endif //_UPP_CONFIG_H_
diff --git a/UPP/Core/Configs/upp_defs.h b/UPP/Core/Configs/upp_defs.h
new file mode 100644
index 0000000..5d9ae19
--- /dev/null
+++ b/UPP/Core/Configs/upp_defs.h
@@ -0,0 +1,178 @@
+/**
+******************************************************************************
+* @file upp_defs.h
+* @brief Общие дефайны УПП
+******************************************************************************
+@addtogroup UPP_DEFS UPP defines
+@ingroup UPP_MAIN
+@brief Общие дефайны для всего проекта УПП
+@{
+******************************************************************************
+* @details
+******************************************************************************/
+#ifndef _UPP_DEFS_H_
+#define _UPP_DEFS_H_
+#include "upp_config.h"
+
+/**
+ * @addtogroup UPP_HIGHLEVEL Defines for high-level
+ * @ingroup UPP_DEFS
+ * @brief Дефайны УПП которые определяют коды ошибок и параметры для общения с верхним уровнем
+ * @{
+ */
+
+
+/**
+ * @brief Список аварий УПП
+ */
+typedef enum {
+ WM_Not_Init = 0, ///< УПП не инициализирован
+ WM_Ready = 1, ///< УПП в готовности
+ WM_Running = 2, ///< УПП в работе, управляет тиристорами
+ WM_Error = 3, ///< УПП в аварии
+} UPP_WorkModeType_t;
+
+/**
+ * @brief Список аварий УПП
+ */
+typedef enum {
+ Err_None = 0, ///< Неисправность отсутствует
+
+ /* Програмные ошибки */
+ Err_Internal_1 = 1, ///< Внутренняя неисправность УПП 1
+ Err_Internal_2 = 2, ///< Внутренняя неисправность УПП 2
+ Err_Internal_3 = 3, ///< Внутренняя неисправность УПП 3
+ Err_Internal_4 = 4, ///< Внутренняя неисправность УПП 4
+ Err_Internal_5 = 5, ///< Внутренняя неисправность УПП 5
+ Err_Internal_6 = 6, ///< Внутренняя неисправность УПП 6
+
+ /* Ошибки по питанию */
+ Err_Power_Digit_5V = 7, ///< Неисправность цифрового источника питания (5 В)
+ Err_Power_24V = 8, ///< Неисправность источника питания 24 В
+ Err_Power_Analog_5V = 9, ///< Неисправность аналогового источника питания микроконтроллера (± 5 В)
+ Err_Power_SCI_5V = 10, ///< Неисправность источника питания последовательных интерфейсов микроконтроллера (5 В)
+ Err_Power_DIO_24V = 11, ///< Неисправность источника питания дискретных входов/выходов (24 В)
+
+ /* Ошибки по допустимым пределам Наряжений/Токов/Температуры */
+ Err_OverCurrent = 12, ///< Ток выше допустимого (см. Imax и TiMax в @ref UPP_PUI_Params_t)
+ Err_OverVoltage = 13, ///< Напряжение сети выше допустимого (см. Umах в @ref UPP_PUI_Params_t)
+ Err_OverTemperature = 14, ///< Температура выше допустимой (плюс 85 °C)
+ Err_UnderVoltage = 15, ///< Напряжение сети ниже допустимого (см. Umin в @ref UPP_PUI_Params_t)
+
+ /* Ошибки по обрывам фаз */
+ Err_LossPhaseAll = 16, ///< Обрыв трёх фаз (см. Imin в @ref UPP_PUI_Params_t)
+ Err_LossPhaseA = 17, ///< Обрыв фазы A (см. Imin в @ref UPP_PUI_Params_t)
+ Err_LossPhaseB = 18, ///< Обрыв фазы B (см. Imin в @ref UPP_PUI_Params_t)
+ Err_LossPhaseC = 19, ///< Обрыв фазы C (см. Imin в @ref UPP_PUI_Params_t)
+
+ /* Другие ошибки */
+ Err_LongStart = 20, ///< Затянутый пуск (ток не спадает за установленное время) (см. Tdelay в @ref UPP_PUI_Params_t)
+ Err_Interlace = 21, ///< Неправильный порядок чередования фаз (см. Interlace в @ref UPP_PUI_Params_t)
+ Err_OverFrequency = 22, ///< Частота сети выше допустимой
+ Err_UnderFrequency = 23, ///< Частота сети ниже допустимой
+} UPP_ErrorType_t;
+
+
+/**
+ * @brief Структура данных от УПП передаваемых в ПУИ
+ */
+typedef struct {
+ uint16_t Error; /** @brief Текущая авария
+ @details В случае срабатывания защиты */
+
+ uint16_t WorkMode; /** @brief Режим работы
+ @details «Готовность» или «Работа» */
+
+ uint16_t Voltage; /** @brief Напряжение на входе УПП, Вольты */
+
+ uint16_t Current; /** @brief Ток на входе УПП, Амперы */
+
+ uint16_t Frequency; /** @brief Частота напряжения на входе УПП */
+
+ uint16_t Temperature; /** @brief Температура радиатора тиристоров, Градусы Цельсия */
+} UPP_PUI_Values_t;
+
+/**
+ * @brief Структура параметров УПП от ПУИ
+ * @details Параметры по умолчанию приведены в @ref UPP_DEFAULT_PARAMS
+ * @note Защиты №X приведены в @ref UPP_ErrorType_t
+ */
+typedef struct {
+ uint16_t Iref; /** @brief Уставка ограничения тока УПП
+ @details В диапазоне от 100 % до 500 % от Iн = 5 А
+ По умолчанию – @ref PUI_Iref_PERCENT_DEFAULT */
+
+ uint16_t Tnt; /** @brief Уставка времени нарастания заданного тока
+ @details В диапазоне от 50 до 5000 мс.
+ По умолчанию – @ref PUI_Tnt_MS_DEFAULT */
+
+ uint16_t Umin; /** @brief Уставка защиты №15 от понижения напряжения входной сети
+ @details В диапазоне от 5% до 99 % от Uн = 690 В.
+ По умолчанию – @ref PUI_Umin_PERCENT_DEFAULT */
+
+ uint16_t Umax; /** @brief Уставка защиты №13 от повышения напряжения входной сети
+ @details В диапазоне от 100% до 120 % от Uн = 690 В.
+ По умолчанию – @ref PUI_Umax_PERCENT_DEFAULT */
+
+ uint16_t Imax; /** @brief Уставка защиты №12 по току
+ @details В диапазоне от 5 % до 99 % от 50 А.
+ По умолчанию – @ref PUI_Imax_PERCENT_DEFAULT */
+
+ uint16_t Imin; /** @brief Уставка защит № 16 – №19 от обрыва фаз(ы)
+ @details В диапазоне от 0 % до 40 % от Iн = 5 А. При задании нуля эти защиты отключаются.
+ По умолчанию – @ref PUI_Imin_PERCENT_DEFAULT */
+
+ uint16_t TiMax; /** @brief Выдержка времени на срабатывание защиты № 12 по току
+ @details В диапазоне от 500 до 10000 мкс.
+ По умолчанию – @ref PUI_TiMax_US_DEFAULT */
+
+ uint16_t Tdelay; /** @brief Выдержка времени защиты № 20 от затянутого пуска
+ @details В диапазоне от 5 до 60 с.
+ По умолчанию – @ref PUI_Tdelay_SECONDS_DEFAULT */
+
+ uint16_t Interlace; /** @brief Разрешение защиты № 21 от обратного порядка чередования фаз;
+ @details 0 – нет защиты, 1 – есть защита.
+ По умолчанию – @ref PUI_Interlace_EN_DEFAULT */
+} UPP_PUI_Params_t;
+
+
+/** //UPP_HIGHLEVEL
+ * @}
+ */
+
+
+/**
+ * @addtogroup UPP_INTERNAL_DEFS Defines for internal use
+ * @ingroup UPP_DEFS
+ * @brief Дефайны УПП которые используютяс исключительно внутри программы
+ * @{
+ */
+#define ANGLE_PERIOD_MS (((float)1/(PM_F_NOM_HZ*2))*1000)
+/**
+ * @brief Состояния полуволны
+ */
+typedef enum {
+ UPP_WAVE_UNKNOWED = 0,
+ UPP_WAVE_POSITIVE,
+ UPP_WAVE_NEGATIVE
+} UPP_HalfWave_t;
+
+/**
+ * @brief Названия Фаз
+ */
+typedef enum {
+ UPP_PHASE_A = 0,
+ UPP_PHASE_B = 1,
+ UPP_PHASE_C = 2,
+ UPP_PHASE_UNKNOWN = 3
+} UPP_Phase_t;
+
+/** //UPP_INTERNAL_DEFS
+ * @}
+ */
+#endif //_UPP_DEFS_H_
+
+
+/** //UPP_DEFS
+ * @}
+ */
diff --git a/UPP/Core/Inc/main.h b/UPP/Core/Inc/main.h
index 704767c..ad65e1f 100644
--- a/UPP/Core/Inc/main.h
+++ b/UPP/Core/Inc/main.h
@@ -31,11 +31,10 @@ extern "C" {
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
-#include "upp_config.h"
+#include "upp_defs.h"
+#include "upp_errors.h"
#include "mylibs_include.h"
-#ifndef MATLAB
#include "modbus.h"
-#endif
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
@@ -56,7 +55,7 @@ extern "C" {
void Error_Handler(void);
/* USER CODE BEGIN EFP */
-extern __IO uint32_t micros;
+
/* USER CODE END EFP */
/* Private defines -----------------------------------------------------------*/
diff --git a/UPP/Core/PowerMonitor/adc_tools.c b/UPP/Core/PowerMonitor/adc_tools.c
index 5129c70..2a8b7eb 100644
--- a/UPP/Core/PowerMonitor/adc_tools.c
+++ b/UPP/Core/PowerMonitor/adc_tools.c
@@ -7,32 +7,6 @@
******************************************************************************/
#include "adc_tools.h"
-//Полосовой фильтр 45-55 Гц
-static float coefs_biquad_U[5] = {
- 0.000010f, // b0
- 0.000020f, // b1
- 0.000010f, // b2
- -1.900000f, // a1
- 0.950000f // a2
-};
-
-// ФНЧ 100 Гц
-static float coefs_biquad_I[5] = {
- 0.000010f, // b0
- 0.000020f, // b1
- 0.000010f, // b2
- -1.900000f, // a1
- 0.950000f // a2
-};
-// ФНЧ 10 Гц
-static float coefs_biquad_T[5] = {
- 0.0002f, // b0
- 0.0004f, // b1
- 0.0002f, // b2
- -1.98f, // a1
- 0.980f // a2
-};
-
static void ADC_EnableAllFilters(ADC_Periodic_t *adc)
{
for(int i = 0; i < ADC_NUMB_OF_CHANNELS; i++)
@@ -106,6 +80,8 @@ HAL_StatusTypeDef ADC_ConfigChannel(ADC_Periodic_t *adc, int ChNumb, uint16_t le
adc->Coefs[ChNumb].lMax = levelMax;
adc->Coefs[ChNumb].vMax = valueMax;
adc->Coefs[ChNumb].lZero = levelZero;
+
+ ADC_ResetStatistics(adc, ChNumb);
return HAL_OK;
}
@@ -116,16 +92,16 @@ HAL_StatusTypeDef ADC_ConfigChannel(ADC_Periodic_t *adc, int ChNumb, uint16_t le
* @return HAL Status.
* @details Запускает АЦП с частотой дискретизации на которую настроен таймер adc_tim.
*/
-HAL_StatusTypeDef ADC_Start(ADC_Periodic_t *adc, uint16_t Period)
+HAL_StatusTypeDef ADC_Start(ADC_Periodic_t *adc, float PeriodUs)
{
HAL_StatusTypeDef res;
if(assert_upp(adc))
return HAL_ERROR;
- if(Period == 0)
+ if(PeriodUs == 0)
return HAL_ERROR;
// Запускаем таймер который будет запускать опрос АЦП с заданным периодом
- __HAL_TIM_SET_AUTORELOAD(adc->htim, Period);
+ __HAL_TIM_SET_AUTORELOAD(adc->htim, TIM_MicrosToTick(PeriodUs, ADC_TIM8_FREQ_MZH));
res = HAL_TIM_Base_Start(adc->htim);
if(res != HAL_OK)
{
diff --git a/UPP/Core/PowerMonitor/adc_tools.h b/UPP/Core/PowerMonitor/adc_tools.h
index e61e16b..7a47e57 100644
--- a/UPP/Core/PowerMonitor/adc_tools.h
+++ b/UPP/Core/PowerMonitor/adc_tools.h
@@ -123,7 +123,7 @@ HAL_StatusTypeDef ADC_Init(ADC_Periodic_t *adc, TIM_HandleTypeDef *htim, ADC_Han
/* Конфигуарция канала АЦП. */
HAL_StatusTypeDef ADC_ConfigChannel(ADC_Periodic_t *adc, int ChNumb, uint16_t levelZero, float valueMax, uint16_t levelMax);
/* Запуск АЦП. */
-HAL_StatusTypeDef ADC_Start(ADC_Periodic_t *adc, uint16_t Period);
+HAL_StatusTypeDef ADC_Start(ADC_Periodic_t *adc, float PeriodUs);
/* Остановка АЦП. */
HAL_StatusTypeDef ADC_Stop(ADC_Periodic_t *adc);
diff --git a/UPP/Core/PowerMonitor/power_monitor.c b/UPP/Core/PowerMonitor/power_monitor.c
index f4dcf07..ff8c982 100644
--- a/UPP/Core/PowerMonitor/power_monitor.c
+++ b/UPP/Core/PowerMonitor/power_monitor.c
@@ -15,17 +15,32 @@ HAL_StatusTypeDef PowerMonitor_Init(PowerMonitor_t *hpm)
if(ADC_Init(&hpm->adc, &adc_tim, &hadc3) != HAL_OK)
return HAL_ERROR;
- if(ADC_ConfigChannel(&hpm->adc, ADC_CHANNEL_UBA, 2048, PM_U_BASE, 4095) != HAL_OK)
- return HAL_ERROR;
- if(ADC_ConfigChannel(&hpm->adc, ADC_CHANNEL_UAC, 2048, PM_U_BASE, 4095) != HAL_OK)
- return HAL_ERROR;
- if(ADC_ConfigChannel(&hpm->adc, ADC_CHANNEL_IC, 2048, PM_I_BASE, 4095) != HAL_OK)
+ if(ADC_ConfigChannel(&hpm->adc, ADC_CHANNEL_UBA,
+ MB_INTERNAL.param.adc.ADC_Zero[ADC_CHANNEL_UBA],
+ MB_INTERNAL.param.adc.ADC_Max[ADC_CHANNEL_UBA],
+ 4095) != HAL_OK)
return HAL_ERROR;
- if(ADC_ConfigChannel(&hpm->adc, ADC_CHANNEL_IA, 2048, PM_I_BASE, 4095) != HAL_OK)
+
+ if(ADC_ConfigChannel(&hpm->adc, ADC_CHANNEL_UAC,
+ MB_INTERNAL.param.adc.ADC_Zero[ADC_CHANNEL_UAC],
+ MB_INTERNAL.param.adc.ADC_Max[ADC_CHANNEL_UAC],
+ 4095) != HAL_OK)
+ return HAL_ERROR;
+
+ if(ADC_ConfigChannel(&hpm->adc, ADC_CHANNEL_IC,
+ MB_INTERNAL.param.adc.ADC_Zero[ADC_CHANNEL_IC],
+ MB_INTERNAL.param.adc.ADC_Max[ADC_CHANNEL_IC],
+ 4095) != HAL_OK)
+ return HAL_ERROR;
+
+ if(ADC_ConfigChannel(&hpm->adc, ADC_CHANNEL_IA,
+ MB_INTERNAL.param.adc.ADC_Zero[ADC_CHANNEL_IA],
+ MB_INTERNAL.param.adc.ADC_Max[ADC_CHANNEL_IA],
+ 4095) != HAL_OK)
return HAL_ERROR;
- if(ZC_Init(&hpm->zc, 3, PM_ZERO_CROSS_HYSTERESIS_V, PM_ZERO_CROSS_DEBOUNCE_10US) != HAL_OK)
+ if(ZC_Init(&hpm->zc, 3, (float)MB_INTERNAL.param.zc.Hysteresis/100, MB_INTERNAL.param.zc.DebouneCouner) != HAL_OK)
return HAL_ERROR;
if(ZC_ConfigChannel(&hpm->zc, U_BA, ZC_BOTH_EDGES) != HAL_OK)
@@ -41,7 +56,7 @@ HAL_StatusTypeDef PowerMonitor_Init(PowerMonitor_t *hpm)
HAL_StatusTypeDef PowerMonitor_Start(PowerMonitor_t *hpm)
{
- if(ADC_Start(&hpm->adc, PM_ADC_PERIOD) != HAL_OK)
+ if(ADC_Start(&hpm->adc, PM_ADC_PERIOD_MKS) != HAL_OK)
return HAL_ERROR;
return HAL_OK;
@@ -51,6 +66,7 @@ HAL_StatusTypeDef PowerMonitor_Start(PowerMonitor_t *hpm)
void PowerMonitor_Handle(PowerMonitor_t *hpm)
{
+ /* Считываем АЦП */
static uint32_t last_zc_cnt[ADC_NUMB_OF_U_CHANNELS] = {0};
ADC_Handle(&hpm->adc);
diff --git a/UPP/Core/PowerMonitor/zero_cross.c b/UPP/Core/PowerMonitor/zero_cross.c
index d587251..621f08e 100644
--- a/UPP/Core/PowerMonitor/zero_cross.c
+++ b/UPP/Core/PowerMonitor/zero_cross.c
@@ -28,9 +28,9 @@ HAL_StatusTypeDef ZC_Init(ZeroCross_Handle_t *zc, uint8_t num_channels,
memset(zc, 0, sizeof(ZeroCross_Handle_t));
// Установка параметров хендла
- zc->NumChannels = num_channels;
- zc->Hysteresis = hysteresis;
- zc->DebounceSamples = debounce_samples;
+ zc->Config.NumChannels = num_channels;
+ zc->Config.Hysteresis = hysteresis;
+ zc->Config.DebounceSamples = debounce_samples;
// Инициализация каналов
for (int i = 0; i < num_channels; i++) {
@@ -63,7 +63,7 @@ HAL_StatusTypeDef ZC_ConfigChannel(ZeroCross_Handle_t *zc, uint8_t channel,
if (assert_upp(zc)){
return HAL_ERROR;
}
- if (channel >= zc->NumChannels) {
+ if (channel >= zc->Config.NumChannels) {
return HAL_ERROR;
}
@@ -94,7 +94,7 @@ void ZC_ProcessChannel(ZeroCross_Handle_t *zc, uint8_t channel, float value, uin
if (!zc->f.Monitoring) {
return;
}
- if (channel >= zc->NumChannels) {
+ if (channel >= zc->Config.NumChannels) {
return;
}
int zc_detected = 0;
@@ -111,16 +111,16 @@ void ZC_ProcessChannel(ZeroCross_Handle_t *zc, uint8_t channel, float value, uin
}
// Детектирование rising edge (отрицательное -> положительное)
- if ((zc_ch->LastValue <= -zc->Hysteresis) &&
- (value >= zc->Hysteresis))
+ if ((zc_ch->LastValue <= -zc->Config.Hysteresis) &&
+ (value >= zc->Config.Hysteresis))
{
if (zc_ch->EdgeType == ZC_RISING_EDGE || zc_ch->EdgeType == ZC_BOTH_EDGES) {
- if(zc->DebounceSamples)
+ if(zc->Config.DebounceSamples)
{
if(zc_ch->DebounceCounter == 0)
{
- zc_ch->DebounceCounter = zc->DebounceSamples;
+ zc_ch->DebounceCounter = zc->Config.DebounceSamples;
}
}
@@ -128,16 +128,16 @@ void ZC_ProcessChannel(ZeroCross_Handle_t *zc, uint8_t channel, float value, uin
}
}
// Детектирование falling edge (положительное -> отрицательное)
- else if ((zc_ch->LastValue >= zc->Hysteresis) &&
- (value <= -zc->Hysteresis))
+ else if ((zc_ch->LastValue >= zc->Config.Hysteresis) &&
+ (value <= -zc->Config.Hysteresis))
{
if (zc_ch->EdgeType == ZC_FALLING_EDGE || zc_ch->EdgeType == ZC_BOTH_EDGES) {
- if(zc->DebounceSamples)
+ if(zc->Config.DebounceSamples)
{
if(zc_ch->DebounceCounter == 0)
{
- zc_ch->DebounceCounter = zc->DebounceSamples;
+ zc_ch->DebounceCounter = zc->Config.DebounceSamples;
}
}
@@ -149,7 +149,7 @@ void ZC_ProcessChannel(ZeroCross_Handle_t *zc, uint8_t channel, float value, uin
{
zc_ch->HalfWave = zc_detected == 1 ? UPP_WAVE_POSITIVE : UPP_WAVE_NEGATIVE;
zc_ch->Occurred = 1;
- uint32_t RealTimeShift = 0;//zc->DebounceSamples*(timestamp - zc->LastTick); // коло-во тиков * период вызова функции
+ uint32_t RealTimeShift = 0;//zc->Config.DebounceSamples*(timestamp - zc->LastTick); // коло-во тиков * период вызова функции
// Переход подтвержден сразу
uint32_t RealTimestamp = timestamp-RealTimeShift;
@@ -166,7 +166,7 @@ void ZC_ProcessChannel(ZeroCross_Handle_t *zc, uint8_t channel, float value, uin
}
// Сохраняем текущее значение для следующей итерации в случае если оно не в мертвой зоне
- if((value > zc->Hysteresis) || (value < -zc->Hysteresis))
+ if((value > zc->Config.Hysteresis) || (value < -zc->Config.Hysteresis))
{
zc_ch->LastValue = value;
}
@@ -188,7 +188,7 @@ void ZC_ProcessAllChannels(ZeroCross_Handle_t *zc, float *values, uint32_t times
return;
}
- for (int ch = 0; ch < zc->NumChannels; ch++) {
+ for (int ch = 0; ch < zc->Config.NumChannels; ch++) {
ZC_ProcessChannel(zc, ch, values[ch], timestamp);
}
@@ -238,7 +238,7 @@ float ZC_GetFrequency(ZeroCross_Handle_t *zc, uint8_t channel)
if (assert_upp(zc)){
return 0.0f;
}
- if (channel >= zc->NumChannels) {
+ if (channel >= zc->Config.NumChannels) {
return 0.0f;
}
@@ -273,7 +273,7 @@ void ZC_Reset(ZeroCross_Handle_t *zc, uint8_t channel)
return;
}
- if (channel < zc->NumChannels) {
+ if (channel < zc->Config.NumChannels) {
zc->Channel[channel].LastValue = 0.0f;
zc->Channel[channel].CurrentValue = 0.0f;
zc->Channel[channel].DebounceCounter = 0;
@@ -284,7 +284,7 @@ void ZC_Reset(ZeroCross_Handle_t *zc, uint8_t channel)
}
else {
// Сброс всех каналов
- for (int i = 0; i < zc->NumChannels; i++) {
+ for (int i = 0; i < zc->Config.NumChannels; i++) {
zc->Channel[i].LastValue = 0.0f;
zc->Channel[i].CurrentValue = 0.0f;
zc->Channel[i].DebounceCounter = 0;
diff --git a/UPP/Core/PowerMonitor/zero_cross.h b/UPP/Core/PowerMonitor/zero_cross.h
index ba22f79..cb75130 100644
--- a/UPP/Core/PowerMonitor/zero_cross.h
+++ b/UPP/Core/PowerMonitor/zero_cross.h
@@ -100,15 +100,22 @@ typedef struct {
ZC_EdgeType_t EdgeType; ///< Тип детектируемого перехода
} ZC_Channel_t;
+
+/**
+ * @brief Параметры перехода через ноль
+ */
+typedef struct {
+ uint8_t NumChannels; ///< Количество используемых каналов для этого хендла
+ float Hysteresis; ///< Гистерезис для избежания дребезга
+ uint16_t DebounceSamples; ///< Количество samples для антидребезга
+} ZC_Config_t;
+
/**
* @brief Хендл детектора нуля
*/
typedef struct {
- ZC_Channel_t Channel[ZC_MAX_CHANNELS]; ///< Каналы @ref ZC_Channel_t
- uint8_t NumChannels; ///< Количество используемых каналов для этого хендла
- float Hysteresis; ///< Гистерезис для избежания дребезга
- uint16_t DebounceSamples; ///< Количество samples для антидребезга
-
+ ZC_Channel_t Channel[ZC_MAX_CHANNELS]; ///< Каналы @ref ZC_Channel_t
+ ZC_Config_t Config;
struct {
unsigned Initialized:1; ///< Флаг инициализации
unsigned Monitoring:1; ///< Флаг активности мониторинга
diff --git a/UPP/Core/Src/main.c b/UPP/Core/Src/main.c
index 9096b23..076b2e2 100644
--- a/UPP/Core/Src/main.c
+++ b/UPP/Core/Src/main.c
@@ -34,7 +34,7 @@
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
-__IO uint32_t micros;
+
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
diff --git a/UPP/Core/Src/stm32f4xx_it.c b/UPP/Core/Src/stm32f4xx_it.c
index f151479..cf5eee0 100644
--- a/UPP/Core/Src/stm32f4xx_it.c
+++ b/UPP/Core/Src/stm32f4xx_it.c
@@ -246,6 +246,7 @@ void TIM8_TRG_COM_TIM14_IRQHandler(void)
HAL_TIM_IRQHandler(&htim14);
/* USER CODE BEGIN TIM8_TRG_COM_TIM14_IRQn 1 */
#endif
+ UPP_Tick();
/* USER CODE END TIM8_TRG_COM_TIM14_IRQn 1 */
}
diff --git a/UPP/Core/UPP/angle_control.c b/UPP/Core/UPP/angle_control.c
index 767edaf..781a050 100644
--- a/UPP/Core/UPP/angle_control.c
+++ b/UPP/Core/UPP/angle_control.c
@@ -1,7 +1,7 @@
/**
******************************************************************************
-* @file pwm_thyristors.c
-* @brief Модуль для управления тиристорами
+* @file angle_control.c
+* @brief Модуль для формирования и отсчитывания угла открытия
******************************************************************************
* @details
******************************************************************************/
@@ -10,22 +10,16 @@
/**
- * @brief Инициализация ШИМ тиристоров.
+ * @brief Инициализация таймера для расчета угла открытия.
* @param hangle Указатель на таймер
* @return HAL Status.
*/
-HAL_StatusTypeDef Angle_Init(Angle_Handle_t *hangle, float AngleMin, float AngleMax)
+HAL_StatusTypeDef Angle_Init(Angle_Handle_t *hangle)
{
if(hangle == NULL)
return HAL_ERROR;
- if(AngleMax < 0 || AngleMax > 1)
- return HAL_ERROR;
- if(AngleMin < 0 || AngleMin > 1)
- return HAL_ERROR;
hangle->htim = &angletim;
- hangle->AngleMax = AngleMax;
- hangle->AngleMin = AngleMin;
HAL_TIM_OC_Start_IT(hangle->htim, ANGLE_CHANNEL_1);
@@ -36,9 +30,65 @@ HAL_StatusTypeDef Angle_Init(Angle_Handle_t *hangle, float AngleMin, float Angle
Angle_Reset(hangle, UPP_PHASE_B);
Angle_Reset(hangle, UPP_PHASE_C);
+ hangle->f.Initialized = 1;
return HAL_OK;
}
+/**
+ * @brief Инициализация углов открытия.
+ * @param hangle Указатель на таймер
+ * @param AngleLimit Лимит AngleMax, рассчитывается от параметров ШИМ
+ * @param AngleMin Минимально возможный угол открытия
+ * @param AngleMax Максимально возможный угол открытия
+ * @return HAL Status.
+ */
+HAL_StatusTypeDef Angle_SetRange(Angle_Handle_t *hangle, float AngleMin, float AngleMax)
+{
+ if(assert_upp(hangle))
+ return HAL_ERROR;
+ if(hangle->f.Running)
+ return HAL_BUSY;
+ if(AngleMax < 0 || AngleMax > 1)
+ return HAL_ERROR;
+ if(AngleMin < 0 || AngleMin > 1)
+ return HAL_ERROR;
+
+ if(AngleMax > hangle->Config.AngleLimit)
+ AngleMax = hangle->Config.AngleLimit;
+ if(AngleMin > hangle->Config.AngleLimit)
+ AngleMin = hangle->Config.AngleLimit;
+
+ if(AngleMin >= AngleMax)
+ return HAL_ERROR;
+
+ hangle->Config.AngleMax = AngleMax;
+ hangle->Config.AngleMin = AngleMin;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Инициализация предельного угла открытия.
+ * @param hangle Указатель на таймер
+ * @param AngleLimit Лимит AngleMax, рассчитывается от параметров ШИМ
+ * @param AngleMin Минимально возможный угол открытия
+ * @param AngleMax Максимально возможный угол открытия
+ * @return HAL Status.
+ */
+HAL_StatusTypeDef Angle_SetLimit(Angle_Handle_t *hangle, float AngleLimit)
+{
+ if(assert_upp(hangle))
+ return HAL_ERROR;
+ if(hangle->f.Running)
+ return HAL_BUSY;
+
+ if(AngleLimit < 0 || AngleLimit > 1)
+ return HAL_ERROR;
+
+ hangle->Config.AngleLimit = AngleLimit;
+
+ return HAL_OK;
+}
/**
* @brief Хендл таймера для рассчета угла открытия.
* @param hangle Указатель на таймер
@@ -46,7 +96,7 @@ HAL_StatusTypeDef Angle_Init(Angle_Handle_t *hangle, float AngleMin, float Angle
*/
UPP_Phase_t Angle_Handle(Angle_Handle_t *hangle)
{
- if(hangle == NULL)
+ if(assert_upp(hangle))
return UPP_PHASE_UNKNOWN;
@@ -79,9 +129,9 @@ UPP_Phase_t Angle_Handle(Angle_Handle_t *hangle)
* @param Phase Для какой фазы надо установить угол открытия
* @return HAL Status.
*/
-HAL_StatusTypeDef Angle_Start(Angle_Handle_t *hangle, UPP_Phase_t Phase, float Angle, float Freq)
+HAL_StatusTypeDef Angle_Start(Angle_Handle_t *hangle, UPP_Phase_t Phase, float Angle, float PeriodMs)
{
- if(hangle == NULL)
+ if(assert_upp(hangle))
return HAL_ERROR;
// Если канал дурацкий - возвращаем ошибку
@@ -89,16 +139,16 @@ HAL_StatusTypeDef Angle_Start(Angle_Handle_t *hangle, UPP_Phase_t Phase, float A
{
return HAL_ERROR;
}
- if(Angle > hangle->AngleMax)
+ if(Angle > hangle->Config.AngleMax)
{
- Angle = hangle->AngleMax;
+ Angle = hangle->Config.AngleMax;
}
- if(Angle < hangle->AngleMin)
+ if(Angle < hangle->Config.AngleMin)
{
- Angle = hangle->AngleMin;
+ Angle = hangle->Config.AngleMin;
}
- uint32_t timer_ticks = TIM_FreqToTick(Freq/Angle, ANGLE_TIM2_FREQ_MHZ);
+ uint32_t timer_ticks = TIM_MillisToTick(PeriodMs*Angle, ANGLE_TIM2_FREQ_MHZ);
uint32_t ccr_ticks = __HAL_TIM_GET_COUNTER(hangle->htim) + timer_ticks;
switch(Phase)
@@ -106,16 +156,19 @@ HAL_StatusTypeDef Angle_Start(Angle_Handle_t *hangle, UPP_Phase_t Phase, float A
case UPP_PHASE_A:
__HAL_TIM_SET_COMPARE(hangle->htim, ANGLE_CHANNEL_1, ccr_ticks);
__HAL_TIM_ENABLE_IT(hangle->htim, TIM_IT_CC1);
+ hangle->f.Running++;
break;
case UPP_PHASE_B:
__HAL_TIM_SET_COMPARE(hangle->htim, ANGLE_CHANNEL_2, ccr_ticks);
__HAL_TIM_ENABLE_IT(hangle->htim, TIM_IT_CC2);
+ hangle->f.Running++;
break;
case UPP_PHASE_C:
__HAL_TIM_SET_COMPARE(hangle->htim, ANGLE_CHANNEL_3, ccr_ticks);
__HAL_TIM_ENABLE_IT(hangle->htim, TIM_IT_CC3);
+ hangle->f.Running++;
break;
case UPP_PHASE_UNKNOWN:
@@ -136,7 +189,7 @@ HAL_StatusTypeDef Angle_Start(Angle_Handle_t *hangle, UPP_Phase_t Phase, float A
*/
HAL_StatusTypeDef Angle_Reset(Angle_Handle_t *hangle, UPP_Phase_t Phase)
{
- if(hangle == NULL)
+ if(assert_upp(hangle))
return HAL_ERROR;
// Если канал дурацкий - возвращаем ошибку
@@ -149,14 +202,20 @@ HAL_StatusTypeDef Angle_Reset(Angle_Handle_t *hangle, UPP_Phase_t Phase)
{
case UPP_PHASE_A:
__HAL_TIM_DISABLE_IT(hangle->htim, TIM_IT_CC1);
+ if(hangle->f.Running)
+ hangle->f.Running--;
break;
case UPP_PHASE_B:
__HAL_TIM_DISABLE_IT(hangle->htim, TIM_IT_CC2);
+ if(hangle->f.Running)
+ hangle->f.Running--;
break;
case UPP_PHASE_C:
__HAL_TIM_DISABLE_IT(hangle->htim, TIM_IT_CC3);
+ if(hangle->f.Running)
+ hangle->f.Running--;
break;
case UPP_PHASE_UNKNOWN:
diff --git a/UPP/Core/UPP/angle_control.h b/UPP/Core/UPP/angle_control.h
index 4da20e1..2b62a01 100644
--- a/UPP/Core/UPP/angle_control.h
+++ b/UPP/Core/UPP/angle_control.h
@@ -1,27 +1,39 @@
/**
******************************************************************************
-* @file pwm_thyristors.h
-* @brief Модуль для управления тиристорами (объединённый 6-канальный)
+* @file angle_control.h
+* @brief Модуль для формирования и отсчитывания угла открытия
******************************************************************************
*/
#ifndef _ANGLE_CONTROL_H_
#define _ANGLE_CONTROL_H_
#include "main.h"
-#define ANGLE_TIM2_FREQ_MHZ 90
+typedef struct
+{
+ float AngleLimit; ///< Лимит AngleMax, рассчитывается от параметров ШИМ
+ float AngleMin; ///< Минимально возможный угол открытия
+ float AngleMax; ///< Максимально возможный угол открытия
+}Angle_Config_t;
typedef struct
{
TIM_HandleTypeDef *htim;
+ Angle_Config_t Config;
- float AngleMin;
- float AngleMax;
+ struct {
+ unsigned Initialized : 1;
+ unsigned Running : 3; ///< Сколько каналов запущено сейчас
+ } f;
}Angle_Handle_t;
/* Инициализация Таймера для рассчета угла открытия. */
-HAL_StatusTypeDef Angle_Init(Angle_Handle_t *hangle, float AngleMin, float AngleMax);
+HAL_StatusTypeDef Angle_Init(Angle_Handle_t *hangle);
+/* Инициализация углов открытия. */
+HAL_StatusTypeDef Angle_SetRange(Angle_Handle_t *hangle, float AngleMin, float AngleMax);
+/* Инициализация предельного угла открытия. */
+HAL_StatusTypeDef Angle_SetLimit(Angle_Handle_t *hangle, float AngleLimit);
/* Установка угла открытия в таймер. */
-HAL_StatusTypeDef Angle_Start(Angle_Handle_t *hangle, UPP_Phase_t Phase, float Angle, float Freq);
+HAL_StatusTypeDef Angle_Start(Angle_Handle_t *hangle, UPP_Phase_t Phase, float Angle, float PeriodMs);
/* Сброс угла открытия у таймера. */
HAL_StatusTypeDef Angle_Reset(Angle_Handle_t *hangle, UPP_Phase_t Phase);
diff --git a/UPP/Core/UPP/pwm_thyristors.c b/UPP/Core/UPP/pwm_thyristors.c
index 20455c8..2d6daba 100644
--- a/UPP/Core/UPP/pwm_thyristors.c
+++ b/UPP/Core/UPP/pwm_thyristors.c
@@ -56,7 +56,7 @@ HAL_StatusTypeDef PWM_Init(PWM_Handle_t *hpwm)
PWM_SetHalfWave(hpwm, UPP_PHASE_B, UPP_WAVE_UNKNOWED);
PWM_SetHalfWave(hpwm, UPP_PHASE_C, UPP_WAVE_UNKNOWED);
- PWM_SetFrequency(hpwm, hpwm->Config.Frequency);
+ PWM_SetConfig(hpwm, MB_INTERNAL.param.pwm.PhaseMask, MB_INTERNAL.param.pwm.Frequency, MB_INTERNAL.param.pwm.PulseNumber);
HAL_TIM_PWM_Start(&hpwm1, PWM_CHANNEL_1);
HAL_TIM_PWM_Start(&hpwm1, PWM_CHANNEL_2);
@@ -115,7 +115,7 @@ HAL_StatusTypeDef PWM_Start(PWM_Handle_t *hpwm, UPP_Phase_t Phase)
* @param Phase На какой фазе надо остановить ШИМ
* @return HAL Status.
*/
-HAL_StatusTypeDef PWM_Stop(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint8_t force_stop)
+HAL_StatusTypeDef PWM_Stop(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint8_t force_stop_all)
{
if(assert_upp(hpwm))
return HAL_ERROR;
@@ -129,10 +129,18 @@ HAL_StatusTypeDef PWM_Stop(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint8_t force_
hpwm->Phase[Phase]->State = PWM_THYR_DISABLED;
- if(force_stop)
+ // Если не force_stop_all - сбрасываем только текущий канал
+ if (!force_stop_all)
{
__PWM_SetOutputState(hpwm->Phase[Phase], PWM_DISABLE);
}
+ // Если force_stop_all - сбрасываем ВСЕ КАНАЛЫ
+ else {
+ for(int ch = 0; ch < 6; ch++)
+ {
+ __PWM_SetOutputState(&hpwm->AllPhases[ch], PWM_DISABLE);
+ }
+ }
return HAL_OK;
}
@@ -169,6 +177,7 @@ HAL_StatusTypeDef PWM_Handle(PWM_Handle_t *hpwm)
__PWM_SetOutputState(hPhase, PWM_ENABLE);
hPhase->PulseCnt = hpwm->Config.PulseNumber;
hPhase->State = PWM_THYR_TIM_ACTIVE;
+ hpwm->f.Running++;
break;
case PWM_THYR_TIM_ACTIVE:
@@ -182,6 +191,8 @@ HAL_StatusTypeDef PWM_Handle(PWM_Handle_t *hpwm)
case PWM_THYR_TIM_DONE:
hPhase->State = PWM_THYR_TIM_WAIT;
+ if(hpwm->f.Running)
+ hpwm->f.Running--;
break;
default:
@@ -192,6 +203,37 @@ HAL_StatusTypeDef PWM_Handle(PWM_Handle_t *hpwm)
return HAL_OK;
}
+/**
+ * @brief Установка частоты ШИМ.
+ * @param hpwm Указатель на хендл ШИМ тиристоров
+ * @param Frequency Частота в ГЦ
+ * @return HAL Status.
+ */
+HAL_StatusTypeDef PWM_SetConfig(PWM_Handle_t *hpwm, uint8_t PhaseMask, uint16_t Frequency, uint8_t PulseNumber)
+{
+ if(assert_upp(hpwm))
+ return HAL_ERROR;
+ if(hpwm->f.Running)
+ return HAL_BUSY;
+
+ HAL_TIM_Base_Stop(&hpwm1);
+
+ hpwm->Config.PhaseMask.all = PhaseMask;
+ hpwm->Config.PulseNumber = PulseNumber;
+ hpwm->Config.Frequency = Frequency;
+ __HAL_TIM_SET_AUTORELOAD(&hpwm1, TIM_FreqToTick(Frequency, PWM_TIM1_FREQ_MHZ));
+ __HAL_TIM_SET_AUTORELOAD(&hpwm2, TIM_FreqToTick(Frequency, PWM_TIM3_FREQ_MHZ));
+ __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_1, __HAL_TIM_GET_AUTORELOAD(&hpwm1)/2);
+ __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_2, __HAL_TIM_GET_AUTORELOAD(&hpwm1)/2);
+ __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_3, __HAL_TIM_GET_AUTORELOAD(&hpwm1)/2);
+ __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_4, __HAL_TIM_GET_AUTORELOAD(&hpwm1)/2);
+ __HAL_TIM_SET_COMPARE(&hpwm2, PWM_CHANNEL_5, __HAL_TIM_GET_AUTORELOAD(&hpwm2)/2);
+ __HAL_TIM_SET_COMPARE(&hpwm2, PWM_CHANNEL_6, __HAL_TIM_GET_AUTORELOAD(&hpwm2)/2);
+
+ return HAL_TIM_Base_Start_IT(&hpwm1);
+}
+
+
/**
* @brief Установка полуволны для слежения.
* @param hpwm Указатель на хендл ШИМ тиристоров
@@ -206,7 +248,7 @@ HAL_StatusTypeDef PWM_SetHalfWave(PWM_Handle_t *hpwm, UPP_Phase_t Phase, UPP_Hal
// Сбрасываем текущий канал
- PWM_Stop(hpwm, Phase, 1);
+ PWM_Stop(hpwm, Phase, 0);
// Если канал дурацкий - выставляем заглушку
if(Phase >= 3)
diff --git a/UPP/Core/UPP/pwm_thyristors.h b/UPP/Core/UPP/pwm_thyristors.h
index fa56447..5908225 100644
--- a/UPP/Core/UPP/pwm_thyristors.h
+++ b/UPP/Core/UPP/pwm_thyristors.h
@@ -1,7 +1,7 @@
/**
******************************************************************************
* @file pwm_thyristors.h
-* @brief Модуль для управления тиристорами (объединённый 6-канальный)
+* @brief Модуль для управления тиристорами
******************************************************************************
*/
#ifndef _PWM_THYRISTORS_H
@@ -12,23 +12,11 @@
-#define PWM_TIM1_FREQ_MHZ 180
-#define PWM_TIM3_FREQ_MHZ 90
-#define PWM_ENABLE TIM_OCMODE_PWM1
-#define PWM_DISABLE TIM_OCMODE_FORCED_ACTIVE
+#define PWM_ENABLE TIM_OCMODE_PWM2
+#define PWM_DISABLE TIM_OCMODE_FORCED_INACTIVE
-#define PWM_SetFrequency(_hpwm_, _freq_) \
-do { _hpwm_->Config.Frequency = _freq_; \
- __HAL_TIM_SET_AUTORELOAD(&hpwm1, TIM_FreqToTick(_freq_, PWM_TIM1_FREQ_MHZ)); \
- __HAL_TIM_SET_AUTORELOAD(&hpwm2, TIM_FreqToTick(_freq_, PWM_TIM3_FREQ_MHZ)); \
- __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_1, __HAL_TIM_GET_AUTORELOAD(&hpwm1)/2); \
- __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_2, __HAL_TIM_GET_AUTORELOAD(&hpwm1)/2); \
- __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_3, __HAL_TIM_GET_AUTORELOAD(&hpwm1)/2); \
- __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_4, __HAL_TIM_GET_AUTORELOAD(&hpwm1)/2); \
- __HAL_TIM_SET_COMPARE(&hpwm2, PWM_CHANNEL_5, __HAL_TIM_GET_AUTORELOAD(&hpwm2)/2); \
- __HAL_TIM_SET_COMPARE(&hpwm2, PWM_CHANNEL_6, __HAL_TIM_GET_AUTORELOAD(&hpwm2)/2); }while(0);
// Индексы для структур каналов @ref PWM_Handle_t
@@ -67,7 +55,7 @@ typedef struct {
} PWM_Channel_t;
/**
- * @brief Канал PWM (один тиристор)
+ * @brief Параметры ШИМ
*/
typedef struct {
union
@@ -81,7 +69,7 @@ typedef struct {
};
}PhaseMask; ///< Какими каналами управлять
uint8_t PulseNumber; ///< Сколько импульсов отправить в пакете для открытия тиристоров
- uint32_t Frequency; ///< Частота импульсов
+ uint16_t Frequency; ///< Частота импульсов
} PWM_ThyrConfig_t;
/**
@@ -93,7 +81,7 @@ typedef struct {
struct {
unsigned Initialized : 1;
- unsigned Running : 1; ///< true если оба таймера запущены
+ unsigned Running : 3; ///< Сколько каналов запущено сейчас
} f;
} PWM_Handle_t;
@@ -103,7 +91,9 @@ HAL_StatusTypeDef PWM_Init(PWM_Handle_t *hpwm);
/* Запуск ШИМ. */
HAL_StatusTypeDef PWM_Start(PWM_Handle_t *hpwm, UPP_Phase_t Phase);
/* Остановить ШИМ. */
-HAL_StatusTypeDef PWM_Stop(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint8_t force_stop);
+HAL_StatusTypeDef PWM_Stop(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint8_t force_stop_all);
+/* Установка частоты ШИМ. */
+HAL_StatusTypeDef PWM_SetConfig(PWM_Handle_t *hpwm, uint8_t PhaseMask, uint16_t Frequency, uint8_t PulseNumber);
/* Установка полуволны для слежения. */
HAL_StatusTypeDef PWM_SetHalfWave(PWM_Handle_t *hpwm, UPP_Phase_t Phase, UPP_HalfWave_t halfwave);
/* Установка полуволны для слежения. */
diff --git a/UPP/Core/UPP/upp_control.c b/UPP/Core/UPP/upp_control.c
new file mode 100644
index 0000000..dec4727
--- /dev/null
+++ b/UPP/Core/UPP/upp_control.c
@@ -0,0 +1,267 @@
+/**
+******************************************************************************
+* @file upp_control.c
+* @brief Модуль определябщий поведение УПП
+******************************************************************************
+* @details
+******************************************************************************/
+#include "upp_main.h" // всё остальное по работе с УПП
+
+
+static int __CheckSimpleParamF(float *paramDist, uint16_t paramSrc, float Coef);
+static int __CheckSimpleParamU32(uint32_t *paramDist, uint16_t paramSrc, float Coef);
+static int __CheckSimpleParamU16(uint16_t *paramDist, uint16_t paramSrc);
+static int __CheckSimpleParamU8(uint8_t *paramDist, uint16_t paramSrc, float Coef);
+static int __AngleSetLimit(void);
+
+/**
+ * @brief Контроль внутренних параметров УПП.
+ * @return HAL Status.
+ */
+void UPP_Control_InternalParams(void)
+{
+ if(upp.call->go) // при запущеном УПП ничего не меняем
+ return;
+
+ // флаги обновились ли конфиги
+ static int adc_channel_update[ADC_NUMB_OF_REGULAR_CHANNELS] = {0};
+ static int zc_update = 0;
+ static int pwm_update = 0;
+
+ // временная переменная для параметров каналов АЦП
+ float adc_channel_max[ADC_NUMB_OF_REGULAR_CHANNELS] = {0};
+ uint16_t adc_channel_zero[ADC_NUMB_OF_REGULAR_CHANNELS] = {0};
+ // временная переменная для параметров перехода через ноль
+ float zc_hysteresis = upp.pm.zc.Config.Hysteresis;
+ uint16_t zc_debounce = upp.pm.zc.Config.DebounceSamples;
+ // временная переменная для параметров ШИМ
+ uint8_t pwm_phase_mask = upp.hpwm.Config.PhaseMask.all;
+ uint16_t pwm_freq = upp.hpwm.Config.Frequency;
+ uint8_t pwm_pulse_num = upp.hpwm.Config.PulseNumber;
+
+
+ for(int i = 0; i < ADC_NUMB_OF_REGULAR_CHANNELS; i++)
+ {
+ adc_channel_max[i] = upp.pm.adc.Coefs[i].vMax;
+ adc_channel_zero[i] = upp.pm.adc.Coefs[i].lZero;
+
+ // Максимальное измеряемое напряжение
+ if(__CheckSimpleParamF(&adc_channel_max[i], MB_INTERNAL.param.adc.ADC_Max[i], 10))
+ {
+ adc_channel_update[i] = 1;
+ }
+ // Значение АЦП при нулевом входе
+ if(__CheckSimpleParamU16(&adc_channel_zero[i], MB_INTERNAL.param.adc.ADC_Zero[i]))
+ {
+ adc_channel_update[i] = 1;
+ }
+ }
+
+ // Параметры алгоритма перехода через ноль
+ if(__CheckSimpleParamF(&zc_hysteresis, MB_INTERNAL.param.zc.Hysteresis, 100))
+ {
+ zc_update = 1;
+ }
+ if(__CheckSimpleParamU16(&zc_debounce, MB_INTERNAL.param.zc.Hysteresis))
+ {
+ zc_update = 1;
+ }
+
+ // Параметры ШИМ токов
+ if(__CheckSimpleParamU8(&pwm_phase_mask, MB_INTERNAL.param.pwm.PhaseMask, 1))
+ {
+ pwm_update = 1;
+ }
+ if(__CheckSimpleParamU16(&pwm_freq, MB_INTERNAL.param.pwm.Frequency))
+ {
+ pwm_update = 1;
+ }
+ if(__CheckSimpleParamU8(&pwm_pulse_num, MB_INTERNAL.param.pwm.PulseNumber, 1))
+ {
+ pwm_update = 1;
+ }
+
+
+ // Обновление АЦП конфигов
+ for(int i = 0; i < ADC_NUMB_OF_REGULAR_CHANNELS; i++)
+ {
+ if(adc_channel_update[i])
+ {
+ if(ADC_ConfigChannel(&upp.pm.adc, i, adc_channel_zero[i], adc_channel_max[i], 4095) == HAL_OK)
+ adc_channel_update[i] = 0;
+ else
+ errors.prvt.cnt.adc_reinit_err++;
+ }
+ }
+ // Обновление Zero-Cross конфигов
+ if(zc_update)
+ {
+ if(ZC_Init(&upp.pm.zc, upp.pm.zc.Config.NumChannels, zc_hysteresis, zc_debounce) == HAL_OK)
+ zc_update = 0;
+ else
+ errors.prvt.cnt.zc_reinit_err++;
+ }
+ // Обновление ШИМ конфигов
+ if(pwm_update)
+ {
+ if(PWM_SetConfig(&upp.hpwm, pwm_phase_mask, pwm_freq, pwm_pulse_num) == HAL_OK)
+ {
+ pwm_update = 0;
+ __AngleSetLimit();
+ }
+ else
+ errors.prvt.cnt.pwm_reinit_err++;
+ }
+ if (upp.hangle.Config.AngleLimit == 0)
+ {
+ __AngleSetLimit();
+ }
+}
+
+
+/**
+ * @brief Установка параметров на дефолтные значения @ref UPP_DEFAULT_PARAMS.
+ * @param pui_default Сбросить параметры ПУИ
+ * @param internal_default Сбросить внутренние параметры
+ * @return HAL Status.
+ */
+void UPP_SetDefault(int pui_default, int internal_default)
+{
+ if(pui_default)
+ {
+ MB_DATA.HoldRegs.pui_params.Iref = PUI_Iref_PERCENT_DEFAULT;
+ MB_DATA.HoldRegs.pui_params.Tnt = PUI_Tnt_MS_DEFAULT;
+ MB_DATA.HoldRegs.pui_params.Umin = PUI_Umin_PERCENT_DEFAULT;
+ MB_DATA.HoldRegs.pui_params.Umax = PUI_Umax_PERCENT_DEFAULT;
+ MB_DATA.HoldRegs.pui_params.Imax = PUI_Imax_PERCENT_DEFAULT;
+ MB_DATA.HoldRegs.pui_params.Imin = PUI_Imin_PERCENT_DEFAULT;
+ MB_DATA.HoldRegs.pui_params.TiMax = PUI_TiMax_US_DEFAULT;
+ MB_DATA.HoldRegs.pui_params.Tdelay = PUI_Tdelay_SECONDS_DEFAULT;
+ MB_DATA.HoldRegs.pui_params.Interlace = PUI_Interlace_EN_DEFAULT;
+ }
+
+ if(internal_default)
+ {
+ MB_INTERNAL.param.adc.ADC_Max[ADC_CHANNEL_UBA] = ADC_U_MAX_V_DEFAULT*10;
+ MB_INTERNAL.param.adc.ADC_Max[ADC_CHANNEL_UAC] = ADC_U_MAX_V_DEFAULT*10;
+ MB_INTERNAL.param.adc.ADC_Max[ADC_CHANNEL_IC] = ADC_I_MAX_A_DEFAULT*10;
+ MB_INTERNAL.param.adc.ADC_Max[ADC_CHANNEL_IA] = ADC_I_MAX_A_DEFAULT*10;
+ MB_INTERNAL.param.adc.ADC_Zero[ADC_CHANNEL_UBA] = ADC_U_ZERO_DEFAULT;
+ MB_INTERNAL.param.adc.ADC_Zero[ADC_CHANNEL_UAC] = ADC_U_ZERO_DEFAULT;
+ MB_INTERNAL.param.adc.ADC_Zero[ADC_CHANNEL_IC] = ADC_I_ZERO_DEFAULT;
+ MB_INTERNAL.param.adc.ADC_Zero[ADC_CHANNEL_IA] = ADC_I_ZERO_DEFAULT;
+
+ MB_INTERNAL.param.pwm.PhaseMask = 0x7; // (все три фазы)
+ MB_INTERNAL.param.pwm.Frequency = (float)PWM_THYR_FREQUENCY_HZ_DEFAULT;
+ MB_INTERNAL.param.pwm.PulseNumber = PWM_THYR_PULSE_NUMBER_DEFAULT;
+
+ MB_INTERNAL.param.zc.Hysteresis = ZERO_CROSS_HYSTERESIS_V_DEFAULT*100;
+ MB_INTERNAL.param.zc.DebouneCouner = ZERO_CROSS_DEBOUNCE_10US_DEFAULT;
+ //__AngleSetLimit();
+ }
+}
+
+
+
+static int __AngleSetLimit(void)
+{
+ // Перерасчет максимально допустимого угла
+ float pulses_percent_of_period = ((MB_INTERNAL.param.pwm.PulseNumber / MB_INTERNAL.param.pwm.Frequency) * 1000) / ANGLE_PERIOD_MS;
+ float angle_limit = 1 - pulses_percent_of_period;
+ Angle_SetLimit(&upp.hangle, angle_limit);
+}
+
+
+
+/**
+ * @brief Сверить и обновить float параметр из uint16_t.
+ * @param paramDist Указатель на float параметр
+ * @param paramSrc Значение для сравнения с float параметром
+ * @param Coef Коэффициент для приведения float к uint16_t: uint16_t = float*coef, float = uint16_t/coef
+ * @return 0 - параметры совпадают, 1 - параметр был обновлен на paramSrc.
+ */
+static int __CheckSimpleParamF(float *paramDist, uint16_t paramSrc, float Coef)
+{
+ if(paramDist == NULL)
+ return 0;
+
+ uint16_t expected_mb_param = *paramDist*Coef;
+ if(expected_mb_param != paramSrc)
+ {
+ *paramDist = (float)paramSrc/Coef;
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+/**
+ * @brief Сверить и обновить uint32_t параметр из uint16_t.
+ * @param paramDist Указатель на uint32_t параметр
+ * @param paramSrc Значение для сравнения с uint32_t параметром
+ * @param Coef Коэффициент для приведения uint32_t к uint16_t: uint16_t = uint32_t*coef, uint32_t = uint16_t/coef
+ * @return 0 - параметры совпадают, 1 - параметр был обновлен на paramSrc.
+ */
+static int __CheckSimpleParamU32(uint32_t *paramDist, uint16_t paramSrc, float Coef)
+{
+ if(paramDist == NULL)
+ return 0;
+
+ uint16_t expected_mb_param = *paramDist*Coef;
+ if(expected_mb_param != paramSrc)
+ {
+ *paramDist = (uint32_t)paramSrc/Coef;
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+/**
+ * @brief Сверить и обновить uint16_t параметр из uint16_t.
+ * @param paramDist Указатель на uint16_t параметр
+ * @param paramSrc Значение для сравнения с uint16_t параметром
+ * @return 0 - параметры совпадают, 1 - параметр был обновлен на paramSrc.
+ */
+static int __CheckSimpleParamU16(uint16_t *paramDist, uint16_t paramSrc)
+{
+ if(paramDist == NULL)
+ return 0;
+
+ uint16_t expected_mb_param = *paramDist;
+ if(expected_mb_param != paramSrc)
+ {
+ *paramDist = (uint16_t)paramSrc;
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/**
+ * @brief Сверить и обновить uint8_t параметр из uint16_t.
+ * @param paramDist Указатель на uint8_t параметр
+ * @param paramSrc Значение для сравнения с uint32_t параметром
+ * @param Coef Коэффициент для приведения uint32_t к uint16_t: uint16_t = uint8_t*coef, uint8_t = uint16_t/coef
+ * @return 0 - параметры совпадают, 1 - параметр был обновлен на paramSrc.
+ */
+static int __CheckSimpleParamU8(uint8_t *paramDist, uint16_t paramSrc, float Coef)
+{
+ if(paramDist == NULL)
+ return 0;
+
+ uint16_t expected_mb_param = *paramDist*Coef;
+ if(expected_mb_param != paramSrc)
+ {
+ *paramDist = (uint8_t)paramSrc/Coef;
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
\ No newline at end of file
diff --git a/UPP/Core/UPP/upp_control.h b/UPP/Core/UPP/upp_control.h
new file mode 100644
index 0000000..6404411
--- /dev/null
+++ b/UPP/Core/UPP/upp_control.h
@@ -0,0 +1,67 @@
+/**
+******************************************************************************
+* @file upp_control.h
+* @brief Модуль определябщий поведение УПП
+******************************************************************************
+* @details
+******************************************************************************/
+
+#ifndef _UPP_CONTROL_H
+#define _UPP_CONTROL_H
+#include "upp_defs.h"
+
+typedef struct
+{
+ unsigned set_default_pui:1;
+ unsigned set_default_internal:1;
+ unsigned go:1;
+ unsigned stop:1;
+
+
+ unsigned reserved:11;
+ unsigned reset_mcu:1;
+}UPP_FuncCalls_t;
+
+
+typedef struct
+{
+ /* Параметры АЦП */
+ struct
+ {
+ uint16_t ADC_Max[4];
+ uint16_t ADC_Zero[4];
+ }adc;
+
+ /* Параметры ШИМ */
+ struct
+ {
+ uint16_t PhaseMask;
+ uint16_t Frequency;
+ uint16_t PulseNumber;
+ }pwm;
+
+ /* Параметры Угла */
+ struct
+ {
+ uint16_t Hysteresis;
+ uint16_t DebouneCouner;
+ }zc;
+
+ /* Параметры Угла */
+ struct
+ {
+ uint16_t Angle_Max;
+ uint16_t Angle_Min;
+ }angle;
+
+
+
+}UPP_PrvtParams_t;
+
+
+/* Контроль внутренних параметров УПП. */
+void UPP_Control_InternalParams(void);
+/* Установка параметров на дефолтные значения */
+void UPP_SetDefault(int pui_default, int internal_default);
+
+#endif //_UPP_CONTROL_H
\ No newline at end of file
diff --git a/UPP/Core/UPP/upp_errors.c b/UPP/Core/UPP/upp_errors.c
new file mode 100644
index 0000000..02ebc29
--- /dev/null
+++ b/UPP/Core/UPP/upp_errors.c
@@ -0,0 +1,44 @@
+/**
+******************************************************************************
+* @file upp_errors.c
+* @brief Ошибки УПП и их обработка
+******************************************************************************
+* @details
+******************************************************************************/
+#include "upp_errors.h" // всё остальное по работе с УПП
+UPP_Errors_t errors;
+
+static UPP_ErrorType_t UPP_SelectCommonError(void)
+{
+ // Пока нет ошибки
+ UPP_ErrorType_t best = Err_None;
+ // Приоритет отсутствия ошибок
+ uint8_t best_prio = UPP_ErrorPriority[Err_None];
+
+ // Перебираем все возможные ошибки по enum
+ for (int e = Err_None + 1; e <= Err_UnderFrequency; e++)
+ {
+ // Проверяем: установлен ли соответствующий бит в pui.all
+ // e-1, потому что ошибка №1 = бит 0, ошибка №2 = бит 1 и т.д.
+ if (errors.pui.all & (1u << (e - 1)))
+ {
+ // Получаем приоритет этой ошибки
+ uint8_t pr = UPP_ErrorPriority[e];
+
+ // Если её приоритет лучше (меньше число) — запоминаем
+ if (pr < best_prio)
+ {
+ best_prio = pr;
+ best = (UPP_ErrorType_t)e;
+ }
+ }
+ }
+
+ // Возвращаем самую важную (наивысшего приоритета) ошибку
+ return best;
+}
+
+void UPP_ErrorsHandle(void)
+{
+ errors.common = UPP_SelectCommonError();
+}
\ No newline at end of file
diff --git a/UPP/Core/UPP/upp_errors.h b/UPP/Core/UPP/upp_errors.h
new file mode 100644
index 0000000..9bed663
--- /dev/null
+++ b/UPP/Core/UPP/upp_errors.h
@@ -0,0 +1,124 @@
+/**
+******************************************************************************
+* @file upp_errors.h
+* @brief Ошибки УПП и их обработка
+******************************************************************************
+* @details
+******************************************************************************/
+
+#ifndef _UPP_ERRORS_H
+#define _UPP_ERRORS_H
+#include "upp_defs.h"
+
+
+/**
+ * @brief Приоритет ПУИ ошибок
+ */
+static const uint8_t UPP_ErrorPriority[] =
+{
+ [Err_None] = 255,
+
+ /* Фатальные ошибки */
+ [Err_LossPhaseAll] = 1,
+ [Err_OverCurrent] = 2,
+ [Err_OverVoltage] = 3,
+ [Err_OverTemperature] = 4,
+ [Err_Power_24V] = 5,
+ [Err_Power_Digit_5V] = 6,
+ [Err_Power_DIO_24V] = 7,
+ [Err_Power_Analog_5V] = 8,
+
+ /* Критичные */
+ [Err_LossPhaseA] = 10,
+ [Err_LossPhaseB] = 11,
+ [Err_LossPhaseC] = 12,
+ [Err_LongStart] = 13,
+ [Err_Interlace] = 14,
+
+ /* Пограничные параметры */
+ [Err_UnderVoltage] = 20,
+ [Err_OverFrequency] = 21,
+ [Err_UnderFrequency] = 22,
+
+ /* Внутренние */
+ [Err_Internal_1] = 40,
+ [Err_Internal_2] = 41,
+ [Err_Internal_3] = 42,
+ [Err_Internal_4] = 43,
+ [Err_Internal_5] = 44,
+ [Err_Internal_6] = 45,
+};
+
+
+
+/**
+ * @brief Структура с всеми ошибками УПП
+ */
+typedef struct
+{
+ UPP_ErrorType_t common; ///< Общая ошибка @ref UPP_ErrorType_t;
+
+ union
+ {
+ uint32_t all;
+ struct
+ {
+ /* Програмные ошибки */
+ unsigned Internal_1:1; ///< Внутренняя неисправность УПП 1
+ unsigned Internal_2:1; ///< Внутренняя неисправность УПП 2
+ unsigned Internal_3:1; ///< Внутренняя неисправность УПП 3
+ unsigned Internal_4:1; ///< Внутренняя неисправность УПП 4
+ unsigned Internal_5:1; ///< Внутренняя неисправность УПП 5
+ unsigned Internal_6:1; ///< Внутренняя неисправность УПП 6
+
+ /* Ошибки по питанию */
+ unsigned Power_Digit_5V:1; ///< Неисправность цифрового источника питания (5 В)
+ unsigned Power_24V:1; ///< Неисправность источника питания 24 В
+ unsigned Power_Analog_5V:1; ///< Неисправность аналогового источника питания микроконтроллера (± 5 В)
+ unsigned Power_SCI_5V:1; ///< Неисправность источника питания последовательных интерфейсов микроконтроллера (5 В)
+ unsigned Power_DIO_24V:1; ///< Неисправность источника питания дискретных входов/выходов (24 В)
+
+ /* Ошибки по допустимым пределам Наряжений/Токов/Температуры */
+ unsigned OverCurrent:1; ///< Ток выше допустимого (см. Imax и TiMax в @ref UPP_PUI_Params_t)
+ unsigned OverVoltage:1; ///< Напряжение сети выше допустимого (см. Umах в @ref UPP_PUI_Params_t)
+ unsigned OverTemperature:1; ///< Температура выше допустимой (плюс 85 °C)
+ unsigned UnderVoltage:1; ///< Напряжение сети ниже допустимого (см. Umin в @ref UPP_PUI_Params_t)
+
+ /* Ошибки по обрывам фаз */
+ unsigned LossPhaseA:1; ///< Обрыв фазы A (см. Imin в @ref UPP_PUI_Params_t)
+ unsigned LossPhaseB:1; ///< Обрыв фазы B (см. Imin в @ref UPP_PUI_Params_t)
+ unsigned LossPhaseC:1; ///< Обрыв фазы C (см. Imin в @ref UPP_PUI_Params_t)
+
+ /* Другие ошибки */
+ unsigned LongStart:1; ///< Затянутый пуск (ток не спадает за установленное время) (см. Tdelay в @ref UPP_PUI_Params_t)
+ unsigned Interlace:1; ///< Неправильный порядок чередования фаз (см. Interlace в @ref UPP_PUI_Params_t)
+ unsigned OverFrequency:1; ///< Частота сети выше допустимой
+ unsigned UnderFrequency:1; ///< Частота сети ниже допустимой
+ }err;
+ }pui;
+
+ struct
+ {
+ union
+ {
+ uint64_t all;
+ struct
+ {
+ unsigned :1;
+ }err;
+ }f;
+
+ struct
+ {
+ uint16_t adc_reinit_err;
+ uint16_t zc_reinit_err;
+ uint16_t pwm_reinit_err;
+ }cnt;
+
+ }prvt; ///< Приватные ошибки, не идущие напрямую в ПУИ
+}UPP_Errors_t;
+extern UPP_Errors_t errors;
+
+void UPP_ErrorsHandle(void);
+
+#endif //_UPP_ERRORS_H
\ No newline at end of file
diff --git a/UPP/Core/UPP/upp_main.c b/UPP/Core/UPP/upp_main.c
index a6a3571..9356f6e 100644
--- a/UPP/Core/UPP/upp_main.c
+++ b/UPP/Core/UPP/upp_main.c
@@ -6,6 +6,7 @@
* @details
******************************************************************************/
#include "upp_main.h" // всё остальное по работе с УПП
+
UPP_t upp;
float alpha_dbg = 0.5;
// ОСНОВНОЙ ЦИКЛ main.c
@@ -16,12 +17,18 @@ float alpha_dbg = 0.5;
*/
int UPP_Init(void)
{
+ // Подключение указателей
+ upp.errors = &errors;
+ upp.PUI.params = &MB_DATA.HoldRegs.pui_params;
+ upp.PUI.values = &MB_DATA.InRegs.pui;
+ upp.call = &MB_INTERNAL.FuncCalls;
+
HAL_TIM_Base_Start(&ustim);
PowerMonitor_Init(&upp.pm);
- upp.hpwm.Config.Frequency = 20000;
- upp.hpwm.Config.PulseNumber = 20;
PWM_Init(&upp.hpwm);
- Angle_Init(&upp.hangle, 0, 0.8);
+ Angle_Init(&upp.hangle);
+
+ upp.workmode = WM_Ready;
return 0;
}
@@ -31,8 +38,9 @@ int UPP_Init(void)
*/
int UPP_PreWhile(void)
{
+ UPP_Control_InternalParams();
+ Angle_SetRange(&upp.hangle, 0.0, 0.8);
PowerMonitor_Start(&upp.pm);
- upp.hpwm.Config.PhaseMask.all = 0x7;
return 0;
}
@@ -41,11 +49,85 @@ int UPP_PreWhile(void)
* @return 0 - если ОК, >1 если ошибка.
*/
int UPP_While(void)
-{
+{
+ // если ошибка вызываем СТОП
+ if(errors.pui.all)
+ {
+ upp.call->stop = 1;
+ }
+ // иначе снимаем СТОП
+ else
+ {
+ upp.call->stop = 0;
+ }
+
+
+ // Сброс на дефолтные по запросу
+ if(upp.call->set_default_pui)
+ {
+ UPP_SetDefault(1, 0);
+ }
+ if(upp.call->set_default_internal)
+ {
+ UPP_SetDefault(0, 1);
+ }
+
+
+
+ // Если СТОП - переходим в ошибку
+ if (upp.call->stop)
+ upp.workmode = WM_Error;
+ // Автомат состояний УПП
+ switch(upp.workmode)
+ {
+ case WM_Ready:
+ // если пришла команда на запуск
+ if (upp.call->go)
+ {
+ upp.workmode = WM_Running;
+ upp.StartTick = local_time();
+ }
+ break;
+
+ case WM_Running:
+ // если пришла команда на остановку
+ if (!upp.call->go)
+ upp.workmode = WM_Ready;
+
+ // если слишком долгий запуск
+ if((local_time() - upp.StartTick) > (upp.PUI.params->Tdelay*1000))
+ {
+ errors.pui.err.LongStart = 1;
+ }
+ break;
+
+ case WM_Error:
+ if(errors.common == Err_None)
+ upp.workmode = WM_Ready;
+
+ PWM_Stop(&upp.hpwm, 0, 1); // Останавливаем ВЕСЬ ШИМ
+ break;
+ }
+
return 0;
}
+
+
+/**
+ * @brief Всякое что будет делатся каждую 1 мс.
+ */
+void UPP_Tick(void)
+{
+ if(upp.workmode == WM_Not_Init)
+ return;
+ UPP_ErrorsHandle();
+ UPP_Control_InternalParams();
+}
+
+
+
// ПРЕРЫВАНИЯ stm32f4xx_it.c
void UPP_ADC_Handle(void)
@@ -57,41 +139,53 @@ void UPP_ADC_Handle(void)
// Если произошел Zero Cross
if(ZC_isOccurred(&upp.pm.zc, phase))
{
- // Меняем полуволну тиристора
- UPP_HalfWave_t curr_halfwave = ZC_GetHalfWave(&upp.pm.zc, phase);
- PWM_SetHalfWave(&upp.hpwm, phase, curr_halfwave);
- Angle_Start(&upp.hangle, phase, alpha_dbg, 100);
+ // Если УПП в работе
+ if(upp.workmode == WM_Running)
+ {
+ // Меняем полуволну тиристора
+ UPP_HalfWave_t curr_halfwave = ZC_GetHalfWave(&upp.pm.zc, phase);
+ PWM_SetHalfWave(&upp.hpwm, phase, curr_halfwave);
+ // Начинаем отсчитывать угол
+ Angle_Start(&upp.hangle, phase, alpha_dbg, 10);
+ }
}
}
+
+ // Проверяем на ошибки
}
void UPP_PWM_Handle(void)
{
PWM_Handle(&upp.hpwm);
}
+void UPP_Angle_Handle(void)
+{
+ UPP_Phase_t phase = Angle_Handle(&upp.hangle);
+ Angle_Reset(&upp.hangle, phase);
+ // Если УПП в работе
+ if(upp.workmode == WM_Running)
+ {
+ switch(phase)
+ {
+ case UPP_PHASE_A:
+ PWM_Start(&upp.hpwm, UPP_PHASE_A);
+ break;
+ case UPP_PHASE_B:
+ PWM_Start(&upp.hpwm, UPP_PHASE_B);
+ break;
+ case UPP_PHASE_C:
+ PWM_Start(&upp.hpwm, UPP_PHASE_C);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef* htim)
{
if (htim == upp.hangle.htim)
{
UPP_Angle_Handle();
}
-}
-void UPP_Angle_Handle(void)
-{
- UPP_Phase_t phase = Angle_Handle(&upp.hangle);
- Angle_Reset(&upp.hangle, phase);
- switch(phase)
- {
- case UPP_PHASE_A:
- PWM_Start(&upp.hpwm, UPP_PHASE_A);
- break;
- case UPP_PHASE_B:
- PWM_Start(&upp.hpwm, UPP_PHASE_B);
- break;
- case UPP_PHASE_C:
- PWM_Start(&upp.hpwm, UPP_PHASE_C);
- break;
- default:
- break;
- }
}
\ No newline at end of file
diff --git a/UPP/Core/UPP/upp_main.h b/UPP/Core/UPP/upp_main.h
index 54b3f56..62bc657 100644
--- a/UPP/Core/UPP/upp_main.h
+++ b/UPP/Core/UPP/upp_main.h
@@ -1,6 +1,6 @@
/**
******************************************************************************
-* @file modbus_data.h
+* @file upp_main.h
* @brief Определения структур данных Modbus устройства
******************************************************************************
* @details
@@ -9,19 +9,35 @@
#ifndef _UPP_MAIN_H
#define _UPP_MAIN_H
-#include "main.h" // либы из AllLibs и вербальные имена из CubeMX
-#include "upp_config.h"
+#include "main.h" // общие библиотеки, конфигурации и вербальные имена из CubeMX
#include "power_monitor.h" // статистика сети и АЦП
#include "pwm_thyristors.h" // Управление тиристорами
#include "angle_control.h" // Управление углом открытия
+#include "upp_status.h" // статус упп
+#include "upp_control.h" // управление упп
+
extern float alpha_dbg;
+
typedef struct
{
- PowerMonitor_t pm;
- PWM_Handle_t hpwm;
- Angle_Handle_t hangle;
+ UPP_WorkModeType_t workmode; ///< Режим УПП
+ UPP_FuncCalls_t *call; ///< Вызов функций УПП
+
+ PowerMonitor_t pm; ///< Мониторинг сети
+ PWM_Handle_t hpwm; ///< Хендл ШИМ тиристоров
+ Angle_Handle_t hangle; ///< Хендл отсчитывания угла открытия
+
+ struct
+ {
+ UPP_PUI_Params_t *params; ///< Параметры от ПУИ
+ UPP_PUI_Values_t *values; ///< Данные для ПУИ
+ } PUI; ///< Общение с ПУИ
+
+
+ UPP_Errors_t *errors; ///< Ошибки УПП
+ uint32_t StartTick;
}UPP_t;
extern UPP_t upp;
@@ -32,7 +48,10 @@ int UPP_Init(void);
int UPP_PreWhile(void);
/* Основной цикл УПП. */
int UPP_While(void);
+/* Всякое что будет делатся каждую 1 мс. */
+void UPP_Tick(void);
+// Прерывания
void UPP_ADC_Handle(void);
void UPP_PWM_Handle(void);
void UPP_Angle_Handle(void);
diff --git a/UPP/Core/UPP/upp_status.c b/UPP/Core/UPP/upp_status.c
new file mode 100644
index 0000000..ed27e20
--- /dev/null
+++ b/UPP/Core/UPP/upp_status.c
@@ -0,0 +1,12 @@
+/**
+******************************************************************************
+* @file upp_status.c
+* @brief Модуль определяющий состояние УПП
+******************************************************************************
+* @details
+******************************************************************************/
+#include "upp_main.h" // всё остальное по работе с УПП
+
+void UPP_Status_Handler(void)
+{
+}
\ No newline at end of file
diff --git a/UPP/Core/UPP/upp_status.h b/UPP/Core/UPP/upp_status.h
new file mode 100644
index 0000000..e33d67f
--- /dev/null
+++ b/UPP/Core/UPP/upp_status.h
@@ -0,0 +1,13 @@
+/**
+******************************************************************************
+* @file upp_status.h
+* @brief Модуль определяющий состояние УПП
+******************************************************************************
+* @details
+******************************************************************************/
+
+#ifndef _UPP_STATUS_H
+#define _UPP_STATUS_H
+
+
+#endif //_UPP_STATUS_H
\ No newline at end of file
diff --git a/UPP/MDK-ARM/UPP.uvoptx b/UPP/MDK-ARM/UPP.uvoptx
index 7736db4..a8f9a56 100644
--- a/UPP/MDK-ARM/UPP.uvoptx
+++ b/UPP/MDK-ARM/UPP.uvoptx
@@ -206,6 +206,18 @@
0
0
0
+ ..\Core\Configs\upp_defs.h
+ upp_defs.h
+ 0
+ 0
+
+
+ 1
+ 3
+ 5
+ 0
+ 0
+ 0
..\Core\Inc\main.h
main.h
0
@@ -213,7 +225,7 @@
1
- 3
+ 4
5
0
0
@@ -225,7 +237,7 @@
1
- 4
+ 5
1
0
0
@@ -237,7 +249,7 @@
1
- 5
+ 6
5
0
0
@@ -249,7 +261,7 @@
1
- 6
+ 7
5
0
0
@@ -261,7 +273,7 @@
1
- 7
+ 8
5
0
0
@@ -273,7 +285,7 @@
1
- 8
+ 9
5
0
0
@@ -285,7 +297,7 @@
1
- 9
+ 10
5
0
0
@@ -305,7 +317,7 @@
0
2
- 10
+ 11
1
0
0
@@ -317,7 +329,7 @@
2
- 11
+ 12
5
0
0
@@ -329,7 +341,7 @@
2
- 12
+ 13
1
0
0
@@ -341,7 +353,7 @@
2
- 13
+ 14
5
0
0
@@ -353,7 +365,7 @@
2
- 14
+ 15
1
0
0
@@ -365,7 +377,7 @@
2
- 15
+ 16
5
0
0
@@ -375,6 +387,78 @@
0
0
+
+ 2
+ 17
+ 1
+ 0
+ 0
+ 0
+ ..\Core\UPP\upp_control.c
+ upp_control.c
+ 0
+ 0
+
+
+ 2
+ 18
+ 5
+ 0
+ 0
+ 0
+ ..\Core\UPP\upp_control.h
+ upp_control.h
+ 0
+ 0
+
+
+ 2
+ 19
+ 1
+ 0
+ 0
+ 0
+ ..\Core\UPP\upp_status.c
+ upp_status.c
+ 0
+ 0
+
+
+ 2
+ 20
+ 5
+ 0
+ 0
+ 0
+ ..\Core\UPP\upp_status.h
+ upp_status.h
+ 0
+ 0
+
+
+ 2
+ 21
+ 1
+ 0
+ 0
+ 0
+ ..\Core\UPP\upp_errors.c
+ upp_errors.c
+ 0
+ 0
+
+
+ 2
+ 22
+ 5
+ 0
+ 0
+ 0
+ ..\Core\UPP\upp_errors.h
+ upp_errors.h
+ 0
+ 0
+
@@ -385,7 +469,7 @@
0
3
- 16
+ 23
1
0
0
@@ -397,7 +481,7 @@
3
- 17
+ 24
5
0
0
@@ -409,7 +493,7 @@
3
- 18
+ 25
1
0
0
@@ -421,7 +505,7 @@
3
- 19
+ 26
5
0
0
@@ -433,7 +517,7 @@
3
- 20
+ 27
1
0
0
@@ -445,7 +529,7 @@
3
- 21
+ 28
5
0
0
@@ -465,7 +549,7 @@
0
4
- 22
+ 29
1
0
0
@@ -477,7 +561,7 @@
4
- 23
+ 30
1
0
0
@@ -489,7 +573,7 @@
4
- 24
+ 31
1
0
0
@@ -501,7 +585,7 @@
4
- 25
+ 32
1
0
0
@@ -513,7 +597,7 @@
4
- 26
+ 33
1
0
0
@@ -525,7 +609,7 @@
4
- 27
+ 34
1
0
0
@@ -537,7 +621,7 @@
4
- 28
+ 35
1
0
0
@@ -549,7 +633,7 @@
4
- 29
+ 36
1
0
0
@@ -561,7 +645,7 @@
4
- 30
+ 37
1
0
0
@@ -573,7 +657,7 @@
4
- 31
+ 38
1
0
0
@@ -585,7 +669,7 @@
4
- 32
+ 39
1
0
0
@@ -597,7 +681,7 @@
4
- 33
+ 40
1
0
0
@@ -609,7 +693,7 @@
4
- 34
+ 41
1
0
0
@@ -629,7 +713,7 @@
0
5
- 35
+ 42
5
0
0
@@ -641,7 +725,7 @@
5
- 36
+ 43
5
0
0
@@ -653,7 +737,7 @@
5
- 37
+ 44
5
0
0
@@ -665,7 +749,7 @@
5
- 38
+ 45
5
0
0
@@ -677,7 +761,7 @@
5
- 39
+ 46
5
0
0
@@ -689,7 +773,7 @@
5
- 40
+ 47
5
0
0
@@ -701,7 +785,7 @@
5
- 41
+ 48
1
0
0
@@ -713,7 +797,7 @@
5
- 42
+ 49
5
0
0
@@ -733,7 +817,7 @@
0
6
- 43
+ 50
1
0
0
@@ -745,7 +829,7 @@
6
- 44
+ 51
1
0
0
@@ -757,7 +841,7 @@
6
- 45
+ 52
1
0
0
@@ -769,7 +853,7 @@
6
- 46
+ 53
1
0
0
@@ -781,7 +865,7 @@
6
- 47
+ 54
1
0
0
@@ -793,7 +877,7 @@
6
- 48
+ 55
1
0
0
@@ -805,7 +889,7 @@
6
- 49
+ 56
1
0
0
@@ -817,7 +901,7 @@
6
- 50
+ 57
1
0
0
@@ -829,7 +913,7 @@
6
- 51
+ 58
1
0
0
@@ -841,7 +925,7 @@
6
- 52
+ 59
1
0
0
@@ -853,7 +937,7 @@
6
- 53
+ 60
1
0
0
@@ -865,7 +949,7 @@
6
- 54
+ 61
1
0
0
@@ -885,7 +969,7 @@
0
7
- 55
+ 62
1
0
0
@@ -897,7 +981,7 @@
7
- 56
+ 63
1
0
0
@@ -917,7 +1001,7 @@
0
8
- 57
+ 64
1
0
0
@@ -929,7 +1013,7 @@
8
- 58
+ 65
1
0
0
@@ -941,7 +1025,7 @@
8
- 59
+ 66
1
0
0
@@ -953,7 +1037,7 @@
8
- 60
+ 67
1
0
0
@@ -965,7 +1049,7 @@
8
- 61
+ 68
1
0
0
@@ -985,7 +1069,7 @@
0
9
- 62
+ 69
1
0
0
@@ -997,7 +1081,7 @@
9
- 63
+ 70
1
0
0
@@ -1009,7 +1093,7 @@
9
- 64
+ 71
1
0
0
@@ -1021,7 +1105,7 @@
9
- 65
+ 72
1
0
0
@@ -1033,7 +1117,7 @@
9
- 66
+ 73
1
0
0
@@ -1045,7 +1129,7 @@
9
- 67
+ 74
1
0
0
@@ -1057,7 +1141,7 @@
9
- 68
+ 75
1
0
0
@@ -1069,7 +1153,7 @@
9
- 69
+ 76
1
0
0
@@ -1081,7 +1165,7 @@
9
- 70
+ 77
1
0
0
@@ -1093,7 +1177,7 @@
9
- 71
+ 78
1
0
0
@@ -1105,7 +1189,7 @@
9
- 72
+ 79
1
0
0
@@ -1117,7 +1201,7 @@
9
- 73
+ 80
1
0
0
@@ -1129,7 +1213,7 @@
9
- 74
+ 81
1
0
0
@@ -1141,7 +1225,7 @@
9
- 75
+ 82
1
0
0
@@ -1153,7 +1237,7 @@
9
- 76
+ 83
1
0
0
@@ -1165,7 +1249,7 @@
9
- 77
+ 84
1
0
0
@@ -1177,7 +1261,7 @@
9
- 78
+ 85
1
0
0
@@ -1189,7 +1273,7 @@
9
- 79
+ 86
1
0
0
@@ -1201,7 +1285,7 @@
9
- 80
+ 87
1
0
0
@@ -1213,7 +1297,7 @@
9
- 81
+ 88
1
0
0
@@ -1225,7 +1309,7 @@
9
- 82
+ 89
1
0
0
@@ -1237,7 +1321,7 @@
9
- 83
+ 90
1
0
0
@@ -1249,7 +1333,7 @@
9
- 84
+ 91
1
0
0
@@ -1261,7 +1345,7 @@
9
- 85
+ 92
1
0
0
@@ -1281,7 +1365,7 @@
0
10
- 86
+ 93
1
0
0
@@ -1301,7 +1385,7 @@
0
11
- 87
+ 94
2
0
0
diff --git a/UPP/MDK-ARM/UPP.uvprojx b/UPP/MDK-ARM/UPP.uvprojx
index 585e041..ff631f5 100644
--- a/UPP/MDK-ARM/UPP.uvprojx
+++ b/UPP/MDK-ARM/UPP.uvprojx
@@ -17,8 +17,8 @@
STM32F427ZGTx
STMicroelectronics
- Keil.STM32F4xx_DFP.2.17.1
- https://www.keil.com/pack/
+ Keil.STM32F4xx_DFP.2.16.0
+ http://www.keil.com/pack/
IRAM(0x20000000-0x2002FFFF) IRAM2(0x10000000-0x1000FFFF) IROM(0x8000000-0x80FFFFF) CLOCK(25000000) FPU2 CPUTYPE("Cortex-M4") TZ
@@ -390,6 +390,11 @@
5
..\Core\Configs\upp_config.h
+
+ upp_defs.h
+ 5
+ ..\Core\Configs\upp_defs.h
+
main.h
5
@@ -465,6 +470,36 @@
5
..\Core\UPP\angle_control.h
+
+ upp_control.c
+ 1
+ ..\Core\UPP\upp_control.c
+
+
+ upp_control.h
+ 5
+ ..\Core\UPP\upp_control.h
+
+
+ upp_status.c
+ 1
+ ..\Core\UPP\upp_status.c
+
+
+ upp_status.h
+ 5
+ ..\Core\UPP\upp_status.h
+
+
+ upp_errors.c
+ 1
+ ..\Core\UPP\upp_errors.c
+
+
+ upp_errors.h
+ 5
+ ..\Core\UPP\upp_errors.h
+