Compare commits

...

2 Commits

13 changed files with 168 additions and 126 deletions

Binary file not shown.

@ -1 +1 @@
Subproject commit a6b27da4ce1d3cf60a251225beff3e6d0af1193e Subproject commit 795ebbd220fd16ba9db4d1c071ed66700c2df928

View File

@ -27,6 +27,8 @@
#define UPP_DISABLE_PROTECT_BOARDPOWER ///< Отключить проверки питания плат (+24, +5 В) #define UPP_DISABLE_PROTECT_BOARDPOWER ///< Отключить проверки питания плат (+24, +5 В)
#define UPP_DISABLE_PROTECT_LOSS_PHASE ///< Отключить проверки на потерянные фазы #define UPP_DISABLE_PROTECT_LOSS_PHASE ///< Отключить проверки на потерянные фазы
#define ZC_DISABLE_HYSTERESIS_DEBOUNCE ///< Отключить гиситерезис и дребезг на определении перехода через ноль
/** //UPP_PARAMS_TEST /** //UPP_PARAMS_TEST
* @} * @}
*/ */

View File

@ -7,36 +7,49 @@
******************************************************************************/ ******************************************************************************/
#include "adc_tools.h" #include "adc_tools.h"
static void ADC_EnableAllFilters(ADC_Periodic_t *adc)
{
for(int i = 0; i < ADC_NUMB_OF_CHANNELS; i++)
{
Filter_Start(&adc->filter[i]);
// FilterExpInt_Process(&adc->filter[i], adc->Coefs[i].lZero);
}
}
static void ADC_InitAllFilters(ADC_Periodic_t *adc) static void ADC_InitAllFilters(ADC_Periodic_t *adc)
{ {
// Filter_Init(&adc->filter[ADC_CHANNEL_UBA], coefs_biquad_U);
// Filter_Init(&adc->filter[ADC_CHANNEL_UAC], coefs_biquad_U);
// Filter_Init(&adc->filter[ADC_CHANNEL_IC], coefs_biquad_I);
// Filter_Init(&adc->filter[ADC_CHANNEL_IA], coefs_biquad_I);
// Filter_Init(&adc->filter[ADC_CHANNEL_TEMP1], coefs_biquad_T);
// Filter_Init(&adc->filter[ADC_CHANNEL_TEMP2], coefs_biquad_T);
for(int i = 0; i < ADC_NUMB_OF_CHANNELS; i++) // FilterBandPassDerivative_Init(&adc->u_fltr[U_AB], (50.0f*PM_FAST_PERIOD_US/1000000), 0.1);
// FilterBandPassDerivative_Init(&adc->u_fltr[U_CA], (50.0f*PM_FAST_PERIOD_US/1000000), 0.1);
//
// FilterMedianInt_Init(&adc->i_fltr[I_C], 5, 2048);
// FilterMedianInt_Init(&adc->i_fltr[I_A], 5, 2048);
//
// FilterLUT_Init(&adc->temp_map[TEMP_1],
// (float *)adc_temp_quants,
// (float *)adc_temp_vals,
// numbof(adc_temp_quants), 1);
// FilterLUT_Init(&adc->temp_map[TEMP_2],
// (float *)adc_temp_quants,
// (float *)adc_temp_vals,
// numbof(adc_temp_quants), 1);
// Инициализация фильтров
for(int i = 0; i < 2; i++)
{ {
Filter_Init(&adc->filter[i], Filter_Initializator); FilterBandPassDerivative_Init(&adc->u_fltr[i], (50.0f*PM_FAST_PERIOD_US/1000000), 0.1);
} FilterMedianInt_Init(&adc->i_fltr[I_C], 5, 2048);
FilterLUT_Init(&adc->temp_map[0], FilterLUT_Init(&adc->temp_map[i],
(float *)adc_temp_quants,
(float *)adc_temp_vals,
numbof(adc_temp_quants), 1);
FilterLUT_Init(&adc->temp_map[1],
(float *)adc_temp_quants, (float *)adc_temp_quants,
(float *)adc_temp_vals, (float *)adc_temp_vals,
numbof(adc_temp_quants), 1); numbof(adc_temp_quants), 1);
} }
// Запуск фильтров
for(int i = 0; i < 2; i++)
{
Filter_Start(&adc->u_fltr[i]);
Filter_Start(&adc->i_fltr[i]);
Filter_Start(&adc->temp_map[i]);
}
}
__STATIC_FORCEINLINE void ADC_FilterRaw(ADC_Periodic_t *adc, int ch_start, int ch_end)
{
}
/** /**
* @brief Инициализация периодического АЦП. * @brief Инициализация периодического АЦП.
* @param adc Указатель на кастомный хендл АЦП * @param adc Указатель на кастомный хендл АЦП
@ -111,17 +124,13 @@ HAL_StatusTypeDef ADC_Start(ADC_Periodic_t *adc, float PeriodUs)
{ {
return res; return res;
} }
// Запускаем АЦП который будет перекидывать данные в ADC_DMA_Buffer // Запускаем АЦП который будет перекидывать данные в DMA буфер RawData
res = HAL_ADC_Start_DMA(adc->hadc, (uint32_t*)adc->RawData, 6); // Затем АЦП с DMA res = HAL_ADC_Start_DMA(adc->hadc, (uint32_t*)adc->RawData, 6);
if(res != HAL_OK) if(res != HAL_OK)
{ {
return res; return res;
} }
ADC_EnableAllFilters(adc);
Filter_Start(&adc->temp_map[0]);
Filter_Start(&adc->temp_map[1]);
return res; return res;
} }
/** /**
@ -139,6 +148,39 @@ HAL_StatusTypeDef ADC_Stop(ADC_Periodic_t *adc)
return HAL_TIM_Base_Stop(adc->htim); return HAL_TIM_Base_Stop(adc->htim);
} }
/**
* @brief Обновление напряжений АЦП.
* @return HAL Status.
*/
HAL_StatusTypeDef ADC_UpdateRegular(ADC_Periodic_t *adc)
{
if(assert_upp(adc))
return HAL_ERROR;
ADC_Coefs_t *coefs = adc->Coefs;
uint16_t *raw = adc->RawData;
float *data = adc->Data;
// Фильтрация от импульсных шумов каналов токов (напряжения позже фильтруются полосовым фильтром)
for(int i = 0; i < 2; i++)
{
int u_ind = ADC_U_CHANNELS_START + i;
int i_ind = ADC_I_CHANNELS_START + i;
// заменяем сырые данные на отфильтрованные данные
raw[u_ind] = Filter_Process(&adc->u_fltr[i], raw[u_ind]);
raw[i_ind] = Filter_Process(&adc->i_fltr[i], raw[i_ind]);
}
// Перерасчеты Напряжений/Токов в единицы измерения
for(int i = ADC_U_CHANNELS_START; i < ADC_NUMB_OF_REGULAR_CHANNELS; i++)
{
ADC_Coefs_t *coefs = &adc->Coefs[i];
data[i] = ((float)(raw[i])-coefs->lZero) * coefs->vMax / (coefs->lMax-coefs->lZero);
}
return HAL_OK;
}
/** /**
@ -153,55 +195,11 @@ HAL_StatusTypeDef ADC_UpdateTemperatures(ADC_Periodic_t *adc)
float *data = adc->Data; float *data = adc->Data;
uint16_t *raw = adc->RawData; uint16_t *raw = adc->RawData;
// Фильтрация от импульсных шумов для каналов напряжения/токов
for(int i = ADC_TEMP_CHANNELS_START; i < ADC_NUMB_OF_CHANNELS; i++)
{
// заменяем сырые данные на отфильтрованные данные
raw[i] = Filter_Process(&adc->filter[i], raw[i]);
}
// Преобразования температуры по таблице // Преобразования температуры по таблице
for (int i = ADC_TEMP_CHANNELS_START; i < ADC_NUMB_OF_CHANNELS; i++) for (int i = ADC_TEMP_CHANNELS_START; i < ADC_TEMP_CHANNELS_END; i++)
{ {
data[i] = Filter_Process(&adc->temp_map[i-ADC_TEMP_CHANNELS_START], raw[i]); data[i] = Filter_Process(&adc->temp_map[i-ADC_TEMP_CHANNELS_START], raw[i]);
} }
return HAL_OK; return HAL_OK;
} }
/**
* @brief Обработка АЦП.
* @return HAL Status.
* @note Вызывается в DMA2_Stream0_IRQHandler() для обработки напряжений/токов,
которые пришли по DMA.
*/
HAL_StatusTypeDef ADC_Handle(ADC_Periodic_t *adc)
{
if(assert_upp(adc))
return HAL_ERROR;
ADC_Coefs_t *coefs = adc->Coefs;
uint16_t *raw = adc->RawData;
float *data = adc->Data;
// Фильтрация от импульсных шумов для каналов напряжения/токов
for(int i = 0; i < ADC_NUMB_OF_CHANNELS; i++)
{
// заменяем сырые данные на отфильтрованные данные
raw[i] = Filter_Process(&adc->filter[i], raw[i]);
}
// Перерасчеты Напряжений/Токов в единицы измерения
for(int i = 0; i < ADC_NUMB_OF_REGULAR_CHANNELS; i++)
{
ADC_Coefs_t *coefs = &adc->Coefs[i];
data[i] = ((float)(raw[i])-coefs->lZero) * coefs->vMax / (coefs->lMax-coefs->lZero);
}
// if(Filter_isDataReady(&adc->filter[0]))
// adc->f.DataReady = 1;
return HAL_OK;
}

View File

@ -23,7 +23,14 @@
#define ADC_NUMB_OF_I_CHANNELS 2 #define ADC_NUMB_OF_I_CHANNELS 2
#define ADC_NUMB_OF_T_CHANNELS 2 #define ADC_NUMB_OF_T_CHANNELS 2
#define ADC_NUMB_OF_REGULAR_CHANNELS (ADC_NUMB_OF_U_CHANNELS+ADC_NUMB_OF_I_CHANNELS) #define ADC_NUMB_OF_REGULAR_CHANNELS (ADC_NUMB_OF_U_CHANNELS+ADC_NUMB_OF_I_CHANNELS)
#define ADC_TEMP_CHANNELS_START ADC_NUMB_OF_REGULAR_CHANNELS
#define ADC_U_CHANNELS_START 0
#define ADC_U_CHANNELS_END 1
#define ADC_I_CHANNELS_START 2
#define ADC_I_CHANNELS_END 3
#define ADC_TEMP_CHANNELS_START 4
#define ADC_TEMP_CHANNELS_END 5
#define ADC_TEMPERATURES_QUANTS \ #define ADC_TEMPERATURES_QUANTS \
{ 2188, 2197, 2206, 2216, 2226, 2236, 2247, 2259, 2271, 2283, \ { 2188, 2197, 2206, 2216, 2226, 2236, 2247, 2259, 2271, 2283, \
@ -51,10 +58,6 @@
static const float adc_temp_vals[] = ADC_TEMPERATURES; static const float adc_temp_vals[] = ADC_TEMPERATURES;
static const float adc_temp_quants[] = ADC_TEMPERATURES_QUANTS; static const float adc_temp_quants[] = ADC_TEMPERATURES_QUANTS;
#define Filter_t FilterMedianInt_t
#define Filter_Init FilterMedianInt_Init
#define Filter_Initializator 5, 2048
/** /**
* @brief Коэфициенты канала АЦП для пересчета в единицы измерения * @brief Коэфициенты канала АЦП для пересчета в единицы измерения
*/ */
@ -100,9 +103,9 @@ typedef struct
uint16_t RawData[ADC_NUMB_OF_CHANNELS]; ///< Сырые значения АЦП uint16_t RawData[ADC_NUMB_OF_CHANNELS]; ///< Сырые значения АЦП
ADC_Coefs_t Coefs[ADC_NUMB_OF_REGULAR_CHANNELS]; ///< Коэффициенты @ref ADC_Coefs_t для регулярных каналов (не температуры) ADC_Coefs_t Coefs[ADC_NUMB_OF_REGULAR_CHANNELS]; ///< Коэффициенты @ref ADC_Coefs_t для регулярных каналов (не температуры)
Filter_t filter[ADC_NUMB_OF_CHANNELS]; ///< Фильтр от шумов АЦП FilterBandPassDerivative_t u_fltr[ADC_NUMB_OF_U_CHANNELS]; ///< Полосовой Фильтр Напряжений от шумов
FilterMedianInt_t i_fltr[ADC_NUMB_OF_I_CHANNELS]; ///< Медианный Фильтр Токов от шумов
FilterLUT_t temp_map[2]; ///< Коррекция нелинейности датчиков температуры FilterLUT_t temp_map[ADC_NUMB_OF_T_CHANNELS]; ///< Коррекция нелинейности датчиков температуры
float Data[ADC_NUMB_OF_CHANNELS]; ///< Пересчитанные значения АЦП (в Вольтах/Амперах) float Data[ADC_NUMB_OF_CHANNELS]; ///< Пересчитанные значения АЦП (в Вольтах/Амперах)
@ -128,6 +131,6 @@ HAL_StatusTypeDef ADC_Stop(ADC_Periodic_t *adc);
/* Обновление температур АЦП. */ /* Обновление температур АЦП. */
HAL_StatusTypeDef ADC_UpdateTemperatures(ADC_Periodic_t *adc); HAL_StatusTypeDef ADC_UpdateTemperatures(ADC_Periodic_t *adc);
/* Обработка АЦП после получения данных. */ /* Обработка АЦП после получения данных. */
HAL_StatusTypeDef ADC_Handle(ADC_Periodic_t *adc); HAL_StatusTypeDef ADC_UpdateRegular(ADC_Periodic_t *adc);
#endif //_ADC_TOOLS_H_ #endif //_ADC_TOOLS_H_

View File

@ -125,6 +125,7 @@ void PowerMonitor_SlowCalc(PowerMonitor_t *hpm)
/* Расчет всякого для трех фаз отдельно */ /* Расчет всякого для трех фаз отдельно */
float fmean = 0; // средняя частота по трем фазам float fmean = 0; // средняя частота по трем фазам
float umean = 0; // средний напряжение по трем фазам
float imean = 0; // средний ток по трем фазам float imean = 0; // средний ток по трем фазам
float iphase_mean = 0; // средний ток каждой фазы float iphase_mean = 0; // средний ток каждой фазы
float uphase_mean = 0; // среднее напряжение каждой фазы float uphase_mean = 0; // среднее напряжение каждой фазы
@ -134,21 +135,15 @@ void PowerMonitor_SlowCalc(PowerMonitor_t *hpm)
for(int i = 0; i < 3; i++) for(int i = 0; i < 3; i++)
{ {
/* Получение частоты фазы */ /* Получение частоты фазы */
meas->final.F[i] = Filter_Process(&hpm->avg[AVG_FAB+i], ZC_GetFrequency(&hpm->zc, i)); meas->final.F[i] = Filter_Process(&hpm->avg[AVG_F+i], ZC_GetFrequency(&hpm->zc, i));
meas->final.Offset[i] = ZC_GetOffset(&hpm->zc, i); // meas->final.Offset[i] = ZC_GetOffset(&hpm->zc, i);
fmean += meas->final.F[i]; fmean += meas->final.F[i];
/* Средниее напряжение фазы */ /* Средниее напряжение фазы */
// uphase_mean = fabsf(meas->slow.U[i]);
// uphase_mean = Filter_Process(&hpm->rms[RMS_UAB+i], uphase_mean);
// meas->final.U[i] = uphase_mean*PI/2/SQRT2; /*PI/2 - получить амплитудное, SQRT2 - получить действующее */
uphase_mean = Filter_Process(&hpm->rms[RMS_U+i], meas->slow.U[i]); uphase_mean = Filter_Process(&hpm->rms[RMS_U+i], meas->slow.U[i]);
meas->final.U[i] = Filter_Process(&hpm->rms_exp[RMS_U+i], uphase_mean); meas->final.U[i] = Filter_Process(&hpm->rms_exp[RMS_U+i], uphase_mean);
/* Средний ток фазы */ /* Средний ток фазы */
// iphase_mean = fabsf(meas->slow.I[i]);
// iphase_mean = Filter_Process(&hpm->rms[RMS_IC+i], iphase_mean)*PI/2;
// meas->final.I[i] = iphase_mean*PI/2/SQRT2; /*PI/2 - получить амплитудное, SQRT2 - получить действующее */
iphase_mean = Filter_Process(&hpm->rms[RMS_I+i], meas->slow.I[i]); iphase_mean = Filter_Process(&hpm->rms[RMS_I+i], meas->slow.I[i]);
meas->final.I[i] = Filter_Process(&hpm->rms_exp[RMS_I+i], iphase_mean); meas->final.I[i] = Filter_Process(&hpm->rms_exp[RMS_I+i], iphase_mean);
imean += meas->final.I[i]; imean += meas->final.I[i];
@ -159,23 +154,24 @@ void PowerMonitor_SlowCalc(PowerMonitor_t *hpm)
} }
/* Получение средней частоты по трем фазам */ /* Получение средней частоты по трем фазам */
meas->final.Fmean = fmean / 3; meas->final.Fmean = fmean / 3;
/* Оределение сдвига фаз */ // /* Оределение сдвига фаз */
static uint32_t prev_tick_phase_a = 0; // static uint32_t prev_tick_phase_a = 0;
if(prev_tick_phase_a != hpm->zc.Channel[0].PeriodStartTime) // if(prev_tick_phase_a != hpm->zc.Channel[0].PeriodStartTime)
{ // Определяем только когда начался новый период фазы A // { // Определяем только когда начался новый период фазы A
prev_tick_phase_a = hpm->zc.Channel[0].PeriodStartTime; // prev_tick_phase_a = hpm->zc.Channel[0].PeriodStartTime;
meas->final.Phase[0] = 0; // meas->final.Phase[0] = 0;
meas->final.Phase[1] = ZC_GetPhaseShift(&hpm->zc, 0, 1); // meas->final.Phase[1] = ZC_GetPhaseShift(&hpm->zc, 0, 1);
meas->final.Phase[2] = ZC_GetPhaseShift(&hpm->zc, 0, 2); // meas->final.Phase[2] = ZC_GetPhaseShift(&hpm->zc, 0, 2);
} // }
/* Расчет амплитуд трехфазной сети */ /* Расчет амплитуд трехфазной сети */
float uamp = vector_abs_linear_calc(meas->slow.U[U_AB], meas->slow.U[U_CA])/SQRT2; /* SQRT2 - получить действующее */ // float uamp = vector_abs_linear_calc(meas->slow.U[U_AB], meas->slow.U[U_CA])/SQRT2; /* SQRT2 - получить действующее */
// float iamp = vector_abs_phase_calc(meas->slow.I[I_A], meas->slow.I[I_C]); // float iamp = vector_abs_phase_calc(meas->slow.I[I_A], meas->slow.I[I_C]);
float uamp = umean / 3;
float iamp = imean / 3; float iamp = imean / 3;
meas->final.Uamp = Filter_Process(&hpm->rms_exp[RMS_EXP_U], uamp); meas->final.Uamp = uamp;//Filter_Process(&hpm->rms_exp[RMS_EXP_U], uamp);
meas->final.Iamp = Filter_Process(&hpm->rms_exp[RMS_EXP_I], iamp); meas->final.Iamp = iamp;//Filter_Process(&hpm->rms_exp[RMS_EXP_I], iamp);
hpm->slow_cnt++; hpm->slow_cnt++;
@ -197,7 +193,7 @@ void PowerMonitor_FastCalc(PowerMonitor_t *hpm)
PowerMonitor_Measured_t *meas = &hpm->measured; PowerMonitor_Measured_t *meas = &hpm->measured;
/* Считываем АЦП с пересчетами и медианой фильтрацией от выбросов */ /* Считываем АЦП с пересчетами и медианой фильтрацией от выбросов */
ADC_Handle(&hpm->adc); ADC_UpdateRegular(&hpm->adc);
/* Заполняем Напряжения/Токи в о.е. */ /* Заполняем Напряжения/Токи в о.е. */
float uba_fast = hpm->adc.Data[ADC_CHANNEL_UBA]/u_base; float uba_fast = hpm->adc.Data[ADC_CHANNEL_UBA]/u_base;

View File

@ -103,6 +103,7 @@ void ZC_ProcessChannel(ZeroCross_Handle_t *zc, uint8_t channel, float value, uin
zc_ch->CurrentValue = value; zc_ch->CurrentValue = value;
#ifndef ZC_DISABLE_HYSTERESIS_DEBOUNCE
// Фильтрация дребезга // Фильтрация дребезга
if(zc_ch->DebounceCounter > 0) if(zc_ch->DebounceCounter > 0)
{ {
@ -144,6 +145,25 @@ void ZC_ProcessChannel(ZeroCross_Handle_t *zc, uint8_t channel, float value, uin
zc_detected = -1; zc_detected = -1;
} }
} }
#else //ZC_DISABLE_HYSTERESIS_DEBOUNCE
// Детектирование rising edge (отрицательное -> положительное)
if ((zc_ch->LastValue < 0) &&
(value > 0))
{
if (zc_ch->EdgeType == ZC_RISING_EDGE || zc_ch->EdgeType == ZC_BOTH_EDGES) {
zc_detected = 1;
}
}
// Детектирование falling edge (положительное -> отрицательное)
else if ((zc_ch->LastValue > 0) &&
(value < 0))
{
if (zc_ch->EdgeType == ZC_FALLING_EDGE || zc_ch->EdgeType == ZC_BOTH_EDGES) {
zc_detected = -1;
}
}
#endif //ZC_DISABLE_HYSTERESIS_DEBOUNCE
if(zc_detected) if(zc_detected)
{ {
@ -172,11 +192,15 @@ void ZC_ProcessChannel(ZeroCross_Handle_t *zc, uint8_t channel, float value, uin
zc_ch->CrossCount++; zc_ch->CrossCount++;
} }
#ifndef ZC_DISABLE_HYSTERESIS_DEBOUNCE
// Сохраняем текущее значение для следующей итерации в случае если оно не в мертвой зоне // Сохраняем текущее значение для следующей итерации в случае если оно не в мертвой зоне
if((value > zc->Config.Hysteresis) || (value < -zc->Config.Hysteresis)) if((value > zc->Config.Hysteresis) || (value < -zc->Config.Hysteresis))
{ {
zc_ch->LastValue = value; zc_ch->LastValue = value;
} }
#else //ZC_DISABLE_HYSTERESIS_DEBOUNCE
zc_ch->LastValue = value;
#endif //ZC_DISABLE_HYSTERESIS_DEBOUNCE
} }
/** /**

View File

@ -323,37 +323,37 @@ static HAL_StatusTypeDef __PWM_SetOutputState(PWM_Channel_t *hCh, uint32_t state
if (hCh->htim == NULL) if (hCh->htim == NULL)
return HAL_ERROR; return HAL_ERROR;
uint32_t ch_mode = state; // Если режим уже выставлен
if(hCh->CurrentMode == state)
{
return HAL_OK;
}
hCh->CurrentMode = state;
// выставляем режим каналов // выставляем режим каналов
switch(hCh->ChMask) switch(hCh->ChMask)
{ {
case TIM_CHANNEL_1: case TIM_CHANNEL_1:
hCh->htim->Instance->CCMR1 &= ~TIM_OCMODE_PWM2; hCh->htim->Instance->CCMR1 &= ~TIM_OCMODE_PWM2;
hCh->htim->Instance->CCMR1 |= ch_mode; hCh->htim->Instance->CCMR1 |= state;
break; break;
case TIM_CHANNEL_2: case TIM_CHANNEL_2:
hCh->htim->Instance->CCMR1 &= ~(TIM_OCMODE_PWM2 << 8); hCh->htim->Instance->CCMR1 &= ~(TIM_OCMODE_PWM2 << 8);
hCh->htim->Instance->CCMR1 |= (ch_mode << 8); hCh->htim->Instance->CCMR1 |= (state << 8);
break; break;
case TIM_CHANNEL_3: case TIM_CHANNEL_3:
hCh->htim->Instance->CCMR2 &= ~TIM_OCMODE_PWM2; hCh->htim->Instance->CCMR2 &= ~TIM_OCMODE_PWM2;
hCh->htim->Instance->CCMR2 |= ch_mode; hCh->htim->Instance->CCMR2 |= state;
break; break;
case TIM_CHANNEL_4: case TIM_CHANNEL_4:
hCh->htim->Instance->CCMR2 &= ~(TIM_OCMODE_PWM2 << 8); hCh->htim->Instance->CCMR2 &= ~(TIM_OCMODE_PWM2 << 8);
hCh->htim->Instance->CCMR2 |= (ch_mode << 8); hCh->htim->Instance->CCMR2 |= (state << 8);
break; break;
default: default:
break; break;
} }
// в последнюю очередь включаем выход. Перед этим настраиваем каналы на ШИМ
if(state == PWM_ENABLE)
{
__HAL_TIM_MOE_ENABLE(hCh->htim);
}
return HAL_OK; return HAL_OK;
} }

View File

@ -54,6 +54,7 @@ typedef struct {
TIM_HandleTypeDef *htim; ///< указатель на соответствующий TIM (hpwm1 или hpwm2) TIM_HandleTypeDef *htim; ///< указатель на соответствующий TIM (hpwm1 или hpwm2)
uint32_t PulseCnt; ///< Счетчик кол-ва импульсов. Инициализируется из структуры @ref PWM_ThyrConfig_t uint32_t PulseCnt; ///< Счетчик кол-ва импульсов. Инициализируется из структуры @ref PWM_ThyrConfig_t
uint32_t ChMask; ///< TIM_CHANNEL_x uint32_t ChMask; ///< TIM_CHANNEL_x
uint32_t CurrentMode; ///< Текущий режим канала
struct { struct {
unsigned Ready:1; ///< Флаг готовности тиристора к работе unsigned Ready:1; ///< Флаг готовности тиристора к работе

View File

@ -175,6 +175,9 @@ int UPP_While(void)
/*======= Состояние В работе =========*/ /*======= Состояние В работе =========*/
case UPP_Work: case UPP_Work:
// Разрешаем выход ШИМ
__HAL_TIM_MOE_ENABLE(&hpwm1);
__HAL_TIM_MOE_ENABLE(&hpwm2);
// Индикация // Индикация
UPP_DO.Ready(DISABLE); UPP_DO.Ready(DISABLE);
UPP_DO.Work(ENABLE); UPP_DO.Work(ENABLE);

View File

@ -385,7 +385,7 @@
<Ww> <Ww>
<count>11</count> <count>11</count>
<WinNumber>1</WinNumber> <WinNumber>1</WinNumber>
<ItemText>\\Debug_F417\../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c\uwTick</ItemText> <ItemText>\\Debug_F417\../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c\uwTick,0x0A</ItemText>
</Ww> </Ww>
<Ww> <Ww>
<count>12</count> <count>12</count>
@ -494,6 +494,21 @@
<WinNumber>2</WinNumber> <WinNumber>2</WinNumber>
<ItemText>upp,0x0A</ItemText> <ItemText>upp,0x0A</ItemText>
</Ww> </Ww>
<Ww>
<count>14</count>
<WinNumber>2</WinNumber>
<ItemText>htim5,0x0A</ItemText>
</Ww>
<Ww>
<count>15</count>
<WinNumber>2</WinNumber>
<ItemText>htim3,0x0A</ItemText>
</Ww>
<Ww>
<count>16</count>
<WinNumber>2</WinNumber>
<ItemText>htim5.Instance-&gt;CNT-2605346416,0x0A</ItemText>
</Ww>
</WatchWindow2> </WatchWindow2>
<Tracepoint> <Tracepoint>
<THDelay>0</THDelay> <THDelay>0</THDelay>
@ -515,7 +530,7 @@
<AscS3>0</AscS3> <AscS3>0</AscS3>
<aSer3>0</aSer3> <aSer3>0</aSer3>
<eProf>0</eProf> <eProf>0</eProf>
<aLa>1</aLa> <aLa>0</aLa>
<aPa1>0</aPa1> <aPa1>0</aPa1>
<AscS4>0</AscS4> <AscS4>0</AscS4>
<aSer4>0</aSer4> <aSer4>0</aSer4>