Compare commits

..

3 Commits

18 changed files with 314 additions and 191 deletions

View File

@ -30,7 +30,11 @@
#define TEMP_1 0 #define TEMP_1 0
#define TEMP_2 1 #define TEMP_2 1
//#define UPP_SIMULATE_I ///< Симулировт токи (Iref/2) а не брать с АЦП
//#define UPP_DISABLE_ERROR_BLOCK ///< Отключить блокировку УПП при ошибках
#define UPP_SIMULATE_I ///< Симулировт токи (Iref/2) а не брать с АЦП
#define UPP_DISABLE_PROTECT_BOARDPOWER ///< Отключить проверки питания плат (+24, +5 В)
#define UPP_DISABLE_PROTECT_LOSS_PHASE ///< Отключить проверки на потерянные фазы
/** /**
* @addtogroup UPP_PARAMS_DEFAULT Default params for external flash * @addtogroup UPP_PARAMS_DEFAULT Default params for external flash
@ -47,7 +51,7 @@
/* Номинальные параметры */ /* Номинальные параметры */
#define NOM_PHASE_NUMB 3 #define NOM_PHASE_NUMB 3
#define NOM_U_V_DEFAULT 690 #define NOM_U_V_DEFAULT 1216
#define NOM_U_DEVIATION_PLUS_PERCENT_DEFAULT 6 #define NOM_U_DEVIATION_PLUS_PERCENT_DEFAULT 6
#define NOM_U_DEVIATION_MINUS_PERCENT_DEFAULT 10 #define NOM_U_DEVIATION_MINUS_PERCENT_DEFAULT 10
#define NOM_F_HZ_DEFAULT 50 #define NOM_F_HZ_DEFAULT 50
@ -76,13 +80,13 @@
#define ANGLE_PULSE_LENGTH_RESERVE_PERCENT_DEFAULT 1.0 #define ANGLE_PULSE_LENGTH_RESERVE_PERCENT_DEFAULT 1.0
#define ANGLE_MAX_PERCENT_DEFAULT 0.8 #define ANGLE_MAX_PERCENT_DEFAULT 0.8
#define ANGLE_MIN_PERCENT_DEFAULT 0.1 #define ANGLE_MIN_PERCENT_DEFAULT 0.1
#define ANGLE_PID_KP_COEF_DEFAULT 1.0 #define ANGLE_PID_KP_COEF_DEFAULT 0.0001
#define ANGLE_PID_KI_COEF_DEFAULT 0.01 #define ANGLE_PID_KI_COEF_DEFAULT 0.0001
#define ANGLE_PID_KD_COEF_DEFAULT 0 #define ANGLE_PID_KD_COEF_DEFAULT 0
#define ANGLE_REF_ALPHA_COEF_DEFAULT 0.0001 #define ANGLE_REF_TAU_COEF_DEFAULT 20.0
/* Параметри мониторинга сети */ /* Параметри мониторинга сети */
#define PM_EXP_ALPHA_COEF_DEFAULT 0.01 #define PM_EXP_TAU_COEF_DEFAULT 0.05
/* Параметры АЦП */ /* Параметры АЦП */
#define ADC_U_MAX_V_DEFAULT 1216.0 #define ADC_U_MAX_V_DEFAULT 1216.0

View File

@ -155,11 +155,11 @@ typedef struct {
#define MS_TO_SLOW_TICKS(_ms_) US_TO_SLOW_TICKS((_ms_)*1000) #define MS_TO_SLOW_TICKS(_ms_) US_TO_SLOW_TICKS((_ms_)*1000)
#define PM_F_SLOW_PERIOD_CNT (MS_TO_SLOW_TICKS(PM_F_SLOW_PERIOD_MS)) ///< Период обновления частоты в тиках @ref PM_SLOW_PERIOD_CNT #define PM_F_SLOW_PERIOD_CNT (MS_TO_SLOW_TICKS(PM_F_SLOW_PERIOD_MS)) ///< Период обновления частоты в тиках @ref PM_SLOW_PERIOD_CNT
/* Перерасчеты в тики */ /* Перерасчеты в тики */
#define ANGLE_PERIOD_MS(_freq_) (((float)1/(_freq_*2))*1000) ///< Период обновления частоты в тиках @ref PM_SLOW_PERIOD_CNT #define ANGLE_PERIOD_MS(_freq_) (((float)1/(_freq_*2))*1000) ///< Период обновления частоты в тиках @ref PM_SLOW_PERIOD_CNT
/* Расчет коэффициента альфа для экспоненциального фильтра */
#define CALC_TAU_COEF(tau, TsUs) (((float)TsUs/1000000) / (((float)TsUs/1000000) + (tau)))
/* Дефайны для "удобного" доступа к структурам */ /* Дефайны для "удобного" доступа к структурам */
#define PARAM_INTERNAL MB_INTERNAL.param #define PARAM_INTERNAL MB_INTERNAL.param

View File

@ -176,6 +176,18 @@ void Error_Handler(void);
/* USER CODE BEGIN Private defines */ /* USER CODE BEGIN Private defines */
extern TIM_HandleTypeDef ustim; extern TIM_HandleTypeDef ustim;
void SystemClock_Config_STM32F417(void); void SystemClock_Config_STM32F417(void);
#if defined(STM32F417xx)
#undef ERR_24V_GPIO_Port
#undef ERR_24V_Pin
#undef DIN1_GPIO_Port
#undef DIN1_Pin
#define ERR_24V_Pin GPIO_PIN_15
#define ERR_24V_GPIO_Port GPIOG
#define DIN1_Pin GPIO_PIN_12
#define DIN1_GPIO_Port GPIOG
#endif
/* USER CODE END Private defines */ /* USER CODE END Private defines */
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -150,9 +150,9 @@ void PowerMonitor_SlowCalc(PowerMonitor_t *hpm)
float fmean = 0; // средняя частота по трем фазам float fmean = 0; // средняя частота по трем фазам
float iphase_mean = 0; // средний ток каждой фазы float iphase_mean = 0; // средний ток каждой фазы
float uphase_mean = 0; // среднее напряжение каждой фазы float uphase_mean = 0; // среднее напряжение каждой фазы
// Дополнительно посчитаем значения в реальных Вольтах/Амперах
float u_base = to_float(PARAM_INTERNAL.nominal.U, 10); // Дополнительно посчитаем значения в реалдьных Вольтах float u_base = to_float(PARAM_INTERNAL.nominal.U, 10);
float i_base = to_float(PARAM_INTERNAL.nominal.I, 10); // Дополнительно посчитаем значения в реалдьных Амперах float i_base = to_float(PARAM_INTERNAL.nominal.I, 10);
for(int i = 0; i < 3; i++) for(int i = 0; i < 3; i++)
{ {
/* Получение частоты фазы */ /* Получение частоты фазы */
@ -260,9 +260,9 @@ void PowerMonitor_FastCalc(PowerMonitor_t *hpm)
/** /**
* @brief Проверяет защиты питания и температур. * @brief Проверяет защиты питания и температур.
* @param measure Указатель на структуру с измеренными значениями * @param measure Указатель на структуру с измеренными значениями
* @param Running Флаг: * @param Running Флаг для защит по току:
* - 1 - УПП в работе, * - 1 - УПП в работе, проверяем токи
* - 0 - УПП ожидает команды * - 0 - УПП ожидает команды, не смотрим токи
* @return 1 - была обнаружена ощибка, 0 - все ок * @return 1 - была обнаружена ощибка, 0 - все ок
*/ */
int PowerMonitor_Protect(PowerMonitor_t *hpm, uint8_t Running) int PowerMonitor_Protect(PowerMonitor_t *hpm, uint8_t Running)

View File

@ -3,6 +3,8 @@
* @file power_monitor.h * @file power_monitor.h
* @brief Модуль мониторящий сеть: Напряжение, Токи, Температуры * @brief Модуль мониторящий сеть: Напряжение, Токи, Температуры
****************************************************************************** ******************************************************************************
* @addtogroup POWER_MONITOR Power Monitoring
* @brief Модуль для слежения за сетью и температурами (крч все что от АЦП)
*****************************************************************************/ *****************************************************************************/
#ifndef _POWER_MONITOR_H_ #ifndef _POWER_MONITOR_H_
#define _POWER_MONITOR_H_ #define _POWER_MONITOR_H_

View File

@ -147,11 +147,17 @@ void MX_GPIO_Init(void)
GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/*Configure GPIO pins : PGPin PGPin */ /*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = ERR_24V_Pin|DIN1_Pin; GPIO_InitStruct.Pin = ERR_24V_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); HAL_GPIO_Init(ERR_24V_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = DIN1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(DIN1_GPIO_Port, &GPIO_InitStruct);
} }

View File

@ -25,6 +25,7 @@
#include "spi.h" #include "spi.h"
#include "tim.h" #include "tim.h"
#include "usart.h" #include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/ /* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */ /* USER CODE BEGIN Includes */
@ -102,6 +103,7 @@ int main(void)
/* USER CODE END SysInit */ /* USER CODE END SysInit */
/* Initialize all configured peripherals */ /* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init(); MX_DMA_Init();
MX_ADC3_Init(); MX_ADC3_Init();
MX_USART3_UART_Init(); MX_USART3_UART_Init();

View File

@ -105,9 +105,16 @@ void Angle_PID_Reset(Angle_Handle_t *hangle)
if(assert_upp(hangle)) if(assert_upp(hangle))
return; return;
hangle->Iref = 0;
hangle->Imeas = 0;
/* Вычисляем выход PID */ /* Вычисляем выход PID */
arm_pid_reset_f32(&hangle->pid); arm_pid_reset_f32(&hangle->pid);
Filter_ReInit(&hangle->refFilter, hangle->refFilter.alpha);
Filter_Start(&hangle->refFilter);
Filter_Process(&hangle->refFilter, 0);
Angle_SetAngle(hangle, 0); Angle_SetAngle(hangle, 0);
Angle_Reset(hangle, UPP_PHASE_A); Angle_Reset(hangle, UPP_PHASE_A);
Angle_Reset(hangle, UPP_PHASE_B); Angle_Reset(hangle, UPP_PHASE_B);

View File

@ -9,6 +9,7 @@
#include "tim.h" #include "tim.h"
static HAL_StatusTypeDef __PWM_SetOutputState(PWM_Channel_t *hCh, uint32_t state); static HAL_StatusTypeDef __PWM_SetOutputState(PWM_Channel_t *hCh, uint32_t state);
static HAL_StatusTypeDef __PWM_ReConfigToSoftwarePulses(void);
/** /**
* @brief Инициализация ШИМ тиристоров. * @brief Инициализация ШИМ тиристоров.
@ -69,6 +70,7 @@ HAL_StatusTypeDef PWM_Init(PWM_Handle_t *hpwm)
PWM_Stop(hpwm, 0, 1); PWM_Stop(hpwm, 0, 1);
#ifndef PWM_HARDWARE_IMPULSES_CONTROL #ifndef PWM_HARDWARE_IMPULSES_CONTROL
__PWM_ReConfigToSoftwarePulses();
HAL_TIM_Base_Start_IT(&hpwm1); HAL_TIM_Base_Start_IT(&hpwm1);
#endif #endif
@ -80,12 +82,14 @@ HAL_StatusTypeDef PWM_Init(PWM_Handle_t *hpwm)
* @param hpwm Указатель на хендл ШИМ тиристоров * @param hpwm Указатель на хендл ШИМ тиристоров
* @param Phase На какой фазе надо запустить ШИМ * @param Phase На какой фазе надо запустить ШИМ
* @return HAL Status. * @return HAL Status.
* @details Переводит автомат состояний канала ШИМ в состояние запуска ШИМ.
*/ */
HAL_StatusTypeDef PWM_Start(PWM_Handle_t *hpwm, UPP_Phase_t Phase) HAL_StatusTypeDef PWM_Start(PWM_Handle_t *hpwm, UPP_Phase_t Phase)
{ {
if(assert_upp(hpwm)) if(assert_upp(hpwm))
return HAL_ERROR; return HAL_ERROR;
// Если уже какой-то канал запущен - не запускаем
if(hpwm->f.Running)
return HAL_BUSY;
// Если канал дурацкий - возвращаем ошибку // Если канал дурацкий - возвращаем ошибку
if(Phase >= 3) if(Phase >= 3)
{ {
@ -94,7 +98,6 @@ HAL_StatusTypeDef PWM_Start(PWM_Handle_t *hpwm, UPP_Phase_t Phase)
if (hpwm->Phase[Phase] == NULL || hpwm->Phase[Phase] == &hpwm->AllPhases[PHASE_UNKNOWN]) if (hpwm->Phase[Phase] == NULL || hpwm->Phase[Phase] == &hpwm->AllPhases[PHASE_UNKNOWN])
return HAL_ERROR; return HAL_ERROR;
switch(hpwm->Phase[Phase]->State) switch(hpwm->Phase[Phase]->State)
{ {
// Если мы НЕ в режиме ожидание - ошибка // Если мы НЕ в режиме ожидание - ошибка
@ -135,9 +138,8 @@ HAL_StatusTypeDef PWM_Start(PWM_Handle_t *hpwm, UPP_Phase_t Phase)
* @param Phase На какой фазе надо остановить ШИМ * @param Phase На какой фазе надо остановить ШИМ
* @param force_stop_all Принудительно остановить ВЕСЬ ШИМ * @param force_stop_all Принудительно остановить ВЕСЬ ШИМ
* @return HAL Status. * @return HAL Status.
* @details Переводит автомат канала ШИМ в состояние отключенного ШИМ и * @details Включает канал в режим форсированного неактивного выхода.
* включает канал в режим форсированного неактивного выхода. * При передаче 1 в force_stop_all, отключаются MOE (Main Output Enable) и все каналы ШИМ
* При передаче 1 в force_stop_all, отключаются все каналы ШИМ и выдается дискрет на запрет ШИМ
*/ */
HAL_StatusTypeDef PWM_Stop(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint8_t force_stop_all) HAL_StatusTypeDef PWM_Stop(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint8_t force_stop_all)
{ {
@ -153,6 +155,7 @@ HAL_StatusTypeDef PWM_Stop(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint8_t force_
__HAL_TIM_MOE_DISABLE(&hpwm2); __HAL_TIM_MOE_DISABLE(&hpwm2);
// выставляем все каналы в FORCE MODE
for(int ch = 0; ch < 6; ch++) for(int ch = 0; ch < 6; ch++)
{ {
__PWM_SetOutputState(&hpwm->AllPhases[ch], PWM_DISABLE); __PWM_SetOutputState(&hpwm->AllPhases[ch], PWM_DISABLE);
@ -170,86 +173,20 @@ HAL_StatusTypeDef PWM_Stop(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint8_t force_
if (hpwm->Phase[Phase] == NULL || hpwm->Phase[Phase] == &hpwm->AllPhases[PHASE_UNKNOWN]) if (hpwm->Phase[Phase] == NULL || hpwm->Phase[Phase] == &hpwm->AllPhases[PHASE_UNKNOWN])
return HAL_ERROR; return HAL_ERROR;
hpwm->Phase[Phase]->State = PWM_THYR_DISABLED;
// Если не force_stop_all - сбрасываем только текущий канал // Если не force_stop_all - сбрасываем только текущий канал
__PWM_SetOutputState(hpwm->Phase[Phase], PWM_DISABLE); __PWM_SetOutputState(hpwm->Phase[Phase], PWM_DISABLE);
if(hpwm->Phase[Phase]->State != PWM_THYR_DISABLED)
{
hpwm->Phase[Phase]->State = PWM_THYR_DISABLED;
#ifdef PWM_HARDWARE_IMPULSES_CONTROL #ifdef PWM_HARDWARE_IMPULSES_CONTROL
if(hpwm->f.Running) if(hpwm->f.Running)
hpwm->f.Running--; hpwm->f.Running--;
HAL_TIM_Base_Stop(hpwm->Phase[Phase]->htim);
HAL_TIM_Base_Stop(hpwm->Phase[Phase]->htim);
#endif #endif
}
return HAL_OK; return HAL_OK;
} }
} }
/**
* @brief Хендл ШИМ тиристоров.
* @param hpwm Указатель на хендл ШИМ тиристоров
* @return HAL Status.
* @details Автомат состояний, который определяет поведение каналов ШИМ
*/
HAL_StatusTypeDef PWM_Handle(PWM_Handle_t *hpwm)
{
if(assert_upp(hpwm))
return HAL_ERROR;
uint8_t phase = 0;
PWM_Channel_t *hPhase = NULL;
for(int ch = 0; ch < 6; ch++)
{
hPhase = &hpwm->AllPhases[ch];
if (hPhase->htim == NULL)
continue;
#ifndef PWM_HARDWARE_IMPULSES_CONTROL
switch (hPhase->State)
{
case PWM_THYR_DISABLED: // канал отключен
__PWM_SetOutputState(hPhase, PWM_DISABLE);
break;
case PWM_THYR_TIM_WAIT: // канал ожидает команды
__PWM_SetOutputState(hPhase, PWM_DISABLE);
break;
case PWM_THYR_TIM_START: // начать ШИМ (пачка импульсов)
__PWM_SetOutputState(hPhase, PWM_ENABLE);
hPhase->PulseCnt = hpwm->Config.PulseNumber - 1; // 1 импульс уже прошел
hPhase->State = PWM_THYR_TIM_ACTIVE;
hpwm->f.Running++;
break;
case PWM_THYR_TIM_ACTIVE: // управление пачкой импульсов ШИМ
hPhase->PulseCnt--;
if (hPhase->PulseCnt <= 1) // если остался один импльс в след раз идем в PWM_THYR_TIM_DONE
{
hPhase->PulseCnt = 0;
hPhase->State = PWM_THYR_TIM_DONE;
}
break;
case PWM_THYR_TIM_DONE: // пачка импульсов отправлена - отключение
hPhase->State = PWM_THYR_TIM_WAIT;
if(hpwm->f.Running)
hpwm->f.Running--;
break;
default: // чзх
__PWM_SetOutputState(hPhase, PWM_DISABLE);
break;
}
#else //PWM_HARDWARE_IMPULSES_CONTROL
// после того как пачка импульсов прошла отключаем активный канал
if (hPhase->State == PWM_THYR_TIM_ACTIVE)
{
__PWM_SetOutputState(hPhase, PWM_DISABLE);
HAL_TIM_Base_Stop(hPhase->htim);
}
#endif
}
return HAL_OK;
}
/** /**
* @brief Установка параметров ШИМ. * @brief Установка параметров ШИМ.
@ -361,6 +298,79 @@ HAL_StatusTypeDef PWM_SetPolarity(PWM_Handle_t *hpwm, int polarity)
return HAL_OK; return HAL_OK;
} }
/**
* @brief Хендл ШИМ тиристоров.
* @param hpwm Указатель на хендл ШИМ тиристоров
* @return HAL Status.
* @details Автомат состояний, который определяет поведение каналов ШИМ
*/
HAL_StatusTypeDef PWM_Handle(PWM_Handle_t *hpwm)
{
if(assert_upp(hpwm))
return HAL_ERROR;
uint8_t phase = 0;
PWM_Channel_t *hPhase = NULL;
for(int ch = 0; ch < 6; ch++)
{
hPhase = &hpwm->AllPhases[ch];
if (hPhase->htim == NULL)
continue;
#ifndef PWM_HARDWARE_IMPULSES_CONTROL
switch (hPhase->State)
{
case PWM_THYR_DISABLED: // канал отключен
__PWM_SetOutputState(hPhase, PWM_DISABLE);
break;
case PWM_THYR_TIM_WAIT: // канал ожидает команды
__PWM_SetOutputState(hPhase, PWM_DISABLE);
break;
case PWM_THYR_TIM_START: // начать ШИМ (пачка импульсов)
__PWM_SetOutputState(hPhase, PWM_ENABLE);
hPhase->PulseCnt = hpwm->Config.PulseNumber - 1; // 1 импульс уже прошел
hPhase->State = PWM_THYR_TIM_ACTIVE;
hpwm->f.Running++;
break;
case PWM_THYR_TIM_ACTIVE: // управление пачкой импульсов ШИМ
hPhase->PulseCnt--;
if (hPhase->PulseCnt <= 1) // если остался один импльс в след раз идем в PWM_THYR_TIM_DONE
{
hPhase->PulseCnt = 0;
hPhase->State = PWM_THYR_TIM_DONE;
}
break;
case PWM_THYR_TIM_DONE: // пачка импульсов отправлена - отключение
hPhase->State = PWM_THYR_TIM_WAIT;
if(hpwm->f.Running)
hpwm->f.Running--;
break;
default: // чзх
__PWM_SetOutputState(hPhase, PWM_DISABLE);
break;
}
#else //PWM_HARDWARE_IMPULSES_CONTROL
// после того как пачка импульсов прошла отключаем активный канал
if (hPhase->State == PWM_THYR_TIM_ACTIVE)
{
if(hpwm->f.Running)
hpwm->f.Running--;
__PWM_SetOutputState(hPhase, PWM_DISABLE);
HAL_TIM_Base_Stop(hPhase->htim);
}
#endif
}
return HAL_OK;
}
//================ ВНУТРЕННИЕ ФУНКЦИИ ===================
/** /**
* @brief Установка режима для канала ШИМ. * @brief Установка режима для канала ШИМ.
* @param hpwm Указатель на хендл ШИМ тиристоров * @param hpwm Указатель на хендл ШИМ тиристоров
@ -408,3 +418,21 @@ static HAL_StatusTypeDef __PWM_SetOutputState(PWM_Channel_t *hCh, uint32_t state
return HAL_OK; return HAL_OK;
} }
/**
* @brief Переконфигурация таймером для софтварного формирования пачки импульсов.
* @return HAL Status.
*/
static HAL_StatusTypeDef __PWM_ReConfigToSoftwarePulses(void)
{
/* One Pulse и Repetitive не используем */
hpwm1.Instance->RCR = 0;
hpwm1.Instance->CR1 &= ~TIM_CR1_OPM;
hpwm2.Instance->RCR = 0;
hpwm2.Instance->CR1 &= ~TIM_CR1_OPM;
/* Настраиваем Slave на втором таймере*/
TIM_SlaveConfigTypeDef sSlaveConfig = {0};
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_TRIGGER;
sSlaveConfig.InputTrigger = TIM_TS_ITR0;
return HAL_TIM_SlaveConfigSynchro(&htim8, &sSlaveConfig);
}

View File

@ -9,7 +9,11 @@
#include "main.h" #include "main.h"
/**
* @brief Вкоючить хардварный способ формирования пачки импульсов
* @note При отключении сильно возрастет нагрузка на контроллер из-за прерываний ШИМ!
* Они поак работают всегда, независимо от того есть импулсь или нет
*/
#define PWM_HARDWARE_IMPULSES_CONTROL #define PWM_HARDWARE_IMPULSES_CONTROL

View File

@ -9,6 +9,9 @@
В этом модуле смотрятся какие флаги выставились и переносят эти флаги В этом модуле смотрятся какие флаги выставились и переносят эти флаги
в структуру ошибок ПУИ ERR_PUI. в структуру ошибок ПУИ ERR_PUI.
Исключение: Программные ошибки и ошибки питания плат,
они пишутся напрямую в ERR_PUI.
Также реализована защита от дребезга и в целом задержка на выставление ошибок. Также реализована защита от дребезга и в целом задержка на выставление ошибок.
******************************************************************************/ ******************************************************************************/
#include "upp_main.h" // УПП #include "upp_main.h" // УПП
@ -27,22 +30,23 @@ void UPP_Errors_Other(void);
void UPP_Errors_Handle(void) void UPP_Errors_Handle(void)
{ {
/*====== Программные ошибки ======*/ /*====== Программные ошибки ======*/
UPP_Errors_Program(); UPP_Errors_Program();
/*====== Ошибки питания плат ======*/ /*====== Ошибки питания плат ======*/
#ifndef UPP_DISABLE_PROTECT_BOARDPOWER
UPP_Errors_Power(); UPP_Errors_Power();
#endif
/*====== Ошибки выхода за допустимые пределы ======*/ /*====== Ошибки выхода за допустимые пределы ======*/
UPP_Errors_Ranges(); UPP_Errors_Ranges();
/*====== Потери фазы ======*/ /*====== Потери фазы ======*/
#ifndef UPP_DISABLE_PROTECT_LOSS_PHASE
UPP_Errors_LossPhase(); UPP_Errors_LossPhase();
#endif
/*====== Остальные ======*/ /*====== Остальные ======*/
UPP_Errors_Other(); UPP_Errors_Other();
errors.common = UPP_SelectCommonError(); errors.common = UPP_SelectCommonError();
} }
@ -53,7 +57,21 @@ void UPP_Errors_Program(void)
void UPP_Errors_Power(void) void UPP_Errors_Power(void)
{ {
//read discrete inputs static int error_latch_ticks = 0;
int error_latch_timeout = 5000;
/* Считывание неисправностей источников питания */
int err_24Vdio = GPIO_Read_Switch(&UPP_DIN.err_24Vdio);
int err_24V = GPIO_Read_Switch(&UPP_DIN.err_24V);
int err_5Vd = GPIO_Read_Switch(&UPP_DIN.err_5Vd);
int err_5Vsi = GPIO_Read_Switch(&UPP_DIN.err_5Vsi);
int err_Va = GPIO_Read_Switch(&UPP_DIN.err_Va);
ERR_PUI.Power_DIO_24V = err_24Vdio;
ERR_PUI.Power_24V = err_24V;
ERR_PUI.Power_Digit_5V = err_5Vd;
ERR_PUI.Power_SCI_5V = err_5Vsi;
ERR_PUI.Power_Analog_5V = err_Va;
} }
void UPP_Errors_Ranges(void) void UPP_Errors_Ranges(void)
@ -163,6 +181,7 @@ void UPP_Errors_Other(void)
{ {
static int InterlaceCnt = 0; static int InterlaceCnt = 0;
if(ERR_PRIVATE.longstart) if(ERR_PRIVATE.longstart)
ERR_PUI.LongStart = 1; ERR_PUI.LongStart = 1;
else else

View File

@ -1,16 +1,21 @@
/** /**
****************************************************************************** ******************************************************************************
* @file upp_main.c * @file upp_main.c
* @brief Инициализация и самые базовые вещи по работе УПП * @brief Главный файл по работе УПП
****************************************************************************** ******************************************************************************
* @details * @details
Работа УПП состоит из нескольких модулей:
- @ref POWER_MONITOR - Считывание и фильтрация данных от АЦП и выставление защит по этим данным
- @ref PWM_THYRISTORS - Формирование пачки импульсов
- @ref ANGLE_CONTROL - Формирование и регулирование угла открытия тиристора
******************************************************************************/ ******************************************************************************/
#include "upp_main.h" // всё остальное по работе с УПП #include "upp_main.h" // всё остальное по работе с УПП
#include "tim.h" #include "tim.h"
#include "iwdg.h" #include "iwdg.h"
UPP_t upp; UPP_t upp;
float dbg_iref = 1; HAL_StatusTypeDef res; // сюда сохраняется результат от выполения всяких функций
float dbg_iref = 2;
int dbg_polarity = 0; int dbg_polarity = 0;
/** /**
@ -30,8 +35,6 @@ int UPP_App_Init(void)
upp.PUI.values = &MB_DATA.InRegs.pui; upp.PUI.values = &MB_DATA.InRegs.pui;
upp.call = &MB_INTERNAL.FuncCalls; upp.call = &MB_INTERNAL.FuncCalls;
UPP_DO.CEN(ENABLE);
if(HAL_TIM_Base_Start(&ustim) != HAL_OK) if(HAL_TIM_Base_Start(&ustim) != HAL_OK)
{ {
return 1; return 1;
@ -67,6 +70,8 @@ int UPP_PreWhile(void)
return 1; return 1;
UPP_DO.CEN(ENABLE);
return 0; return 0;
} }
@ -81,55 +86,63 @@ int UPP_While(void)
if(upp.pm.f.runSlow) if(upp.pm.f.runSlow)
{ {
static uint32_t slow_cnt = 0; static uint32_t slow_cnt = 0;
HAL_IWDG_Refresh(&hiwdg);
BenchTime_Start(BT_SLOWCALC, angletim.Instance->CNT, HAL_MAX_DELAY); BenchTime_Start(BT_SLOWCALC, angletim.Instance->CNT, HAL_MAX_DELAY);
res = HAL_IWDG_Refresh(&hiwdg);
// Медленные расчеты
PowerMonitor_SlowCalc(&upp.pm);
#ifdef UPP_SIMULATE_I // симулируем токи
upp.pm.measured.final.Iamp = upp.hangle.Iref/2;
// Защиты // При симуляции тока не включаем его проверку
PowerMonitor_Protect(&upp.pm, 0);
#else
// Защиты // Определенные защиты по току включаем только в после разгона
PowerMonitor_Protect(&upp.pm, (fabsf(upp.hangle.Iref - dbg_iref) < 0.1));
#endif
#ifndef UPP_DISABLE_ERROR_BLOCK
// если ошибка вызываем СТОП // если ошибка вызываем СТОП
if(errors.pui.all) upp.call->stop = (errors.common != Err_None);
{ #endif
upp.call->stop = 0;
}
// иначе снимаем СТОП
else
{
upp.call->stop = 0;
}
// Если СТОП - переходим в ошибку
if (upp.call->stop)
upp.workmode = UPP_Error;
// Сброс на дефолтные по запросу // Сброс на дефолтные по запросу
if(upp.call->set_default_pui || upp.call->set_default_internal) if(upp.call->set_default_pui || upp.call->set_default_internal)
{ {
UPP_Params_SetDefault(upp.call->set_default_pui, upp.call->set_default_internal); UPP_Params_SetDefault(upp.call->set_default_pui, upp.call->set_default_internal);
upp.call->set_default_pui = 0;
upp.call->set_default_internal = 0;
} }
// Медленные расчеты
PowerMonitor_SlowCalc(&upp.pm);
// Защиты // Определенные защиты включаем только в режиме работы
PowerMonitor_Protect(&upp.pm, upp.workmode == UPP_Work);
// Если СТОП - переходим в ошибку
if (upp.call->stop)
upp.workmode = UPP_Error;
// Автомат состояний УПП // Автомат состояний УПП
switch(upp.workmode) switch(upp.workmode)
{ {
/* Состояние инициализации */ /*======= Состояние Инициализация =========*/
case UPP_Init: case UPP_Init:
if(slow_cnt == 0)
{ // начало инициализации - сбрасываем флаги
memset(&ERR_PRIVATE, 0, sizeof(ERR_PRIVATE));
memset(&ERR_PUI, 0, sizeof(ERR_PUI));
}
if(slow_cnt > MS_TO_SLOW_TICKS(UPP_INIT_BEFORE_READY_MS)) if(slow_cnt > MS_TO_SLOW_TICKS(UPP_INIT_BEFORE_READY_MS))
{ { // конец инициализации - сбрасываем чтобы потом еще раз инициализироватся
slow_cnt = 0; // сбрасываем чтобы потом еще раз инициализироватся slow_cnt = 0;
upp.workmode = UPP_Ready; upp.workmode = UPP_Ready;
} }
else else
{ { // инициализация в процессе
slow_cnt++; slow_cnt++;
} }
break; break;
/* Состояние готовности */ /*======= Состояние Готовность =========*/
case UPP_Ready: case UPP_Ready:
PWM_Stop(&upp.hpwm, 0, 1); // Останавливаем ВЕСЬ ШИМ res = PWM_Stop(&upp.hpwm, 0, 1); // Останавливаем ВЕСЬ ШИМ
// Индикация // Индикация
UPP_DO.Ready(ENABLE); UPP_DO.Ready(ENABLE);
UPP_DO.Work(DISABLE); UPP_DO.Work(DISABLE);
@ -144,7 +157,7 @@ int UPP_While(void)
} }
break; break;
/* Состояние В работе */ /*======= Состояние В работе =========*/
case UPP_Work: case UPP_Work:
// Индикация // Индикация
UPP_DO.Ready(DISABLE); UPP_DO.Ready(DISABLE);
@ -154,12 +167,9 @@ int UPP_While(void)
if (!upp.call->go) if (!upp.call->go)
upp.workmode = UPP_Init; upp.workmode = UPP_Init;
// Регулирование тиристоров // Регулирование тиристоров
#ifndef UPP_SIMULATE_I // берем с АЦП
Angle_PID(&upp.hangle, dbg_iref, upp.pm.measured.final.Iamp); Angle_PID(&upp.hangle, dbg_iref, upp.pm.measured.final.Iamp);
#else // симулируем
Angle_PID(&upp.hangle, dbg_iref, upp.hangle.Iref/2);
#endif
// если слишком долгий запуск // если слишком долгий запуск
if((local_time() - upp.StartTick) > (upp.PUI.params->Tdelay*1000)) if((local_time() - upp.StartTick) > (upp.PUI.params->Tdelay*1000))
{ {
@ -167,7 +177,7 @@ int UPP_While(void)
} }
break; break;
// /* Состояние Работа завершена */ /*======= Состояние Работа завершена =========*/
// case WM_Done: // case WM_Done:
// // Индикация // // Индикация
// UPP_DO.Ready(DISABLE); // UPP_DO.Ready(DISABLE);
@ -176,7 +186,7 @@ int UPP_While(void)
// PWM_Stop(&upp.hpwm, 0, 1); // Останавливаем ВЕСЬ ШИМ // PWM_Stop(&upp.hpwm, 0, 1); // Останавливаем ВЕСЬ ШИМ
// break; // break;
/* Состояние Ошибки */ /*======= Состояние Ошибка/Неизвестно =========*/
case UPP_Error: case UPP_Error:
default: default:
PWM_Stop(&upp.hpwm, 0, 1); // Останавливаем ВЕСЬ ШИМ PWM_Stop(&upp.hpwm, 0, 1); // Останавливаем ВЕСЬ ШИМ
@ -192,11 +202,6 @@ int UPP_While(void)
break; break;
} }
UPP_Errors_Handle();
UPP_Params_ControlInternal();
upp.pm.f.runSlow = 0; upp.pm.f.runSlow = 0;
upp.Timings.slow_calc_us = BenchTime_End(BT_SLOWCALC, angletim.Instance->CNT)/ANGLE_TIM2_FREQ_MHZ; upp.Timings.slow_calc_us = BenchTime_End(BT_SLOWCALC, angletim.Instance->CNT)/ANGLE_TIM2_FREQ_MHZ;
}//if(upp.pm.f.runSlow) }//if(upp.pm.f.runSlow)
@ -216,12 +221,25 @@ void UPP_Tick(void)
{ {
if(upp.workmode == UPP_Init) if(upp.workmode == UPP_Init)
return; return;
// Обрабока ошибок и выставление итоговой Ошибки
UPP_Errors_Handle();
//
UPP_Params_ControlInternal();
if(GPIO_Read_Switch(&UPP_DIN.Pusk))
{
upp.call->go = 1;
}
else
{
upp.call->go = 0;
}
} }
// ПРЕРЫВАНИЯ stm32f4xx_it.c // ПРЕРЫВАНИЯ stm32f4xx_it.c
void UPP_ADC_Handle(void) void UPP_ADC_Handle(void)
{ {
BenchTime_Start(BT_ADC, angletim.Instance->CNT, HAL_MAX_DELAY); BenchTime_Start(BT_ADC, angletim.Instance->CNT, HAL_MAX_DELAY);
@ -245,9 +263,11 @@ void UPP_ADC_Handle(void)
{ {
// Меняем полуволну тиристора // Меняем полуволну тиристора
UPP_HalfWave_t curr_halfwave = ZC_GetHalfWave(&upp.pm.zc, phase); UPP_HalfWave_t curr_halfwave = ZC_GetHalfWave(&upp.pm.zc, phase);
PWM_SetHalfWave(&upp.hpwm, phase, curr_halfwave); res = PWM_SetHalfWave(&upp.hpwm, phase, curr_halfwave);
// Начинаем отсчитывать угол // Начинаем отсчитывать угол
Angle_Start(&upp.hangle, phase, 10); res = Angle_Start(&upp.hangle, phase, 10);
if(res != HAL_OK)
__NOP();
} }
} }
} }
@ -260,34 +280,37 @@ void UPP_ADC_Handle(void)
void UPP_PWM_Handle(void) void UPP_PWM_Handle(void)
{ {
BenchTime_Start(BT_PWM, angletim.Instance->CNT, HAL_MAX_DELAY); BenchTime_Start(BT_PWM, angletim.Instance->CNT, HAL_MAX_DELAY);
PWM_Handle(&upp.hpwm); res = PWM_Handle(&upp.hpwm);
upp.Timings.isr_pwm_us = BenchTime_End(BT_PWM, angletim.Instance->CNT)/ANGLE_TIM2_FREQ_MHZ; upp.Timings.isr_pwm_us = BenchTime_End(BT_PWM, angletim.Instance->CNT)/ANGLE_TIM2_FREQ_MHZ;
} }
void UPP_Angle_Handle(void) void UPP_Angle_Handle(void)
{ {
UPP_Phase_t phase = Angle_Handle(&upp.hangle); UPP_Phase_t phase = Angle_Handle(&upp.hangle);
Angle_Reset(&upp.hangle, phase); res = Angle_Reset(&upp.hangle, phase);
// Если УПП в работе // Если УПП в работе
if(upp.workmode == UPP_Work) if(upp.workmode == UPP_Work)
{ {
switch(phase) switch(phase)
{ {
case UPP_PHASE_A: case UPP_PHASE_A:
PWM_Start(&upp.hpwm, UPP_PHASE_A); res = PWM_Start(&upp.hpwm, UPP_PHASE_A);
break; break;
case UPP_PHASE_B: case UPP_PHASE_B:
PWM_Start(&upp.hpwm, UPP_PHASE_B); res = PWM_Start(&upp.hpwm, UPP_PHASE_B);
break; break;
case UPP_PHASE_C: case UPP_PHASE_C:
PWM_Start(&upp.hpwm, UPP_PHASE_C); res = PWM_Start(&upp.hpwm, UPP_PHASE_C);
break; break;
default: default:
break; break;
} }
if(res != HAL_OK)
__NOP();
} }
} }
// Callback по совпадению CCRx
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef* htim) void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef* htim)
{ {
if (htim == upp.hangle.htim) if (htim == upp.hangle.htim)

View File

@ -1,7 +1,7 @@
/** /**
****************************************************************************** ******************************************************************************
* @file upp_main.h * @file upp_main.h
* @brief Определения структур данных Modbus устройства * @brief Определения структур для работы УПП
****************************************************************************** ******************************************************************************
* @details * @details
******************************************************************************/ ******************************************************************************/

View File

@ -215,7 +215,7 @@ void UPP_Params_SetDefault(int pui_default, int internal_default)
PARAM_INTERNAL.nominal.F_deviation_minus = NOM_F_DEVIATION_MINUS_PERCENT_DEFAULT*100; PARAM_INTERNAL.nominal.F_deviation_minus = NOM_F_DEVIATION_MINUS_PERCENT_DEFAULT*100;
PARAM_INTERNAL.nominal.I = NOM_I_A_DEFAULT*10; PARAM_INTERNAL.nominal.I = NOM_I_A_DEFAULT*10;
PARAM_INTERNAL.pm.mean_alpha = PM_EXP_ALPHA_COEF_DEFAULT*65535; PARAM_INTERNAL.pm.mean_alpha = CALC_TAU_COEF(PM_EXP_TAU_COEF_DEFAULT,PM_SLOW_PERIOD_US)*65535;
PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_UBA] = ADC_U_MAX_V_DEFAULT*10; PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_UBA] = ADC_U_MAX_V_DEFAULT*10;
PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_UAC] = ADC_U_MAX_V_DEFAULT*10; PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_UAC] = ADC_U_MAX_V_DEFAULT*10;
@ -237,7 +237,7 @@ void UPP_Params_SetDefault(int pui_default, int internal_default)
PARAM_INTERNAL.angle.PID_Kp = ANGLE_PID_KP_COEF_DEFAULT*10000; PARAM_INTERNAL.angle.PID_Kp = ANGLE_PID_KP_COEF_DEFAULT*10000;
PARAM_INTERNAL.angle.PID_Ki = ANGLE_PID_KI_COEF_DEFAULT*10000; PARAM_INTERNAL.angle.PID_Ki = ANGLE_PID_KI_COEF_DEFAULT*10000;
PARAM_INTERNAL.angle.PID_Kd = ANGLE_PID_KD_COEF_DEFAULT*10000; PARAM_INTERNAL.angle.PID_Kd = ANGLE_PID_KD_COEF_DEFAULT*10000;
PARAM_INTERNAL.angle.PID_ExpAlpha = ANGLE_REF_ALPHA_COEF_DEFAULT*65535; PARAM_INTERNAL.angle.PID_ExpAlpha = CALC_TAU_COEF(ANGLE_REF_TAU_COEF_DEFAULT,PM_SLOW_PERIOD_US)*65535;
PARAM_INTERNAL.angle.Angle_Max = ANGLE_MAX_PERCENT_DEFAULT*65535; PARAM_INTERNAL.angle.Angle_Max = ANGLE_MAX_PERCENT_DEFAULT*65535;
PARAM_INTERNAL.angle.Angle_Min = ANGLE_MIN_PERCENT_DEFAULT*65535; PARAM_INTERNAL.angle.Angle_Min = ANGLE_MIN_PERCENT_DEFAULT*65535;
PARAM_INTERNAL.angle.PulseLengthReserve = ANGLE_PULSE_LENGTH_RESERVE_PERCENT_DEFAULT*100; PARAM_INTERNAL.angle.PulseLengthReserve = ANGLE_PULSE_LENGTH_RESERVE_PERCENT_DEFAULT*100;

View File

@ -331,7 +331,7 @@
<Type>0</Type> <Type>0</Type>
<LineNumber>407</LineNumber> <LineNumber>407</LineNumber>
<EnabledFlag>1</EnabledFlag> <EnabledFlag>1</EnabledFlag>
<Address>134233418</Address> <Address>134233790</Address>
<ByteObject>0</ByteObject> <ByteObject>0</ByteObject>
<HtxType>0</HtxType> <HtxType>0</HtxType>
<ManyObjects>0</ManyObjects> <ManyObjects>0</ManyObjects>
@ -345,6 +345,22 @@
<Bp> <Bp>
<Number>1</Number> <Number>1</Number>
<Type>0</Type> <Type>0</Type>
<LineNumber>136</LineNumber>
<EnabledFlag>1</EnabledFlag>
<Address>134256304</Address>
<ByteObject>0</ByteObject>
<HtxType>0</HtxType>
<ManyObjects>0</ManyObjects>
<SizeOfObject>0</SizeOfObject>
<BreakByAccess>0</BreakByAccess>
<BreakIfRCount>1</BreakIfRCount>
<Filename>../Core/Src/stm32f4xx_it.c</Filename>
<ExecCommand></ExecCommand>
<Expression>\\Debug_F417\../Core/Src/stm32f4xx_it.c\136</Expression>
</Bp>
<Bp>
<Number>2</Number>
<Type>0</Type>
<LineNumber>27</LineNumber> <LineNumber>27</LineNumber>
<EnabledFlag>1</EnabledFlag> <EnabledFlag>1</EnabledFlag>
<Address>0</Address> <Address>0</Address>
@ -358,22 +374,6 @@
<ExecCommand></ExecCommand> <ExecCommand></ExecCommand>
<Expression></Expression> <Expression></Expression>
</Bp> </Bp>
<Bp>
<Number>2</Number>
<Type>0</Type>
<LineNumber>136</LineNumber>
<EnabledFlag>1</EnabledFlag>
<Address>0</Address>
<ByteObject>0</ByteObject>
<HtxType>0</HtxType>
<ManyObjects>0</ManyObjects>
<SizeOfObject>0</SizeOfObject>
<BreakByAccess>0</BreakByAccess>
<BreakIfRCount>0</BreakIfRCount>
<Filename>../Core/Src/stm32f4xx_it.c</Filename>
<ExecCommand></ExecCommand>
<Expression></Expression>
</Bp>
</Breakpoint> </Breakpoint>
<WatchWindow1> <WatchWindow1>
<Ww> <Ww>
@ -429,27 +429,22 @@
<Ww> <Ww>
<count>10</count> <count>10</count>
<WinNumber>1</WinNumber> <WinNumber>1</WinNumber>
<ItemText>upp.call-&gt;reset_mcu</ItemText> <ItemText>upp.pm.zc.Channel[0].HalfWave</ItemText>
</Ww> </Ww>
<Ww> <Ww>
<count>11</count> <count>11</count>
<WinNumber>1</WinNumber> <WinNumber>1</WinNumber>
<ItemText>upp.pm.zc.Channel[0].HalfWave</ItemText> <ItemText>\\Debug_F417\../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c\uwTick</ItemText>
</Ww> </Ww>
<Ww> <Ww>
<count>12</count> <count>12</count>
<WinNumber>1</WinNumber> <WinNumber>1</WinNumber>
<ItemText>upp.call-&gt;reserved</ItemText> <ItemText>htim1</ItemText>
</Ww> </Ww>
<Ww> <Ww>
<count>13</count> <count>13</count>
<WinNumber>1</WinNumber> <WinNumber>1</WinNumber>
<ItemText>\\Debug_F417\../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c\uwTick</ItemText> <ItemText>htim2</ItemText>
</Ww>
<Ww>
<count>14</count>
<WinNumber>1</WinNumber>
<ItemText>htim1</ItemText>
</Ww> </Ww>
</WatchWindow1> </WatchWindow1>
<WatchWindow2> <WatchWindow2>
@ -513,6 +508,11 @@
<WinNumber>2</WinNumber> <WinNumber>2</WinNumber>
<ItemText>iref_dbg</ItemText> <ItemText>iref_dbg</ItemText>
</Ww> </Ww>
<Ww>
<count>12</count>
<WinNumber>2</WinNumber>
<ItemText>upp.pm.measured.slow.U[0]</ItemText>
</Ww>
</WatchWindow2> </WatchWindow2>
<Tracepoint> <Tracepoint>
<THDelay>0</THDelay> <THDelay>0</THDelay>
@ -534,7 +534,7 @@
<AscS3>0</AscS3> <AscS3>0</AscS3>
<aSer3>0</aSer3> <aSer3>0</aSer3>
<eProf>0</eProf> <eProf>0</eProf>
<aLa>0</aLa> <aLa>1</aLa>
<aPa1>0</aPa1> <aPa1>0</aPa1>
<AscS4>0</AscS4> <AscS4>0</AscS4>
<aSer4>0</aSer4> <aSer4>0</aSer4>
@ -568,6 +568,10 @@
<Name>System Viewer\DBG</Name> <Name>System Viewer\DBG</Name>
<WinId>35902</WinId> <WinId>35902</WinId>
</Entry> </Entry>
<Entry>
<Name>System Viewer\GPIOG</Name>
<WinId>35899</WinId>
</Entry>
<Entry> <Entry>
<Name>System Viewer\TIM1</Name> <Name>System Viewer\TIM1</Name>
<WinId>35901</WinId> <WinId>35901</WinId>

View File

@ -17,8 +17,8 @@
<TargetCommonOption> <TargetCommonOption>
<Device>STM32F427ZGTx</Device> <Device>STM32F427ZGTx</Device>
<Vendor>STMicroelectronics</Vendor> <Vendor>STMicroelectronics</Vendor>
<PackID>Keil.STM32F4xx_DFP.2.16.0</PackID> <PackID>Keil.STM32F4xx_DFP.2.17.1</PackID>
<PackURL>http://www.keil.com/pack/</PackURL> <PackURL>https://www.keil.com/pack/</PackURL>
<Cpu>IRAM(0x20000000-0x2002FFFF) IRAM2(0x10000000-0x1000FFFF) IROM(0x8000000-0x80FFFFF) CLOCK(25000000) FPU2 CPUTYPE("Cortex-M4") TZ</Cpu> <Cpu>IRAM(0x20000000-0x2002FFFF) IRAM2(0x10000000-0x1000FFFF) IROM(0x8000000-0x80FFFFF) CLOCK(25000000) FPU2 CPUTYPE("Cortex-M4") TZ</Cpu>
<FlashUtilSpec></FlashUtilSpec> <FlashUtilSpec></FlashUtilSpec>
<StartupFile></StartupFile> <StartupFile></StartupFile>
@ -1004,8 +1004,8 @@
<TargetCommonOption> <TargetCommonOption>
<Device>STM32F417ZGTx</Device> <Device>STM32F417ZGTx</Device>
<Vendor>STMicroelectronics</Vendor> <Vendor>STMicroelectronics</Vendor>
<PackID>Keil.STM32F4xx_DFP.2.16.0</PackID> <PackID>Keil.STM32F4xx_DFP.2.17.1</PackID>
<PackURL>http://www.keil.com/pack/</PackURL> <PackURL>https://www.keil.com/pack/</PackURL>
<Cpu>IRAM(0x20000000,0x00020000) IRAM2(0x10000000,0x00010000) IROM(0x08000000,0x00100000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE</Cpu> <Cpu>IRAM(0x20000000,0x00020000) IRAM2(0x10000000,0x00010000) IROM(0x08000000,0x00100000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE</Cpu>
<FlashUtilSpec></FlashUtilSpec> <FlashUtilSpec></FlashUtilSpec>
<StartupFile></StartupFile> <StartupFile></StartupFile>

View File

@ -358,8 +358,9 @@ PG12.GPIOParameters=GPIO_Label
PG12.GPIO_Label=ERR_24V PG12.GPIO_Label=ERR_24V
PG12.Locked=true PG12.Locked=true
PG12.Signal=GPIO_Input PG12.Signal=GPIO_Input
PG15.GPIOParameters=GPIO_Label PG15.GPIOParameters=GPIO_PuPd,GPIO_Label
PG15.GPIO_Label=DIN1 PG15.GPIO_Label=DIN1
PG15.GPIO_PuPd=GPIO_PULLUP
PG15.Locked=true PG15.Locked=true
PG15.Signal=GPIO_Input PG15.Signal=GPIO_Input
PG6.GPIOParameters=GPIO_PuPd,GPIO_Label PG6.GPIOParameters=GPIO_PuPd,GPIO_Label
@ -402,7 +403,7 @@ ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath= ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=false ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-true-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_ADC3_Init-ADC3-false-HAL-true,5-MX_USART3_UART_Init-USART3-false-HAL-true,6-MX_CAN1_Init-CAN1-false-HAL-true,7-MX_IWDG_Init-IWDG-false-HAL-true,8-MX_RTC_Init-RTC-true-HAL-true,9-MX_TIM1_Init-TIM1-false-HAL-true,10-MX_TIM3_Init-TIM3-false-HAL-true,11-MX_USART6_UART_Init-USART6-false-HAL-true,12-MX_SPI3_Init-SPI3-false-HAL-true,13-MX_TIM11_Init-TIM11-false-HAL-true,14-MX_TIM12_Init-TIM12-false-HAL-true,15-MX_TIM8_Init-TIM8-false-HAL-true,16-MX_TIM5_Init-TIM5-false-HAL-true,17-MX_TIM2_Init-TIM2-false-HAL-true ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_ADC3_Init-ADC3-false-HAL-true,5-MX_USART3_UART_Init-USART3-false-HAL-true,6-MX_CAN1_Init-CAN1-false-HAL-true,7-MX_IWDG_Init-IWDG-false-HAL-true,8-MX_RTC_Init-RTC-true-HAL-true,9-MX_TIM1_Init-TIM1-false-HAL-true,10-MX_TIM3_Init-TIM3-false-HAL-true,11-MX_USART6_UART_Init-USART6-false-HAL-true,12-MX_SPI3_Init-SPI3-false-HAL-true,13-MX_TIM11_Init-TIM11-false-HAL-true,14-MX_TIM12_Init-TIM12-false-HAL-true,15-MX_TIM8_Init-TIM8-false-HAL-true,16-MX_TIM5_Init-TIM5-false-HAL-true,17-MX_TIM2_Init-TIM2-false-HAL-true
RCC.48MHZClocksFreq_Value=90000000 RCC.48MHZClocksFreq_Value=90000000
RCC.AHBFreq_Value=180000000 RCC.AHBFreq_Value=180000000
RCC.APB1CLKDivider=RCC_HCLK_DIV4 RCC.APB1CLKDivider=RCC_HCLK_DIV4

View File

@ -0,0 +1,11 @@
clc
clear all
alpha = 0.01
ts = 500;
tau = (ts/1000000) * (1-alpha)/alpha
alpha2 = ts/1000000 / (ts/1000000 + tau )