diff --git a/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_tim.c b/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_tim.c
index 46b9f21..c8210a1 100644
--- a/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_tim.c
+++ b/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_tim.c
@@ -91,167 +91,215 @@ void Channels_Simulation(TIM_TypeDef* TIMx, struct TIM_Sim* TIMS)
/* Выбор режима CaptureCompare или PWM и симуляция для каждого канала */
void CC_PWM_Ch1_Simulation(TIM_TypeDef *TIMx, struct TIM_Sim *TIMS)
{ // определяет режим канала
-switch (TIMx->CCMR1 & TIM_CCMR1_OC1M)
-{
- case (TIM_OCMODE_ACTIVE): // ACTIVE mode
- if (abs(TIMx->CNT - TIMx->CCR1) < 2*TIMS->tx_step)
- TIMS->Channels.OC1REF = 1;
- break;
+ switch (TIMx->CCMR1 & TIM_CCMR1_OC1M)
+ {
+ case (TIM_OCMODE_ACTIVE): // ACTIVE mode
+ if (abs(TIMx->CNT - TIMx->CCR1) < 2*TIMS->tx_step)
+ TIMS->Channels.OC1REF = 1;
+ break;
- case (TIM_OCMODE_INACTIVE): // INACTIVE mode
- if (abs(TIMx->CNT - TIMx->CCR1) < 2*TIMS->tx_step)
- TIMS->Channels.OC1REF = 0;
- break;
+ case (TIM_OCMODE_INACTIVE): // INACTIVE mode
+ if (abs(TIMx->CNT - TIMx->CCR1) < 2*TIMS->tx_step)
+ TIMS->Channels.OC1REF = 0;
+ break;
- case (TIM_OCMODE_TOGGLE): // TOOGLE mode
- if (abs(TIMx->CNT - TIMx->CCR1) < 2*TIMS->tx_step)
- TIMS->Channels.OC1REF = ~TIMS->Channels.OC1REF;
- break;
+ case (TIM_OCMODE_TOGGLE): // TOOGLE mode
+ if (abs(TIMx->CNT - TIMx->CCR1) < 2*TIMS->tx_step)
+ TIMS->Channels.OC1REF = ~TIMS->Channels.OC1REF;
+ break;
- case (TIM_OCMODE_PWM1): // PWM MODE 1 mode
- if (TIMx->CNT < TIMx->CCR1)
- TIMS->Channels.OC1REF = 1;
- else
- TIMS->Channels.OC1REF = 0;
- break;
+ case (TIM_OCMODE_PWM1): // PWM MODE 1 mode
+ if (TIMx->CNT < TIMx->CCR1)
+ TIMS->Channels.OC1REF = 1;
+ else
+ TIMS->Channels.OC1REF = 0;
+ break;
- case (TIM_OCMODE_PWM2): // PWM MODE 2 mode
- if (TIMx->CNT < TIMx->CCR1)
- TIMS->Channels.OC1REF = 0;
- else
- TIMS->Channels.OC1REF = 1;
- break;
+ case (TIM_OCMODE_PWM2): // PWM MODE 2 mode
+ if (TIMx->CNT < TIMx->CCR1)
+ TIMS->Channels.OC1REF = 0;
+ else
+ TIMS->Channels.OC1REF = 1;
+ break;
- case (TIM_OCMODE_FORCED_ACTIVE): // FORCED ACTIVE mode
- TIMS->Channels.OC1REF = 1; break;
+ case (TIM_OCMODE_FORCED_ACTIVE): // FORCED ACTIVE mode
+ TIMS->Channels.OC1REF = 1; break;
- case (TIM_OCMODE_FORCED_INACTIVE): // FORCED INACTIVE mode
- TIMS->Channels.OC1REF = 0; break;
+ case (TIM_OCMODE_FORCED_INACTIVE): // FORCED INACTIVE mode
+ TIMS->Channels.OC1REF = 0; break;
-}
+ }
+ if (TIMx->DIER & TIM_IT_CC1)
+ {
+ TIMx->SR |= TIM_SR_CC1IF;
+ if (((TIMS->tx_cnt - TIMS->tx_step) < TIMx->CCR1) && (TIMS->tx_cnt >= TIMx->CCR1))
+ {
+ TIM_Call_IRQHandller(TIMx);
+ }
+ else if (((TIMS->tx_cnt - TIMS->tx_step) > TIMx->CCR1) && (TIMS->tx_cnt <= TIMx->CCR1))
+ {
+ TIM_Call_IRQHandller(TIMx);
+ }
+ }
}
void CC_PWM_Ch2_Simulation(TIM_TypeDef *TIMx, struct TIM_Sim *TIMS)
{ // определяет режим канала
-switch (TIMx->CCMR1 & TIM_CCMR1_OC2M)
-{
- case ((TIM_OCMODE_ACTIVE) << (TIM_OCMODE_SECOND_SHIFT)): // ACTIVE mode
- if (abs(TIMx->CNT - TIMx->CCR2) < 2*TIMS->tx_step)
- TIMS->Channels.OC2REF = 1;
- break;
+ switch (TIMx->CCMR1 & TIM_CCMR1_OC2M)
+ {
+ case ((TIM_OCMODE_ACTIVE) << (TIM_OCMODE_SECOND_SHIFT)): // ACTIVE mode
+ if (abs(TIMx->CNT - TIMx->CCR2) < 2*TIMS->tx_step)
+ TIMS->Channels.OC2REF = 1;
+ break;
- case ((TIM_OCMODE_INACTIVE) << (TIM_OCMODE_SECOND_SHIFT)): // INACTIVE mode
- if (abs(TIMx->CNT - TIMx->CCR2) < 2*TIMS->tx_step)
- TIMS->Channels.OC2REF = 0;
- break;
+ case ((TIM_OCMODE_INACTIVE) << (TIM_OCMODE_SECOND_SHIFT)): // INACTIVE mode
+ if (abs(TIMx->CNT - TIMx->CCR2) < 2*TIMS->tx_step)
+ TIMS->Channels.OC2REF = 0;
+ break;
- case ((TIM_OCMODE_TOGGLE) << (TIM_OCMODE_SECOND_SHIFT)): // Toogle mode
- if (abs(TIMx->CNT - TIMx->CCR2) < 2*TIMS->tx_step)
- TIMS->Channels.OC2REF = ~TIMS->Channels.OC2REF;
- break;
+ case ((TIM_OCMODE_TOGGLE) << (TIM_OCMODE_SECOND_SHIFT)): // Toogle mode
+ if (abs(TIMx->CNT - TIMx->CCR2) < 2*TIMS->tx_step)
+ TIMS->Channels.OC2REF = ~TIMS->Channels.OC2REF;
+ break;
- case ((TIM_OCMODE_PWM1) << (TIM_OCMODE_SECOND_SHIFT)): // PWM mode 1 mode
- if (TIMx->CNT < TIMx->CCR2)
- TIMS->Channels.OC2REF = 1;
- else
- TIMS->Channels.OC2REF = 0;
- break;
+ case ((TIM_OCMODE_PWM1) << (TIM_OCMODE_SECOND_SHIFT)): // PWM mode 1 mode
+ if (TIMx->CNT < TIMx->CCR2)
+ TIMS->Channels.OC2REF = 1;
+ else
+ TIMS->Channels.OC2REF = 0;
+ break;
- case ((TIM_OCMODE_PWM2) << (TIM_OCMODE_SECOND_SHIFT)): // PWM mode 2 mode
- if (TIMx->CNT < TIMx->CCR2)
- TIMS->Channels.OC2REF = 0;
- else
- TIMS->Channels.OC2REF = 1;
- break;
+ case ((TIM_OCMODE_PWM2) << (TIM_OCMODE_SECOND_SHIFT)): // PWM mode 2 mode
+ if (TIMx->CNT < TIMx->CCR2)
+ TIMS->Channels.OC2REF = 0;
+ else
+ TIMS->Channels.OC2REF = 1;
+ break;
- case ((TIM_OCMODE_FORCED_ACTIVE) << (TIM_OCMODE_SECOND_SHIFT)): // FORCED ACTIVE mode
- TIMS->Channels.OC2REF = 1; break;
+ case ((TIM_OCMODE_FORCED_ACTIVE) << (TIM_OCMODE_SECOND_SHIFT)): // FORCED ACTIVE mode
+ TIMS->Channels.OC2REF = 1; break;
- case ((TIM_OCMODE_FORCED_INACTIVE) << (TIM_OCMODE_SECOND_SHIFT)): // FORCED INACTIVE mode
- TIMS->Channels.OC2REF = 0; break;
+ case ((TIM_OCMODE_FORCED_INACTIVE) << (TIM_OCMODE_SECOND_SHIFT)): // FORCED INACTIVE mode
+ TIMS->Channels.OC2REF = 0; break;
-}
+ }
+ if (TIMx->DIER & TIM_IT_CC2)
+ {
+ TIMx->SR |= TIM_SR_CC2IF;
+ if (((TIMS->tx_cnt - TIMS->tx_step) < TIMx->CCR2) && (TIMS->tx_cnt >= TIMx->CCR2))
+ {
+ TIM_Call_IRQHandller(TIMx);
+ }
+ else if (((TIMS->tx_cnt - TIMS->tx_step) > TIMx->CCR2) && (TIMS->tx_cnt <= TIMx->CCR2))
+ {
+ TIM_Call_IRQHandller(TIMx);
+ }
+ }
}
void CC_PWM_Ch3_Simulation(TIM_TypeDef *TIMx, struct TIM_Sim *TIMS)
{ // определяет режим канала
-switch (TIMx->CCMR2 & TIM_CCMR1_OC1M)
-{
- case (TIM_OCMODE_ACTIVE): // ACTIVE mode
- if (abs(TIMx->CNT - TIMx->CCR3) < 2*TIMS->tx_step)
- TIMS->Channels.OC3REF = 1;
- break;
+ switch (TIMx->CCMR2 & TIM_CCMR1_OC1M)
+ {
+ case (TIM_OCMODE_ACTIVE): // ACTIVE mode
+ if (abs(TIMx->CNT - TIMx->CCR3) < 2*TIMS->tx_step)
+ TIMS->Channels.OC3REF = 1;
+ break;
- case (TIM_OCMODE_INACTIVE): // INACTIVE mode
- if (abs(TIMx->CNT - TIMx->CCR3) < 2*TIMS->tx_step)
- TIMS->Channels.OC3REF = 0;
- break;
+ case (TIM_OCMODE_INACTIVE): // INACTIVE mode
+ if (abs(TIMx->CNT - TIMx->CCR3) < 2*TIMS->tx_step)
+ TIMS->Channels.OC3REF = 0;
+ break;
- case (TIM_OCMODE_TOGGLE): // Toogle mode
- if (abs(TIMx->CNT - TIMx->CCR3) < 2*TIMS->tx_step)
- TIMS->Channels.OC3REF = ~TIMS->Channels.OC3REF;
- break;
+ case (TIM_OCMODE_TOGGLE): // Toogle mode
+ if (abs(TIMx->CNT - TIMx->CCR3) < 2*TIMS->tx_step)
+ TIMS->Channels.OC3REF = ~TIMS->Channels.OC3REF;
+ break;
- case (TIM_OCMODE_PWM1): // PWM mode 1 mode
- if (TIMx->CNT < TIMx->CCR3)
- TIMS->Channels.OC3REF = 1;
- else
- TIMS->Channels.OC3REF = 0;
- break;
+ case (TIM_OCMODE_PWM1): // PWM mode 1 mode
+ if (TIMx->CNT < TIMx->CCR3)
+ TIMS->Channels.OC3REF = 1;
+ else
+ TIMS->Channels.OC3REF = 0;
+ break;
- case (TIM_OCMODE_PWM2): // PWM mode 2 mode
- if (TIMx->CNT < TIMx->CCR3)
- TIMS->Channels.OC3REF = 0;
- else
- TIMS->Channels.OC3REF = 1;
- break;
+ case (TIM_OCMODE_PWM2): // PWM mode 2 mode
+ if (TIMx->CNT < TIMx->CCR3)
+ TIMS->Channels.OC3REF = 0;
+ else
+ TIMS->Channels.OC3REF = 1;
+ break;
- case (TIM_OCMODE_FORCED_ACTIVE): // FORCED ACTIVE mode
- TIMS->Channels.OC3REF = 1; break;
+ case (TIM_OCMODE_FORCED_ACTIVE): // FORCED ACTIVE mode
+ TIMS->Channels.OC3REF = 1; break;
- case (TIM_OCMODE_FORCED_INACTIVE): // FORCED INACTIVE mode
- TIMS->Channels.OC3REF = 0; break;
+ case (TIM_OCMODE_FORCED_INACTIVE): // FORCED INACTIVE mode
+ TIMS->Channels.OC3REF = 0; break;
-}
+ }
+ if (TIMx->DIER & TIM_IT_CC3)
+ {
+ TIMx->SR |= TIM_SR_CC3IF;
+ if (((TIMS->tx_cnt - TIMS->tx_step) < TIMx->CCR3) && (TIMS->tx_cnt >= TIMx->CCR3))
+ {
+ TIM_Call_IRQHandller(TIMx);
+ }
+ else if (((TIMS->tx_cnt - TIMS->tx_step) > TIMx->CCR3) && (TIMS->tx_cnt <= TIMx->CCR3))
+ {
+ TIM_Call_IRQHandller(TIMx);
+ }
+ }
}
void CC_PWM_Ch4_Simulation(TIM_TypeDef *TIMx, struct TIM_Sim *TIMS)
{ // определяет режим канала
-switch (TIMx->CCMR1 & TIM_CCMR1_OC2M)
-{
- case ((TIM_OCMODE_ACTIVE) << (TIM_OCMODE_SECOND_SHIFT)): // ACTIVE mode
- if (abs(TIMx->CNT - TIMx->CCR4) < 2*TIMS->tx_step)
- TIMS->Channels.OC4REF = 1;
- break;
+ switch (TIMx->CCMR1 & TIM_CCMR1_OC2M)
+ {
+ case ((TIM_OCMODE_ACTIVE) << (TIM_OCMODE_SECOND_SHIFT)): // ACTIVE mode
+ if (abs(TIMx->CNT - TIMx->CCR4) < 2*TIMS->tx_step)
+ TIMS->Channels.OC4REF = 1;
+ break;
- case ((TIM_OCMODE_INACTIVE) << (TIM_OCMODE_SECOND_SHIFT)): // INACTIVE mode
- if (abs(TIMx->CNT - TIMx->CCR4) < 2*TIMS->tx_step)
- TIMS->Channels.OC4REF = 0;
- break;
+ case ((TIM_OCMODE_INACTIVE) << (TIM_OCMODE_SECOND_SHIFT)): // INACTIVE mode
+ if (abs(TIMx->CNT - TIMx->CCR4) < 2*TIMS->tx_step)
+ TIMS->Channels.OC4REF = 0;
+ break;
- case ((TIM_OCMODE_TOGGLE) << (TIM_OCMODE_SECOND_SHIFT)): // Toogle mode
- if (abs(TIMx->CNT - TIMx->CCR4) < 2*TIMS->tx_step)
- TIMS->Channels.OC4REF = ~TIMS->Channels.OC4REF;
- break;
+ case ((TIM_OCMODE_TOGGLE) << (TIM_OCMODE_SECOND_SHIFT)): // Toogle mode
+ if (abs(TIMx->CNT - TIMx->CCR4) < 2*TIMS->tx_step)
+ TIMS->Channels.OC4REF = ~TIMS->Channels.OC4REF;
+ break;
- case ((TIM_OCMODE_PWM1) << (TIM_OCMODE_SECOND_SHIFT)): // PWM mode 1 mode
- if (TIMx->CNT < TIMx->CCR4)
- TIMS->Channels.OC4REF = 1;
- else
- TIMS->Channels.OC4REF = 0;
- break;
+ case ((TIM_OCMODE_PWM1) << (TIM_OCMODE_SECOND_SHIFT)): // PWM mode 1 mode
+ if (TIMx->CNT < TIMx->CCR4)
+ TIMS->Channels.OC4REF = 1;
+ else
+ TIMS->Channels.OC4REF = 0;
+ break;
- case ((TIM_OCMODE_PWM2) << (TIM_OCMODE_SECOND_SHIFT)): // PWM mode 2 mode
- if (TIMx->CNT < TIMx->CCR4)
- TIMS->Channels.OC4REF = 0;
- else
- TIMS->Channels.OC4REF = 1;
- break;
+ case ((TIM_OCMODE_PWM2) << (TIM_OCMODE_SECOND_SHIFT)): // PWM mode 2 mode
+ if (TIMx->CNT < TIMx->CCR4)
+ TIMS->Channels.OC4REF = 0;
+ else
+ TIMS->Channels.OC4REF = 1;
+ break;
- case ((TIM_OCMODE_FORCED_ACTIVE) << (TIM_OCMODE_SECOND_SHIFT)): // FORCED ACTIVE mode
- TIMS->Channels.OC4REF = 1; break;
+ case ((TIM_OCMODE_FORCED_ACTIVE) << (TIM_OCMODE_SECOND_SHIFT)): // FORCED ACTIVE mode
+ TIMS->Channels.OC4REF = 1; break;
- case ((TIM_OCMODE_FORCED_INACTIVE) << (TIM_OCMODE_SECOND_SHIFT)): // FORCED INACTIVE mode
- TIMS->Channels.OC4REF = 0; break;
+ case ((TIM_OCMODE_FORCED_INACTIVE) << (TIM_OCMODE_SECOND_SHIFT)): // FORCED INACTIVE mode
+ TIMS->Channels.OC4REF = 0; break;
-}
+ }
+ if (TIMx->DIER & TIM_IT_CC4)
+ {
+ TIMx->SR |= TIM_SR_CC4IF;
+ if (((TIMS->tx_cnt - TIMS->tx_step) < TIMx->CCR4) && (TIMS->tx_cnt >= TIMx->CCR4))
+ {
+ TIM_Call_IRQHandller(TIMx);
+ }
+ else if (((TIMS->tx_cnt - TIMS->tx_step) > TIMx->CCR4) && (TIMS->tx_cnt <= TIMx->CCR4))
+ {
+ TIM_Call_IRQHandller(TIMx);
+ }
+ }
}
/* Запись каналов таймера в порты GPIO */
void Write_OC_to_GPIO(TIM_TypeDef *TIMx, struct TIM_Sim *TIMS)
@@ -565,70 +613,68 @@ void TIM_SIM_DEINIT(void)
// Т.к. в MSVC нет понятия weak function, необходимо объявить все колбеки
// И если какой-то колбек не используется, его надо определить
//#ifndef USE_TIM1_UP_TIM10_HANDLER
-//void TIM1_UP_TIM10_IRQHandler(void) {}
+__weak void TIM1_UP_TIM10_IRQHandler(void) {}
//#endif
//#ifndef USE_TIM2_HANDLER
-//void TIM2_IRQHandler(void) {}
+__weak void TIM2_IRQHandler(void) {}
//#endif
//#ifndef USE_TIM3_HANDLER
-//void TIM3_IRQHandler(void) {}
+__weak void TIM3_IRQHandler(void) {}
//#endif
//#ifndef USE_TIM4_HANDLER
-//void TIM4_IRQHandler(void) {}
+__weak void TIM4_IRQHandler(void) {}
//#endif
//#ifndef USE_TIM5_HANDLER
-//void TIM5_IRQHandler(void) {}
+__weak void TIM5_IRQHandler(void) {}
//#endif
//#ifndef USE_TIM6_HANDLER
-//void TIM6_DAC_IRQHandler(void) {}
+__weak void TIM6_DAC_IRQHandler(void) {}
//#endif
//#ifndef USE_TIM7_HANDLER
-//void TIM7_IRQHandler(void) {}
+__weak void TIM7_IRQHandler(void) {}
//#endif
//#ifndef USE_TIM8_UP_TIM13_HANDLER
-//void TIM8_UP_TIM13_IRQHandler(void) {}
+__weak void TIM8_UP_TIM13_IRQHandler(void) {}
//#endif
//#ifndef USE_TIM1_BRK_TIM9_HANDLER
-//void TIM1_BRK_TIM9_IRQHandler(void) {}
+__weak void TIM1_BRK_TIM9_IRQHandler(void) {}
//#endif
//#ifndef USE_TIM1_TRG_COM_TIM11_HANDLER
-//void TIM1_TRG_COM_TIM11_IRQHandler(void) {}
+__weak void TIM1_TRG_COM_TIM11_IRQHandler(void) {}
//#endif
//#ifndef USE_TIM8_BRK_TIM12_HANDLER
-//void TIM8_BRK_TIM12_IRQHandler(void) {}
+__weak void TIM8_BRK_TIM12_IRQHandler(void) {}
//#endif
//#ifndef USE_TIM8_TRG_COM_TIM14_HANDLER
-//void TIM8_TRG_COM_TIM14_IRQHandler(void) {}
+__weak void TIM8_TRG_COM_TIM14_IRQHandler(void) {}
//#endif
/* Вызов прерывания */
void TIM_Call_IRQHandller(TIM_TypeDef* TIMx)
{ // calling HANDLER
- //if (TIMx == TIM1)
- // TIM1_UP_IRQHandler();
- //if ((TIMx == TIM1) || (TIMx == TIM10))
- // TIM1_UP_TIM10_IRQHandler();
- //else if (TIMx == TIM2)
- // TIM2_IRQHandler();
- //else if (TIMx == TIM3)
- // TIM3_IRQHandler();
- //else if (TIMx == TIM4)
- // TIM4_IRQHandler();
- //else if (TIMx == TIM5)
- // TIM5_IRQHandler();
- //else if (TIMx == TIM6)
- // TIM6_DAC_IRQHandler();
- //else if (TIMx == TIM7)
- // TIM7_IRQHandler();
- //else if ((TIMx == TIM8) || (TIMx == TIM13))
- // TIM8_UP_TIM13_IRQHandler();
- //else if ((TIMx == TIM1) || (TIMx == TIM9))
- // TIM1_BRK_TIM9_IRQHandler();
- //else if ((TIMx == TIM1) || (TIMx == TIM11))
- // TIM1_TRG_COM_TIM11_IRQHandler();
- //else if ((TIMx == TIM8) || (TIMx == TIM12))
- // TIM8_BRK_TIM12_IRQHandler();
- //else if ((TIMx == TIM8) || (TIMx == TIM14))
- // TIM8_TRG_COM_TIM14_IRQHandler();
+ if ((TIMx == TIM1) || (TIMx == TIM10))
+ TIM1_UP_TIM10_IRQHandler();
+ else if (TIMx == TIM2)
+ TIM2_IRQHandler();
+ else if (TIMx == TIM3)
+ TIM3_IRQHandler();
+ else if (TIMx == TIM4)
+ TIM4_IRQHandler();
+ else if (TIMx == TIM5)
+ TIM5_IRQHandler();
+ else if (TIMx == TIM6)
+ TIM6_DAC_IRQHandler();
+ else if (TIMx == TIM7)
+ TIM7_IRQHandler();
+ else if ((TIMx == TIM8) || (TIMx == TIM13))
+ TIM8_UP_TIM13_IRQHandler();
+ else if ((TIMx == TIM1) || (TIMx == TIM9))
+ TIM1_BRK_TIM9_IRQHandler();
+ else if ((TIMx == TIM1) || (TIMx == TIM11))
+ TIM1_TRG_COM_TIM11_IRQHandler();
+ else if ((TIMx == TIM8) || (TIMx == TIM12))
+ TIM8_BRK_TIM12_IRQHandler();
+ else if ((TIMx == TIM8) || (TIMx == TIM14))
+ TIM8_TRG_COM_TIM14_IRQHandler();
}
//------------------------------------------------------------------//
diff --git a/MATLAB/app_wrapper/app_includes.h b/MATLAB/app_wrapper/app_includes.h
index 7f49c25..785ac41 100644
--- a/MATLAB/app_wrapper/app_includes.h
+++ b/MATLAB/app_wrapper/app_includes.h
@@ -14,8 +14,6 @@
#include "tim.h"
#include "adc.h"
#include "upp_main.h"
-#include "adc_tools.h"
-#include "power_monitor.h"
// INCLUDES END
#endif //_APP_INCLUDES_H_
\ No newline at end of file
diff --git a/MATLAB/app_wrapper/app_init.c b/MATLAB/app_wrapper/app_init.c
index 176d679..705b1e2 100644
--- a/MATLAB/app_wrapper/app_init.c
+++ b/MATLAB/app_wrapper/app_init.c
@@ -19,6 +19,7 @@ void app_init(void) {
HAL_Init();
MX_DMA_Init();
MX_TIM1_Init();
+ MX_TIM2_Init();
MX_TIM3_Init();
MX_TIM8_Init();
MX_TIM5_Init();
diff --git a/MATLAB/app_wrapper/app_io.c b/MATLAB/app_wrapper/app_io.c
index f8400cd..8b6e497 100644
--- a/MATLAB/app_wrapper/app_io.c
+++ b/MATLAB/app_wrapper/app_io.c
@@ -31,23 +31,23 @@ void Write_PowerMonitor(real_T* Buffer, int ind_port)
int nn = 0;
for (int i = 0; i < 3; i++)
{
- WriteOutputArray(pm.U[i], ind_port, nn++);
+ WriteOutputArray(upp.pm.U[i], ind_port, nn++);
}
for (int i = 0; i < 3; i++)
{
- WriteOutputArray(pm.ZC_Detected[i], ind_port, nn++);
+ WriteOutputArray(upp.pm.zc.Channel[i].HalfWave, ind_port, nn++);
}
for (int i = 0; i < 3; i++)
{
- WriteOutputArray(pm.F[i], ind_port, nn++);
+ WriteOutputArray(upp.pm.F[i], ind_port, nn++);
}
for (int i = 0; i < 3; i++)
{
- WriteOutputArray(pm.I[i], ind_port, nn++);
+ WriteOutputArray(upp.pm.I[i], ind_port, nn++);
}
for (int i = 0; i < 2; i++)
{
- WriteOutputArray(pm.T[i], ind_port, nn++);
+ WriteOutputArray(upp.pm.T[i], ind_port, nn++);
}
}
/**
@@ -63,6 +63,7 @@ void app_readInputs(const real_T* Buffer) {
ADC_Set_Channel_Value(ADC3, 8, ReadInputArray(0,4));
ADC_Set_Channel_Value(ADC3, 10, ReadInputArray(0,5));
+ alpha_dbg = ReadInputArray(1, 0);
// USER APP INPUT END
}
@@ -73,13 +74,12 @@ void app_readInputs(const real_T* Buffer) {
*/
void app_writeOutputBuffer(real_T* Buffer) {
// USER APP OUTPUT START
- //ThyristorWrite(Buffer, 0);
+ Write_Thyristors(Buffer, 0);
Write_PowerMonitor(Buffer, 1);
- WriteOutputArray(hmcu.dSFuncPeriod, 2, 12);
- WriteOutputArray(hmcu.dSFuncTime, 2, 13);
- WriteOutputArray(hmcu.dMCUStepTime, 2, 14);
+ WriteOutputArray(TIM2->CNT, 2, 0);
+ WriteOutputArray(TIM2->CCR1, 2, 1);
// USER APP OUTPUT END
}
\ No newline at end of file
diff --git a/MATLAB/upp_init.m b/MATLAB/upp_init.m
new file mode 100644
index 0000000..7618676
--- /dev/null
+++ b/MATLAB/upp_init.m
@@ -0,0 +1,8 @@
+clear all
+
+Ts = 5e-6;
+Vnom = 380;
+Fnom = 50;
+
+Temperature1 = 2.22; % 20 градусов
+Temperature2 = 2.99; % 34 градусов
\ No newline at end of file
diff --git a/MATLAB/upp_r2023.slx b/MATLAB/upp_r2023.slx
index 9b886b6..857c684 100644
Binary files a/MATLAB/upp_r2023.slx and b/MATLAB/upp_r2023.slx differ
diff --git a/UPP/AllLibs/MyLibs b/UPP/AllLibs/MyLibs
index 606058e..99652a9 160000
--- a/UPP/AllLibs/MyLibs
+++ b/UPP/AllLibs/MyLibs
@@ -1 +1 @@
-Subproject commit 606058ef552c6341c965bc76d3eda6929ca58e13
+Subproject commit 99652a9ad5ea0686ad9242b165508a9d92ac80a1
diff --git a/UPP/AllLibs/PeriphGeneral b/UPP/AllLibs/PeriphGeneral
index 50c07cd..b3f118b 160000
--- a/UPP/AllLibs/PeriphGeneral
+++ b/UPP/AllLibs/PeriphGeneral
@@ -1 +1 @@
-Subproject commit 50c07cd0911d11106670d25d1457c45735eaa4fa
+Subproject commit b3f118b074951fa827e5a692e9da7637b5397a98
diff --git a/UPP/Core/Configs/mylibs_config.h b/UPP/Core/Configs/mylibs_config.h
index c87e783..cbc013d 100644
--- a/UPP/Core/Configs/mylibs_config.h
+++ b/UPP/Core/Configs/mylibs_config.h
@@ -131,7 +131,7 @@
#define INCLUDE_BIT_ACCESS_LIB ///< Подключить библиотеку с typedef с битовыми полями
#define INCLUDE_TRACKERS_LIB ///< Подключить библиотеку с трекерами
//#define INCLUDE_TRACE_LIB ///< Подключить библиотеку с трейсами
-//#define INCLUDE_GENERAL_PERIPH_LIBS ///< Подключить библиотеку с периферией
+#define INCLUDE_GENERAL_PERIPH_LIBS ///< Подключить библиотеку с периферией
//#define INCLUDE_BENCH_TIME ///< Подключить библиотеку с бенчмарком времени
#define INCLUDE_FILTERS ///< Подключить библиотеку с фильтрами
diff --git a/UPP/Core/Configs/upp_config.h b/UPP/Core/Configs/upp_config.h
index 5c60f54..1208474 100644
--- a/UPP/Core/Configs/upp_config.h
+++ b/UPP/Core/Configs/upp_config.h
@@ -14,7 +14,10 @@
#define _UPP_CONFIG_H_
#include "stm32f4xx_hal.h"
+// Проверка корректности структуры
+#define assert_upp(_struct_) check_null_ptr_2(_struct_, (_struct_)->f.Initialized)
+/* Дефайны для индексов */
#define U_BA 0
#define U_AC 1
#define U_BC 2
@@ -24,14 +27,39 @@
#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 Состояния полуволны
+ */
+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;
+
#endif //_UPP_CONFIG_H_
diff --git a/UPP/Core/Inc/main.h b/UPP/Core/Inc/main.h
index a2211ec..704767c 100644
--- a/UPP/Core/Inc/main.h
+++ b/UPP/Core/Inc/main.h
@@ -71,11 +71,15 @@ extern __IO uint32_t micros;
#define PWM_CHANNEL_6 TIM_CHANNEL_4
#define mb_htim htim12
#define adc_tim htim8
-#define hpwm2 htim2
+#define usTick ustim.Instance->CNT
+#define hpwm2 htim3
#define mb_dbg_huart huart6
#define ustim htim5
#define hpwm1 htim1
-#define usTick ustim.Instance->CNT
+#define ANGLE_CHANNEL_1 TIM_CHANNEL_1
+#define ANGLE_CHANNEL_2 TIM_CHANNEL_2
+#define ANGLE_CHANNEL_3 TIM_CHANNEL_3
+#define angletim htim2
#define UM_LED_GREEN2_Pin GPIO_PIN_2
#define UM_LED_GREEN2_GPIO_Port GPIOE
#define CEN_O_Pin GPIO_PIN_3
diff --git a/UPP/Core/Inc/stm32f4xx_it.h b/UPP/Core/Inc/stm32f4xx_it.h
index 52044da..a95542f 100644
--- a/UPP/Core/Inc/stm32f4xx_it.h
+++ b/UPP/Core/Inc/stm32f4xx_it.h
@@ -55,6 +55,8 @@ void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
+void TIM1_UP_TIM10_IRQHandler(void);
+void TIM2_IRQHandler(void);
void TIM8_TRG_COM_TIM14_IRQHandler(void);
void DMA2_Stream0_IRQHandler(void);
/* USER CODE BEGIN EFP */
diff --git a/UPP/Core/Inc/tim.h b/UPP/Core/Inc/tim.h
index 6a9d43b..2b501c6 100644
--- a/UPP/Core/Inc/tim.h
+++ b/UPP/Core/Inc/tim.h
@@ -34,6 +34,8 @@ extern "C" {
extern TIM_HandleTypeDef htim1;
+extern TIM_HandleTypeDef htim2;
+
extern TIM_HandleTypeDef htim3;
extern TIM_HandleTypeDef htim5;
@@ -49,6 +51,7 @@ extern TIM_HandleTypeDef htim12;
/* USER CODE END Private defines */
void MX_TIM1_Init(void);
+void MX_TIM2_Init(void);
void MX_TIM3_Init(void);
void MX_TIM5_Init(void);
void MX_TIM8_Init(void);
diff --git a/UPP/Core/PowerMonitor/adc_tools.c b/UPP/Core/PowerMonitor/adc_tools.c
index dbd81d7..5129c70 100644
--- a/UPP/Core/PowerMonitor/adc_tools.c
+++ b/UPP/Core/PowerMonitor/adc_tools.c
@@ -32,8 +32,6 @@ static float coefs_biquad_T[5] = {
-1.98f, // a1
0.980f // a2
};
-// Проверка корректности структуры АЦП
-#define assert_adc(_adc_) check_null_ptr_2(_adc_, (_adc_)->f.Initialized)
static void ADC_EnableAllFilters(ADC_Periodic_t *adc)
{
@@ -100,7 +98,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 res;
- if(assert_adc(adc))
+ if(assert_upp(adc))
return HAL_ERROR;
if((valueMax == 0) || (levelMax == 0))
return HAL_ERROR;
@@ -121,7 +119,7 @@ HAL_StatusTypeDef ADC_ConfigChannel(ADC_Periodic_t *adc, int ChNumb, uint16_t le
HAL_StatusTypeDef ADC_Start(ADC_Periodic_t *adc, uint16_t Period)
{
HAL_StatusTypeDef res;
- if(assert_adc(adc))
+ if(assert_upp(adc))
return HAL_ERROR;
if(Period == 0)
return HAL_ERROR;
@@ -154,7 +152,7 @@ HAL_StatusTypeDef ADC_Start(ADC_Periodic_t *adc, uint16_t Period)
*/
HAL_StatusTypeDef ADC_Stop(ADC_Periodic_t *adc)
{
- if(assert_adc(adc))
+ if(assert_upp(adc))
return HAL_ERROR;
// Запускаем таймер который будет запускать опрос АЦП
@@ -170,7 +168,7 @@ HAL_StatusTypeDef ADC_Stop(ADC_Periodic_t *adc)
*/
HAL_StatusTypeDef ADC_Handle(ADC_Periodic_t *adc)
{
- if(assert_adc(adc))
+ if(assert_upp(adc))
return HAL_ERROR;
ADC_Coefs_t *coefs = adc->Coefs;
@@ -219,7 +217,7 @@ void ADC_UpdateStatistics(ADC_Periodic_t *adc, uint8_t channel, ADC_StatLevel_t
{
if (level < ADC_LEVEL_BASE)
return;
- if(assert_adc(adc))
+ if(assert_upp(adc))
return;
if (channel >= ADC_NUMB_OF_REGULAR_CHANNELS)
return;
diff --git a/UPP/Core/PowerMonitor/adc_tools.h b/UPP/Core/PowerMonitor/adc_tools.h
index 12da5ae..e61e16b 100644
--- a/UPP/Core/PowerMonitor/adc_tools.h
+++ b/UPP/Core/PowerMonitor/adc_tools.h
@@ -126,6 +126,7 @@ HAL_StatusTypeDef ADC_ConfigChannel(ADC_Periodic_t *adc, int ChNumb, uint16_t le
HAL_StatusTypeDef ADC_Start(ADC_Periodic_t *adc, uint16_t Period);
/* Остановка АЦП. */
HAL_StatusTypeDef ADC_Stop(ADC_Periodic_t *adc);
+
/* Обработка АЦП после получения данных. */
HAL_StatusTypeDef ADC_Handle(ADC_Periodic_t *adc);
diff --git a/UPP/Core/PowerMonitor/power_monitor.c b/UPP/Core/PowerMonitor/power_monitor.c
index 53f5f3e..f4dcf07 100644
--- a/UPP/Core/PowerMonitor/power_monitor.c
+++ b/UPP/Core/PowerMonitor/power_monitor.c
@@ -43,7 +43,7 @@ HAL_StatusTypeDef PowerMonitor_Start(PowerMonitor_t *hpm)
{
if(ADC_Start(&hpm->adc, PM_ADC_PERIOD) != HAL_OK)
return HAL_ERROR;
-
+
return HAL_OK;
}
@@ -51,8 +51,7 @@ HAL_StatusTypeDef PowerMonitor_Start(PowerMonitor_t *hpm)
void PowerMonitor_Handle(PowerMonitor_t *hpm)
{
-
- static uint32_t last_zc_state[ADC_NUMB_OF_U_CHANNELS] = {0};
+ static uint32_t last_zc_cnt[ADC_NUMB_OF_U_CHANNELS] = {0};
ADC_Handle(&hpm->adc);
hpm->U[U_BA] = hpm->adc.Data[ADC_CHANNEL_UBA];
@@ -69,14 +68,7 @@ void PowerMonitor_Handle(PowerMonitor_t *hpm)
ZC_ProcessAllChannels(&hpm->zc, hpm->U, usTick);
for(int i = 0; i < 3; i++)
{
- if(last_zc_state[i] != ZC_GetStableState(&hpm->zc, i))
- {
- last_zc_state[i] = ZC_GetStableState(&hpm->zc, i);
- hpm->ZC_Detected[i] = !hpm->ZC_Detected[i];
- }
+
+ hpm->F[i] = ZC_GetFrequency(&hpm->zc, i) / 2;
}
-
- hpm->F[U_BA] = (hpm->zc.Channel[U_BA].Frequency) / 2;
- hpm->F[U_AC] = (hpm->zc.Channel[U_AC].Frequency) / 2;
- hpm->F[U_BC] = (hpm->zc.Channel[U_BC].Frequency) / 2;
}
\ No newline at end of file
diff --git a/UPP/Core/PowerMonitor/power_monitor.h b/UPP/Core/PowerMonitor/power_monitor.h
index 54ac6e6..56bf1cd 100644
--- a/UPP/Core/PowerMonitor/power_monitor.h
+++ b/UPP/Core/PowerMonitor/power_monitor.h
@@ -10,11 +10,12 @@
#include "adc_tools.h"
#include "zero_cross.h"
+
typedef struct
{
ADC_Periodic_t adc;
ZeroCross_Handle_t zc;
- uint32_t ZC_Detected[3];
+ UPP_HalfWave_t CurrentHalfWave[3];
float U[3];
float F[3];
diff --git a/UPP/Core/PowerMonitor/zero_cross.c b/UPP/Core/PowerMonitor/zero_cross.c
index e6ae71f..d587251 100644
--- a/UPP/Core/PowerMonitor/zero_cross.c
+++ b/UPP/Core/PowerMonitor/zero_cross.c
@@ -38,7 +38,6 @@ HAL_StatusTypeDef ZC_Init(ZeroCross_Handle_t *zc, uint8_t num_channels,
zc->Channel[i].LastValue = 0.0f;
zc->Channel[i].CurrentValue = 0.0f;
zc->Channel[i].DebounceCounter = 0;
- zc->Channel[i].StableState = 0;
zc->Channel[i].LastCrossTime = 0;
zc->Channel[i].Period = 0;
zc->Channel[i].Frequency = 0.0f;
@@ -61,10 +60,9 @@ HAL_StatusTypeDef ZC_Init(ZeroCross_Handle_t *zc, uint8_t num_channels,
HAL_StatusTypeDef ZC_ConfigChannel(ZeroCross_Handle_t *zc, uint8_t channel,
ZC_EdgeType_t edgeType)
{
- if (zc == NULL || !zc->f.Initialized) {
+ if (assert_upp(zc)){
return HAL_ERROR;
}
-
if (channel >= zc->NumChannels) {
return HAL_ERROR;
}
@@ -74,7 +72,6 @@ HAL_StatusTypeDef ZC_ConfigChannel(ZeroCross_Handle_t *zc, uint8_t channel,
// Сброс состояния канала при реконфигурации
zc->Channel[channel].LastValue = 0.0f;
zc->Channel[channel].DebounceCounter = 0;
- zc->Channel[channel].StableState = 0;
zc->Channel[channel].LastCrossTime = 0;
zc->Channel[channel].Period = 0;
zc->Channel[channel].Frequency = 0.0f;
@@ -91,7 +88,10 @@ HAL_StatusTypeDef ZC_ConfigChannel(ZeroCross_Handle_t *zc, uint8_t channel,
*/
void ZC_ProcessChannel(ZeroCross_Handle_t *zc, uint8_t channel, float value, uint32_t timestamp)
{
- if (zc == NULL || !zc->f.Initialized || !zc->f.Monitoring) {
+ if (assert_upp(zc)){
+ return;
+ }
+ if (!zc->f.Monitoring) {
return;
}
if (channel >= zc->NumChannels) {
@@ -147,9 +147,9 @@ void ZC_ProcessChannel(ZeroCross_Handle_t *zc, uint8_t channel, float value, uin
if(zc_detected)
{
- zc_ch->StableState = zc_detected == 1? 1:0;
-
- uint32_t RealTimeShift = zc->DebounceSamples*(timestamp - zc->LastTick); // коло-во тиков * период вызова функции
+ 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 RealTimestamp = timestamp-RealTimeShift;
@@ -180,7 +180,11 @@ void ZC_ProcessChannel(ZeroCross_Handle_t *zc, uint8_t channel, float value, uin
*/
void ZC_ProcessAllChannels(ZeroCross_Handle_t *zc, float *values, uint32_t timestamp)
{
- if (zc == NULL || !zc->f.Initialized || !zc->f.Monitoring || values == NULL) {
+ if (assert_upp(zc)){
+ return;
+ }
+
+ if (!zc->f.Monitoring || values == NULL) {
return;
}
@@ -191,6 +195,38 @@ void ZC_ProcessAllChannels(ZeroCross_Handle_t *zc, float *values, uint32_t times
zc->LastTick = timestamp;
}
+
+/**
+ * @brief Полученить флаг - переход произошел.
+ * @param zc Указатель на хендл детектора нуля
+ * @param channel Номер канала
+ * @return 1 - переход произошел, 0 - перехода не было.
+ */
+int ZC_isOccurred(ZeroCross_Handle_t *zc, uint8_t channel)
+{
+ if (assert_upp(zc)){
+ return 0;
+ }
+ int occurred = zc->Channel[channel].Occurred;
+ zc->Channel[channel].Occurred = 0;
+ return occurred;
+}
+
+/**
+ * @brief Получение полуволны (после последнего zero-cross).
+ * @param zc Указатель на хендл детектора нуля
+ * @param channel Номер канала
+ * @return Текущая полуволна @ref UPP_HalfWave_t.
+ */
+UPP_HalfWave_t ZC_GetHalfWave(ZeroCross_Handle_t *zc, uint8_t channel)
+{
+ if (assert_upp(zc)){
+ return UPP_WAVE_UNKNOWED;
+ }
+
+ return zc->Channel[channel].HalfWave;
+}
+
/**
* @brief Получение частоты сигнала.
* @param zc Указатель на хендл детектора нуля
@@ -199,73 +235,16 @@ void ZC_ProcessAllChannels(ZeroCross_Handle_t *zc, float *values, uint32_t times
*/
float ZC_GetFrequency(ZeroCross_Handle_t *zc, uint8_t channel)
{
- if (zc == NULL || !zc->f.Initialized || channel >= zc->NumChannels) {
+ if (assert_upp(zc)){
+ return 0.0f;
+ }
+ if (channel >= zc->NumChannels) {
return 0.0f;
}
return zc->Channel[channel].Frequency;
}
-/**
- * @brief Получение периода сигнала.
- * @param zc Указатель на хендл детектора нуля
- * @param channel Номер канала
- * @return Период в тактах таймера.
- */
-uint32_t ZC_GetPeriod(ZeroCross_Handle_t *zc, uint8_t channel)
-{
- if (zc == NULL || !zc->f.Initialized || channel >= zc->NumChannels) {
- return 0;
- }
-
- return zc->Channel[channel].Period;
-}
-
-/**
- * @brief Получение счетчика переходов.
- * @param zc Указатель на хендл детектора нуля
- * @param channel Номер канала
- * @return Количество переходов.
- */
-uint32_t ZC_GetCrossCount(ZeroCross_Handle_t *zc, uint8_t channel)
-{
- if (zc == NULL || !zc->f.Initialized || channel >= zc->NumChannels) {
- return 0;
- }
-
- return zc->Channel[channel].CrossCount;
-}
-
-/**
- * @brief Получение текущего состояния канала.
- * @param zc Указатель на хендл детектора нуля
- * @param channel Номер канала
- * @return Состояние (0 - отрицательное, 1 - положительное).
- */
-uint8_t ZC_GetStableState(ZeroCross_Handle_t *zc, uint8_t channel)
-{
- if (zc == NULL || !zc->f.Initialized || channel >= zc->NumChannels) {
- return 0;
- }
-
- return zc->Channel[channel].StableState;
-}
-
-/**
- * @brief Получение текущего значения канала.
- * @param zc Указатель на хендл детектора нуля
- * @param channel Номер канала
- * @return Текущее значение сигнала.
- */
-float ZC_GetCurrentValue(ZeroCross_Handle_t *zc, uint8_t channel)
-{
- if (zc == NULL || !zc->f.Initialized || channel >= zc->NumChannels) {
- return 0.0f;
- }
-
- return zc->Channel[channel].CurrentValue;
-}
-
/**
* @brief Включение/выключение мониторинга.
* @param zc Указатель на хендл детектора нуля
@@ -273,6 +252,9 @@ float ZC_GetCurrentValue(ZeroCross_Handle_t *zc, uint8_t channel)
*/
void ZC_EnableMonitoring(ZeroCross_Handle_t *zc, uint8_t enable)
{
+ if (assert_upp(zc)){
+ return;
+ }
if (zc == NULL || !zc->f.Initialized) {
return;
}
@@ -287,7 +269,7 @@ void ZC_EnableMonitoring(ZeroCross_Handle_t *zc, uint8_t enable)
*/
void ZC_Reset(ZeroCross_Handle_t *zc, uint8_t channel)
{
- if (zc == NULL || !zc->f.Initialized) {
+ if (assert_upp(zc)){
return;
}
@@ -295,7 +277,6 @@ void ZC_Reset(ZeroCross_Handle_t *zc, uint8_t channel)
zc->Channel[channel].LastValue = 0.0f;
zc->Channel[channel].CurrentValue = 0.0f;
zc->Channel[channel].DebounceCounter = 0;
- zc->Channel[channel].StableState = 0;
zc->Channel[channel].LastCrossTime = 0;
zc->Channel[channel].Period = 0;
zc->Channel[channel].Frequency = 0.0f;
@@ -307,7 +288,6 @@ void ZC_Reset(ZeroCross_Handle_t *zc, uint8_t channel)
zc->Channel[i].LastValue = 0.0f;
zc->Channel[i].CurrentValue = 0.0f;
zc->Channel[i].DebounceCounter = 0;
- zc->Channel[i].StableState = 0;
zc->Channel[i].LastCrossTime = 0;
zc->Channel[i].Period = 0;
zc->Channel[i].Frequency = 0.0f;
diff --git a/UPP/Core/PowerMonitor/zero_cross.h b/UPP/Core/PowerMonitor/zero_cross.h
index fc91202..ba22f79 100644
--- a/UPP/Core/PowerMonitor/zero_cross.h
+++ b/UPP/Core/PowerMonitor/zero_cross.h
@@ -88,15 +88,16 @@ typedef enum {
* @brief Структура канала детектора нуля
*/
typedef struct {
- uint32_t CrossCount; ///< Счетчик переходов
- float LastValue; ///< Предыдущее значение
- float CurrentValue; ///< Текущее значение
- uint16_t DebounceCounter; ///< Счетчик антидребезга
- uint8_t StableState; ///< Стабильное состояние (0=отриц, 1=полож)
- uint32_t LastCrossTime; ///< Время последнего перехода
- uint32_t Period; ///< Период сигнала (в тактах таймера)
- float Frequency; ///< Частота
- ZC_EdgeType_t EdgeType; ///< Тип детектируемого перехода
+ uint8_t Occurred; ///< Флаг что пересечение нуля произошло
+ uint32_t CrossCount; ///< Счетчик переходов
+ float LastValue; ///< Предыдущее значение
+ float CurrentValue; ///< Текущее значение
+ uint16_t DebounceCounter; ///< Счетчик антидребезга
+ uint32_t LastCrossTime; ///< Время последнего перехода
+ uint32_t Period; ///< Период сигнала (в тактах таймера)
+ float Frequency; ///< Частота
+ UPP_HalfWave_t HalfWave; ///< Текущая полуволна
+ ZC_EdgeType_t EdgeType; ///< Тип детектируемого перехода
} ZC_Channel_t;
/**
@@ -132,36 +133,17 @@ void ZC_ProcessChannel(ZeroCross_Handle_t *zc, uint8_t channel, float value,
void ZC_ProcessAllChannels(ZeroCross_Handle_t *zc, float *values,
uint32_t timestamp);
+/* Полученить флаг - переход произошел. */
+int ZC_isOccurred(ZeroCross_Handle_t *zc, uint8_t channel);
/* Получение частоты сигнала */
float ZC_GetFrequency(ZeroCross_Handle_t *zc, uint8_t channel);
-
-/* Получение периода сигнала */
-uint32_t ZC_GetPeriod(ZeroCross_Handle_t *zc, uint8_t channel);
-
-/* Получение счетчика переходов */
-uint32_t ZC_GetCrossCount(ZeroCross_Handle_t *zc, uint8_t channel);
-
-/* Получение текущего состояния канала */
-uint8_t ZC_GetStableState(ZeroCross_Handle_t *zc, uint8_t channel);
-
-/* Получение текущего значения канала */
-float ZC_GetCurrentValue(ZeroCross_Handle_t *zc, uint8_t channel);
-
+/* Получение полуволны (после последнего zero-cross) */
+UPP_HalfWave_t ZC_GetHalfWave(ZeroCross_Handle_t *zc, uint8_t channel);
/* Включение/выключение мониторинга */
void ZC_EnableMonitoring(ZeroCross_Handle_t *zc, uint8_t enable);
-
/* Сброс статистики канала */
void ZC_Reset(ZeroCross_Handle_t *zc, uint8_t channel);
-/* Установка гистерезиса для хендла */
-void ZC_SetHysteresis(ZeroCross_Handle_t *zc, float hysteresis);
-
-/* Установка дебаунс samples для хендла */
-void ZC_SetDebounceSamples(ZeroCross_Handle_t *zc, uint8_t debounce_samples);
-
-/* Получение количества каналов хендла */
-uint8_t ZC_GetNumChannels(ZeroCross_Handle_t *zc);
-
#endif /* _ZERO_CROSS_H_ */
/**
diff --git a/UPP/Core/Src/main.c b/UPP/Core/Src/main.c
index 16e30e8..9096b23 100644
--- a/UPP/Core/Src/main.c
+++ b/UPP/Core/Src/main.c
@@ -107,6 +107,7 @@ int main(void)
MX_TIM12_Init();
MX_TIM8_Init();
MX_TIM5_Init();
+ MX_TIM2_Init();
/* USER CODE BEGIN 2 */
#else //MATLAB
#endif //MATLAB
diff --git a/UPP/Core/Src/stm32f4xx_it.c b/UPP/Core/Src/stm32f4xx_it.c
index ceef07b..f151479 100644
--- a/UPP/Core/Src/stm32f4xx_it.c
+++ b/UPP/Core/Src/stm32f4xx_it.c
@@ -23,6 +23,8 @@
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "upp_main.h"
+#include "pwm_thyristors.h"
+#include "angle_control.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@@ -57,6 +59,8 @@
/* External variables --------------------------------------------------------*/
extern DMA_HandleTypeDef hdma_adc3;
+extern TIM_HandleTypeDef htim1;
+extern TIM_HandleTypeDef htim2;
extern TIM_HandleTypeDef htim8;
extern TIM_HandleTypeDef htim14;
@@ -202,13 +206,41 @@ void SysTick_Handler(void)
/* please refer to the startup file (startup_stm32f4xx.s). */
/******************************************************************************/
+/**
+ * @brief This function handles TIM1 update interrupt and TIM10 global interrupt.
+ */
+void TIM1_UP_TIM10_IRQHandler(void)
+{
+ /* USER CODE BEGIN TIM1_UP_TIM10_IRQn 0 */
+
+ /* USER CODE END TIM1_UP_TIM10_IRQn 0 */
+ HAL_TIM_IRQHandler(&htim1);
+ /* USER CODE BEGIN TIM1_UP_TIM10_IRQn 1 */
+ UPP_PWM_Handle();
+ /* USER CODE END TIM1_UP_TIM10_IRQn 1 */
+}
+
+/**
+ * @brief This function handles TIM2 global interrupt.
+ */
+void TIM2_IRQHandler(void)
+{
+ /* USER CODE BEGIN TIM2_IRQn 0 */
+
+ /* USER CODE END TIM2_IRQn 0 */
+ HAL_TIM_IRQHandler(&htim2);
+ /* USER CODE BEGIN TIM2_IRQn 1 */
+ //UPP_Angle_Handle();
+ /* USER CODE END TIM2_IRQn 1 */
+}
+
/**
* @brief This function handles TIM8 trigger and commutation interrupts and TIM14 global interrupt.
*/
void TIM8_TRG_COM_TIM14_IRQHandler(void)
{
/* USER CODE BEGIN TIM8_TRG_COM_TIM14_IRQn 0 */
-#ifndef MATLAB
+#ifndef MATLAB // в матлабе нет htim14, т.к. это систем тики
/* USER CODE END TIM8_TRG_COM_TIM14_IRQn 0 */
HAL_TIM_IRQHandler(&htim8);
HAL_TIM_IRQHandler(&htim14);
diff --git a/UPP/Core/Src/tim.c b/UPP/Core/Src/tim.c
index a9cc642..85caab9 100644
--- a/UPP/Core/Src/tim.c
+++ b/UPP/Core/Src/tim.c
@@ -25,6 +25,7 @@
/* USER CODE END 0 */
TIM_HandleTypeDef htim1;
+TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim3;
TIM_HandleTypeDef htim5;
TIM_HandleTypeDef htim8;
@@ -48,7 +49,7 @@ void MX_TIM1_Init(void)
/* USER CODE END TIM1_Init 1 */
htim1.Instance = TIM1;
- htim1.Init.Prescaler = 180-1;
+ htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 65535;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
@@ -67,7 +68,11 @@ void MX_TIM1_Init(void)
{
Error_Handler();
}
- sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
+ if (HAL_TIM_OnePulse_Init(&htim1, TIM_OPMODE_SINGLE) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
@@ -112,6 +117,67 @@ void MX_TIM1_Init(void)
/* USER CODE END TIM1_Init 2 */
HAL_TIM_MspPostInit(&htim1);
+}
+/* TIM2 init function */
+void MX_TIM2_Init(void)
+{
+
+ /* USER CODE BEGIN TIM2_Init 0 */
+
+ /* USER CODE END TIM2_Init 0 */
+
+ TIM_ClockConfigTypeDef sClockSourceConfig = {0};
+ TIM_MasterConfigTypeDef sMasterConfig = {0};
+ TIM_OC_InitTypeDef sConfigOC = {0};
+
+ /* USER CODE BEGIN TIM2_Init 1 */
+
+ /* USER CODE END TIM2_Init 1 */
+ htim2.Instance = TIM2;
+ htim2.Init.Prescaler = 0;
+ htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
+ htim2.Init.Period = 4294967295;
+ htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
+ htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
+ if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
+ if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ if (HAL_TIM_OC_Init(&htim2) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
+ sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
+ if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ sConfigOC.OCMode = TIM_OCMODE_TIMING;
+ sConfigOC.Pulse = 0;
+ sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
+ sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
+ if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ /* USER CODE BEGIN TIM2_Init 2 */
+
+ /* USER CODE END TIM2_Init 2 */
+
}
/* TIM3 init function */
void MX_TIM3_Init(void)
@@ -122,6 +188,7 @@ void MX_TIM3_Init(void)
/* USER CODE END TIM3_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
+ TIM_SlaveConfigTypeDef sSlaveConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
@@ -147,8 +214,18 @@ void MX_TIM3_Init(void)
{
Error_Handler();
}
+ if (HAL_TIM_OnePulse_Init(&htim3, TIM_OPMODE_SINGLE) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ sSlaveConfig.SlaveMode = TIM_SLAVEMODE_TRIGGER;
+ sSlaveConfig.InputTrigger = TIM_TS_ITR0;
+ if (HAL_TIM_SlaveConfigSynchro(&htim3, &sSlaveConfig) != HAL_OK)
+ {
+ Error_Handler();
+ }
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
- sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
+ sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler();
@@ -325,10 +402,29 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
/* USER CODE END TIM1_MspInit 0 */
/* TIM1 clock enable */
__HAL_RCC_TIM1_CLK_ENABLE();
+
+ /* TIM1 interrupt Init */
+ HAL_NVIC_SetPriority(TIM1_UP_TIM10_IRQn, 0, 0);
+ HAL_NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);
/* USER CODE BEGIN TIM1_MspInit 1 */
/* USER CODE END TIM1_MspInit 1 */
}
+ else if(tim_baseHandle->Instance==TIM2)
+ {
+ /* USER CODE BEGIN TIM2_MspInit 0 */
+
+ /* USER CODE END TIM2_MspInit 0 */
+ /* TIM2 clock enable */
+ __HAL_RCC_TIM2_CLK_ENABLE();
+
+ /* TIM2 interrupt Init */
+ HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
+ HAL_NVIC_EnableIRQ(TIM2_IRQn);
+ /* USER CODE BEGIN TIM2_MspInit 1 */
+
+ /* USER CODE END TIM2_MspInit 1 */
+ }
else if(tim_baseHandle->Instance==TIM3)
{
/* USER CODE BEGIN TIM3_MspInit 0 */
@@ -469,10 +565,27 @@ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
/* USER CODE END TIM1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM1_CLK_DISABLE();
+
+ /* TIM1 interrupt Deinit */
+ HAL_NVIC_DisableIRQ(TIM1_UP_TIM10_IRQn);
/* USER CODE BEGIN TIM1_MspDeInit 1 */
/* USER CODE END TIM1_MspDeInit 1 */
}
+ else if(tim_baseHandle->Instance==TIM2)
+ {
+ /* USER CODE BEGIN TIM2_MspDeInit 0 */
+
+ /* USER CODE END TIM2_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_TIM2_CLK_DISABLE();
+
+ /* TIM2 interrupt Deinit */
+ HAL_NVIC_DisableIRQ(TIM2_IRQn);
+ /* USER CODE BEGIN TIM2_MspDeInit 1 */
+
+ /* USER CODE END TIM2_MspDeInit 1 */
+ }
else if(tim_baseHandle->Instance==TIM3)
{
/* USER CODE BEGIN TIM3_MspDeInit 0 */
diff --git a/UPP/Core/UPP/angle_control.c b/UPP/Core/UPP/angle_control.c
new file mode 100644
index 0000000..de0ee4f
--- /dev/null
+++ b/UPP/Core/UPP/angle_control.c
@@ -0,0 +1,167 @@
+/**
+******************************************************************************
+* @file pwm_thyristors.c
+* @brief Модуль для управления тиристорами
+******************************************************************************
+* @details
+******************************************************************************/
+#include "angle_control.h"
+#include "tim.h"
+
+
+/**
+ * @brief Инициализация ШИМ тиристоров.
+ * @param hangle Указатель на таймер
+ * @return HAL Status.
+ */
+HAL_StatusTypeDef Angle_Init(Angle_Handle_t *hangle, float AngleMin, float AngleMax)
+{
+ 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);
+ HAL_TIM_OC_Start_IT(hangle->htim, ANGLE_CHANNEL_2);
+ HAL_TIM_OC_Start_IT(hangle->htim, ANGLE_CHANNEL_3);
+
+ Angle_Reset(hangle, UPP_PHASE_A);
+ Angle_Reset(hangle, UPP_PHASE_B);
+ Angle_Reset(hangle, UPP_PHASE_C);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Хендл таймера для рассчета угла открытия.
+ * @param hangle Указатель на таймер
+ * @return HAL Status.
+ */
+UPP_Phase_t Angle_Handle(Angle_Handle_t *hangle)
+{
+ if(hangle == NULL)
+ return UPP_PHASE_UNKNOWN;
+
+
+ switch(hangle->htim->Channel)
+ {
+ case HAL_TIM_ACTIVE_CHANNEL_1:
+ return UPP_PHASE_A;
+ break;
+
+ case HAL_TIM_ACTIVE_CHANNEL_2:
+ return UPP_PHASE_B;
+ break;
+
+ case HAL_TIM_ACTIVE_CHANNEL_3:
+ return UPP_PHASE_C;
+ break;
+
+ default:
+ return UPP_PHASE_UNKNOWN;
+ break;
+ }
+
+
+ return UPP_PHASE_UNKNOWN;
+}
+
+/**
+ * @brief Установка угла открытия в таймер.
+ * @param hangle Указатель на таймер
+ * @param Phase Для какой фазы надо установить угол открытия
+ * @return HAL Status.
+ */
+HAL_StatusTypeDef Angle_Start(Angle_Handle_t *hangle, UPP_Phase_t Phase, float Angle, float Freq)
+{
+ if(hangle == NULL)
+ return HAL_ERROR;
+
+ // Если канал дурацкий - возвращаем ошибку
+ if(Phase >= 3)
+ {
+ return HAL_ERROR;
+ }
+ if(Angle > hangle->AngleMax)
+ {
+ Angle = hangle->AngleMax;
+ }
+ if(Angle < hangle->AngleMin)
+ {
+ Angle = hangle->AngleMin;
+ }
+
+ uint32_t timer_ticks = TIM_FreqToTick(Freq/Angle, ANGLE_TIM2_FREQ_MHZ);
+ uint32_t ccr_ticks = __HAL_TIM_GET_COUNTER(hangle->htim) + timer_ticks;
+
+ switch(Phase)
+ {
+ case UPP_PHASE_A:
+ __HAL_TIM_ENABLE_IT(hangle->htim, TIM_IT_CC1);
+ __HAL_TIM_SET_COMPARE(hangle->htim, ANGLE_CHANNEL_1, ccr_ticks);
+ break;
+
+ case UPP_PHASE_B:
+ __HAL_TIM_ENABLE_IT(hangle->htim, TIM_IT_CC2);
+ __HAL_TIM_SET_COMPARE(hangle->htim, ANGLE_CHANNEL_2, ccr_ticks);
+ break;
+
+ case UPP_PHASE_C:
+ __HAL_TIM_ENABLE_IT(hangle->htim, TIM_IT_CC3);
+ __HAL_TIM_SET_COMPARE(hangle->htim, ANGLE_CHANNEL_3, ccr_ticks);
+ break;
+
+ case UPP_PHASE_UNKNOWN:
+ // ПОКА ХЗ
+ break;
+
+
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Сброс угла открытия у таймера.
+ * @param hangle Указатель на таймер
+ * @param Phase Для какой фазы надо сбросить угол открытия
+ * @return HAL Status.
+ */
+HAL_StatusTypeDef Angle_Reset(Angle_Handle_t *hangle, UPP_Phase_t Phase)
+{
+ if(hangle == NULL)
+ return HAL_ERROR;
+
+ // Если канал дурацкий - возвращаем ошибку
+ if(Phase >= 3)
+ {
+ return HAL_ERROR;
+ }
+
+ switch(Phase)
+ {
+ case UPP_PHASE_A:
+ __HAL_TIM_DISABLE_IT(hangle->htim, TIM_IT_CC1);
+ break;
+
+ case UPP_PHASE_B:
+ __HAL_TIM_DISABLE_IT(hangle->htim, TIM_IT_CC2);
+ break;
+
+ case UPP_PHASE_C:
+ __HAL_TIM_DISABLE_IT(hangle->htim, TIM_IT_CC3);
+ break;
+
+ case UPP_PHASE_UNKNOWN:
+ // ПОКА ХЗ
+ break;
+ }
+ return HAL_OK;
+}
\ No newline at end of file
diff --git a/UPP/Core/UPP/angle_control.h b/UPP/Core/UPP/angle_control.h
new file mode 100644
index 0000000..4da20e1
--- /dev/null
+++ b/UPP/Core/UPP/angle_control.h
@@ -0,0 +1,30 @@
+/**
+******************************************************************************
+* @file pwm_thyristors.h
+* @brief Модуль для управления тиристорами (объединённый 6-канальный)
+******************************************************************************
+*/
+#ifndef _ANGLE_CONTROL_H_
+#define _ANGLE_CONTROL_H_
+#include "main.h"
+
+#define ANGLE_TIM2_FREQ_MHZ 90
+
+typedef struct
+{
+ TIM_HandleTypeDef *htim;
+
+ float AngleMin;
+ float AngleMax;
+}Angle_Handle_t;
+
+/* Инициализация Таймера для рассчета угла открытия. */
+HAL_StatusTypeDef Angle_Init(Angle_Handle_t *hangle, float AngleMin, float AngleMax);
+/* Установка угла открытия в таймер. */
+HAL_StatusTypeDef Angle_Start(Angle_Handle_t *hangle, UPP_Phase_t Phase, float Angle, float Freq);
+/* Сброс угла открытия у таймера. */
+HAL_StatusTypeDef Angle_Reset(Angle_Handle_t *hangle, UPP_Phase_t Phase);
+
+/* Хендл таймера для рассчета угла открытия. */
+UPP_Phase_t Angle_Handle(Angle_Handle_t *hangle);
+#endif /* _ANGLE_CONTROL_H_ */
diff --git a/UPP/Core/UPP/pwm_thyristors.c b/UPP/Core/UPP/pwm_thyristors.c
new file mode 100644
index 0000000..fc6c643
--- /dev/null
+++ b/UPP/Core/UPP/pwm_thyristors.c
@@ -0,0 +1,303 @@
+/**
+******************************************************************************
+* @file pwm_thyristors.c
+* @brief Модуль для управления тиристорами
+******************************************************************************
+* @details
+******************************************************************************/
+#include "pwm_thyristors.h"
+#include "angle_control.h"
+#include "tim.h"
+
+static HAL_StatusTypeDef __PWM_SetOutputState(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint32_t state);
+
+/**
+ * @brief Инициализация ШИМ тиристоров.
+ * @param hpwm Указатель на хендл ШИМ тиристоров
+ * @return HAL Status.
+ */
+HAL_StatusTypeDef PWM_Init(PWM_Handle_t *hpwm)
+{
+ if(hpwm == NULL)
+ return HAL_ERROR;
+
+ // Фаза A
+ hpwm->AllPhases[PHASE_A_POS].State = PWM_THYR_DISABLED;
+ hpwm->AllPhases[PHASE_A_POS].ChMask = PWM_CHANNEL_1;
+ hpwm->AllPhases[PHASE_A_POS].htim = &hpwm1;
+ hpwm->AllPhases[PHASE_A_NEG].State = PWM_THYR_DISABLED;
+ hpwm->AllPhases[PHASE_A_NEG].ChMask = PWM_CHANNEL_2;
+ hpwm->AllPhases[PHASE_A_NEG].htim = &hpwm1;
+
+ // Фаза B
+ hpwm->AllPhases[PHASE_B_POS].State = PWM_THYR_DISABLED;
+ hpwm->AllPhases[PHASE_B_POS].ChMask = PWM_CHANNEL_3;
+ hpwm->AllPhases[PHASE_B_POS].htim = &hpwm1;
+ hpwm->AllPhases[PHASE_B_NEG].State = PWM_THYR_DISABLED;
+ hpwm->AllPhases[PHASE_B_NEG].ChMask = PWM_CHANNEL_4;
+ hpwm->AllPhases[PHASE_B_NEG].htim = &hpwm1;
+
+ // Фаза C
+ hpwm->AllPhases[PHASE_C_POS].State = PWM_THYR_DISABLED;
+ hpwm->AllPhases[PHASE_C_POS].ChMask = PWM_CHANNEL_5;
+ hpwm->AllPhases[PHASE_C_POS].htim = &hpwm2;
+ hpwm->AllPhases[PHASE_C_NEG].State = PWM_THYR_DISABLED;
+ hpwm->AllPhases[PHASE_C_NEG].ChMask = PWM_CHANNEL_6;
+ hpwm->AllPhases[PHASE_C_NEG].htim = &hpwm2;
+
+ // Фаза неизвестная (чтобы не был указатель в никуда, а был на эту структуру)
+ hpwm->AllPhases[PHASE_UNKNOWN].State = PWM_THYR_DISABLED;
+ hpwm->AllPhases[PHASE_UNKNOWN].ChMask = 0;
+ hpwm->AllPhases[PHASE_UNKNOWN].htim = NULL;
+ hpwm->f.Initialized = 1;
+
+ // Инициализируем ничем. Потом когда словим сеть - поставим конкретные тиристоры
+ PWM_SetHalfWave(hpwm, UPP_PHASE_A, UPP_WAVE_UNKNOWED);
+ PWM_SetHalfWave(hpwm, UPP_PHASE_B, UPP_WAVE_UNKNOWED);
+ PWM_SetHalfWave(hpwm, UPP_PHASE_C, UPP_WAVE_UNKNOWED);
+
+ PWM_SetFrequency(hpwm, hpwm->Config.Frequency);
+
+ HAL_TIM_PWM_Start(&hpwm1, PWM_CHANNEL_1);
+ HAL_TIM_PWM_Start(&hpwm1, PWM_CHANNEL_2);
+ HAL_TIM_PWM_Start(&hpwm1, PWM_CHANNEL_3);
+ HAL_TIM_PWM_Start(&hpwm1, PWM_CHANNEL_4);
+ HAL_TIM_PWM_Start(&hpwm2, PWM_CHANNEL_5);
+ HAL_TIM_PWM_Start(&hpwm2, PWM_CHANNEL_6);
+ HAL_TIM_Base_Start_IT(&hpwm1);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Запуск ШИМ.
+ * @param hpwm Указатель на хендл ШИМ тиристоров
+ * @param Phase На какой фазе надо запустить ШИМ
+ * @return HAL Status.
+ */
+HAL_StatusTypeDef PWM_Start(PWM_Handle_t *hpwm, UPP_Phase_t Phase)
+{
+ if(assert_upp(hpwm))
+ return HAL_ERROR;
+ if (hpwm->Phase[Phase] == NULL || hpwm->Phase[Phase] == &hpwm->AllPhases[PHASE_UNKNOWN])
+ return HAL_ERROR;
+ // Если канал дурацкий - возвращаем ошибку
+ if(Phase >= 3)
+ {
+ return HAL_ERROR;
+ }
+
+
+ switch(hpwm->Phase[Phase]->State)
+ {
+ case PWM_THYR_TIM_START:
+ case PWM_THYR_TIM_ACTIVE:
+ case PWM_THYR_TIM_DONE:
+ return HAL_BUSY;
+
+ case PWM_THYR_DISABLED:
+ case PWM_THYR_TIM_WAIT_ZERO:
+ // переходим в состояние старта ШИМ
+ hpwm->Phase[Phase]->State = PWM_THYR_TIM_START;
+ return HAL_OK;
+
+ default:
+ return HAL_ERROR;;
+ }
+
+ return HAL_ERROR;
+}
+
+/**
+ * @brief Остановить ШИМ.
+ * @param hpwm Указатель на хендл ШИМ тиристоров
+ * @param Phase На какой фазе надо остановить ШИМ
+ * @return HAL Status.
+ */
+HAL_StatusTypeDef PWM_Stop(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint8_t force_stop)
+{
+ if(assert_upp(hpwm))
+ return HAL_ERROR;
+ if (hpwm->Phase[Phase] == NULL || hpwm->Phase[Phase] == &hpwm->AllPhases[PHASE_UNKNOWN])
+ return HAL_ERROR;
+ // Если канал дурацкий - возвращаем ошибку
+ if(Phase >= 3)
+ {
+ return HAL_ERROR;
+ }
+
+ hpwm->Phase[Phase]->State = PWM_THYR_TIM_WAIT_ZERO;
+
+ if(force_stop)
+ {
+ __PWM_SetOutputState(hpwm, Phase, PWM_DISABLE);
+ }
+
+ return HAL_ERROR;
+}
+/**
+ * @brief Хендл ШИМ тиристоров.
+ * @param hpwm Указатель на хендл ШИМ тиристоров
+ * @return HAL Status.
+ */
+HAL_StatusTypeDef PWM_Handle(PWM_Handle_t *hpwm)
+{
+ if(assert_upp(hpwm))
+ return HAL_ERROR;
+
+ for(int phase = 0; phase < 3; phase++)
+ {
+ if(!read_bit(hpwm->Config.PhaseMask.all, phase))
+ continue;
+ if (hpwm->Phase[phase] == NULL || hpwm->Phase[phase] == &hpwm->AllPhases[PHASE_UNKNOWN])
+ continue;
+
+ switch(hpwm->Phase[phase]->State)
+ {
+ case PWM_THYR_DISABLED:
+ __PWM_SetOutputState(hpwm, phase, PWM_DISABLE);
+ break;
+
+ case PWM_THYR_TIM_WAIT_ZERO:
+ __PWM_SetOutputState(hpwm, phase, PWM_DISABLE);
+ break;
+
+ case PWM_THYR_TIM_START:
+ __PWM_SetOutputState(hpwm, phase, PWM_ENABLE);
+ hpwm->Phase[phase]->PulseCnt = hpwm->Config.PulseNumber;
+ hpwm->Phase[phase]->State = PWM_THYR_TIM_ACTIVE;
+ break;
+
+ case PWM_THYR_TIM_ACTIVE:
+ hpwm->Phase[phase]->PulseCnt--;
+ if(hpwm->Phase[phase]->PulseCnt <= 0)
+ {
+ hpwm->Phase[phase]->PulseCnt = 0;
+ hpwm->Phase[phase]->State = PWM_THYR_TIM_DONE;
+ }
+ break;
+
+ case PWM_THYR_TIM_DONE:
+ hpwm->Phase[phase]->State = PWM_THYR_TIM_WAIT_ZERO;
+ break;
+
+ default:
+ __PWM_SetOutputState(hpwm, phase, PWM_DISABLE);
+ break;
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief Установка полуволны для слежения.
+ * @param hpwm Указатель на хендл ШИМ тиристоров
+ * @param Phase Для какой фазы надо установить полуволну
+ * @param halfwave Какую полуволну установить
+ * @return HAL Status.
+ */
+HAL_StatusTypeDef PWM_SetHalfWave(PWM_Handle_t *hpwm, UPP_Phase_t Phase, UPP_HalfWave_t halfwave)
+{
+ if(assert_upp(hpwm))
+ return HAL_ERROR;
+
+
+ // Сбрасываем текущий канал
+ __PWM_SetOutputState(hpwm, Phase, PWM_DISABLE);
+ // Если канал дурацкий - выставляем заглушку
+ if(Phase >= 3)
+ {
+ hpwm->Phase[Phase] = &hpwm->AllPhases[PHASE_UNKNOWN];
+ return HAL_ERROR;
+ }
+ // Выставляем канал
+ switch(halfwave)
+ {
+ case UPP_WAVE_POSITIVE:
+ hpwm->Phase[Phase] = &hpwm->AllPhases[Phase];
+ return HAL_OK;
+
+ case UPP_WAVE_NEGATIVE:
+ hpwm->Phase[Phase] = &hpwm->AllPhases[Phase+3];
+ return HAL_OK;
+
+ default:
+ hpwm->Phase[Phase] = &hpwm->AllPhases[PHASE_UNKNOWN];
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @brief Установка режима для канала ШИМ.
+ * @param hpwm Указатель на хендл ШИМ тиристоров
+ * @param Phase Для какой фазы надо установить состояние
+ * @param state Какое состояние установить
+ * @return HAL Status.
+ */
+static HAL_StatusTypeDef __PWM_SetOutputState(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint32_t state)
+{
+ if(hpwm->Phase[Phase] == NULL || hpwm->Phase[Phase] == &hpwm->AllPhases[PHASE_UNKNOWN])
+ return HAL_ERROR;
+
+ uint32_t ch_mode = state;
+
+
+ switch(hpwm->Phase[Phase]->ChMask)
+ {
+ case TIM_CHANNEL_1:
+ hpwm->Phase[Phase]->htim->Instance->CCMR1 &= ~TIM_OCMODE_PWM2;
+ hpwm->Phase[Phase]->htim->Instance->CCMR1 |= ch_mode;
+ break;
+ case TIM_CHANNEL_2:
+ hpwm->Phase[Phase]->htim->Instance->CCMR1 &= ~(TIM_OCMODE_PWM2 << 8);
+ hpwm->Phase[Phase]->htim->Instance->CCMR1 |= (ch_mode << 8);
+ break;
+ case TIM_CHANNEL_3:
+ hpwm->Phase[Phase]->htim->Instance->CCMR2 &= ~TIM_OCMODE_PWM2;
+ hpwm->Phase[Phase]->htim->Instance->CCMR2 |= ch_mode;
+ break;
+ case TIM_CHANNEL_4:
+ hpwm->Phase[Phase]->htim->Instance->CCMR2 &= ~(TIM_OCMODE_PWM2 << 8);
+ hpwm->Phase[Phase]->htim->Instance->CCMR2 |= (ch_mode << 8);
+ break;
+ default:
+ break;
+ }
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Установка полуволны для слежения.
+ * @param hpwm Указатель на хендл ШИМ тиристоров
+ * @param Phase Для какой фазы надо установить полуволну
+ * @param halfwave Какую полуволну установить
+ * @return HAL Status.
+ */
+UPP_HalfWave_t PWM_GetHalfWave(PWM_Handle_t *hpwm, UPP_Phase_t Phase)
+{
+ if(assert_upp(hpwm))
+ return UPP_WAVE_UNKNOWED;
+ if (hpwm->Phase[Phase] == NULL || hpwm->Phase[Phase] == &hpwm->AllPhases[PHASE_UNKNOWN])
+ return UPP_WAVE_UNKNOWED;
+
+ // Если канал дурацкий - возвращаем UNKNOWED
+ if(Phase >= 3)
+ {
+ return UPP_WAVE_UNKNOWED;
+ }
+
+ // Выставляем канал
+ if(hpwm->Phase[Phase] == &hpwm->AllPhases[Phase])
+ {
+ return UPP_WAVE_POSITIVE;
+ }
+ else if(hpwm->Phase[Phase] == &hpwm->AllPhases[Phase+3])
+ {
+ return UPP_WAVE_NEGATIVE;
+ }
+ else
+ {
+ return UPP_WAVE_UNKNOWED;
+ }
+}
\ No newline at end of file
diff --git a/UPP/Core/UPP/pwm_thyristors.h b/UPP/Core/UPP/pwm_thyristors.h
new file mode 100644
index 0000000..008f930
--- /dev/null
+++ b/UPP/Core/UPP/pwm_thyristors.h
@@ -0,0 +1,114 @@
+/**
+******************************************************************************
+* @file pwm_thyristors.h
+* @brief Модуль для управления тиристорами (объединённый 6-канальный)
+******************************************************************************
+*/
+#ifndef _PWM_THYRISTORS_H
+#define _PWM_THYRISTORS_H
+#include "main.h"
+
+
+
+
+
+#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_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
+#define PHASE_A_POS 0
+#define PHASE_B_POS 1
+#define PHASE_C_POS 2
+#define PHASE_A_NEG 3
+#define PHASE_B_NEG 4
+#define PHASE_C_NEG 5
+#define PHASE_UNKNOWN 6
+
+
+/**
+ * @brief Состояния канала
+ */
+typedef enum {
+ PWM_THYR_DISABLED = 0, ///< Канал отключен
+ PWM_THYR_TIM_WAIT_ZERO, ///< Таймер ждет пересечения нуля
+ PWM_THYR_TIM_START, ///< Запуск таймера для ШИМ
+ PWM_THYR_TIM_ACTIVE, ///< Таймер активен и формирует ШИМ
+ PWM_THYR_TIM_DONE ///< Таймер закончил свою работу в полупериоде
+} PWM_State_t;
+
+/**
+ * @brief Канал PWM (один тиристор)
+ */
+typedef struct {
+ PWM_State_t State; ///< Состояние тиристора
+ TIM_HandleTypeDef *htim; ///< указатель на соответствующий TIM (hpwm1 или hpwm2)
+ uint32_t PulseCnt; ///< Счетчик кол-ва импульсов. Инициализируется из структуры @ref PWM_ThyrConfig_t
+ uint32_t ChMask; ///< TIM_CHANNEL_x
+
+ struct {
+ unsigned Ready:1; ///< Флаг готовности тиристора к работе
+ } f;
+} PWM_Channel_t;
+
+/**
+ * @brief Канал PWM (один тиристор)
+ */
+typedef struct {
+ union
+ {
+ uint8_t all;
+ struct
+ {
+ uint8_t phA:1;
+ uint8_t phB:1;
+ uint8_t phC:1;
+ };
+ }PhaseMask; ///< Какими каналами управлять
+ uint8_t PulseNumber; ///< Сколько импульсов отправить в пакете для открытия тиристоров
+ uint32_t Frequency; ///< Частота импульсов
+} PWM_ThyrConfig_t;
+
+/**
+ * @brief Хендл управляюзщий тиристорами */
+typedef struct {
+ PWM_ThyrConfig_t Config;
+ PWM_Channel_t *Phase[3]; ///< Текущие каналы для фаз
+ PWM_Channel_t AllPhases[7]; ///< Все каналы для фаз (+1 для деинициализированного канала)
+
+ struct {
+ unsigned Initialized : 1;
+ unsigned Running : 1; ///< true если оба таймера запущены
+ } f;
+} PWM_Handle_t;
+
+/* ---- API ---- */
+/* Инициализация ШИМ тиристоров. */
+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_SetHalfWave(PWM_Handle_t *hpwm, UPP_Phase_t Phase, UPP_HalfWave_t halfwave);
+/* Установка полуволны для слежения. */
+UPP_HalfWave_t PWM_GetHalfWave(PWM_Handle_t *hpwm, UPP_Phase_t Phase);
+
+/* Хендл ШИМ тиристоров. */
+HAL_StatusTypeDef PWM_Handle(PWM_Handle_t *hpwm);
+#endif /* _PWM_THYRISTORS_H */
diff --git a/UPP/Core/UPP/upp_main.c b/UPP/Core/UPP/upp_main.c
index 052684c..729fb6c 100644
--- a/UPP/Core/UPP/upp_main.c
+++ b/UPP/Core/UPP/upp_main.c
@@ -6,9 +6,9 @@
* @details
******************************************************************************/
#include "upp_main.h" // всё остальное по работе с УПП
-#include "power_monitor.h" // статистика сети и АЦП
-
-PowerMonitor_t pm;
+UPP_t upp;
+float alpha_dbg = 0.5;
+// ОСНОВНОЙ ЦИКЛ main.c
/**
* @brief Инициализация УПП.
@@ -17,7 +17,11 @@ PowerMonitor_t pm;
int UPP_Init(void)
{
HAL_TIM_Base_Start(&ustim);
- PowerMonitor_Init(&pm);
+ 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);
return 0;
}
@@ -27,7 +31,8 @@ int UPP_Init(void)
*/
int UPP_PreWhile(void)
{
- PowerMonitor_Start(&pm);
+ PowerMonitor_Start(&upp.pm);
+ upp.hpwm.Config.PhaseMask.all = 0x7;
return 0;
}
@@ -41,7 +46,52 @@ int UPP_While(void)
return 0;
}
+// ПРЕРЫВАНИЯ stm32f4xx_it.c
+
void UPP_ADC_Handle(void)
{
- PowerMonitor_Handle(&pm);
+ PowerMonitor_Handle(&upp.pm);
+
+ for(int phase = 0; phase < 3; phase++)
+ {
+ // Если произошел 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, upp.hpwm.Config.Frequency);
+ }
+ }
+}
+void UPP_PWM_Handle(void)
+{
+ PWM_Handle(&upp.hpwm);
+}
+
+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);
+ 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 5ba7672..54b3f56 100644
--- a/UPP/Core/UPP/upp_main.h
+++ b/UPP/Core/UPP/upp_main.h
@@ -11,7 +11,19 @@
#include "main.h" // либы из AllLibs и вербальные имена из CubeMX
#include "upp_config.h"
+#include "power_monitor.h" // статистика сети и АЦП
+#include "pwm_thyristors.h" // Управление тиристорами
+#include "angle_control.h" // Управление углом открытия
+extern float alpha_dbg;
+
+typedef struct
+{
+ PowerMonitor_t pm;
+ PWM_Handle_t hpwm;
+ Angle_Handle_t hangle;
+}UPP_t;
+extern UPP_t upp;
/* Инициализация УПП */
@@ -22,4 +34,6 @@ int UPP_PreWhile(void);
int UPP_While(void);
void UPP_ADC_Handle(void);
+void UPP_PWM_Handle(void);
+void UPP_Angle_Handle(void);
#endif //_UPP_MAIN_H
\ No newline at end of file
diff --git a/UPP/MDK-ARM/UPP.uvoptx b/UPP/MDK-ARM/UPP.uvoptx
index ba12a47..7736db4 100644
--- a/UPP/MDK-ARM/UPP.uvoptx
+++ b/UPP/MDK-ARM/UPP.uvoptx
@@ -327,6 +327,54 @@
0
0
+
+ 2
+ 12
+ 1
+ 0
+ 0
+ 0
+ ..\Core\UPP\pwm_thyristors.c
+ pwm_thyristors.c
+ 0
+ 0
+
+
+ 2
+ 13
+ 5
+ 0
+ 0
+ 0
+ ..\Core\UPP\pwm_thyristors.h
+ pwm_thyristors.h
+ 0
+ 0
+
+
+ 2
+ 14
+ 1
+ 0
+ 0
+ 0
+ ..\Core\UPP\angle_control.c
+ angle_control.c
+ 0
+ 0
+
+
+ 2
+ 15
+ 5
+ 0
+ 0
+ 0
+ ..\Core\UPP\angle_control.h
+ angle_control.h
+ 0
+ 0
+
@@ -337,7 +385,7 @@
0
3
- 12
+ 16
1
0
0
@@ -349,7 +397,7 @@
3
- 13
+ 17
5
0
0
@@ -361,7 +409,7 @@
3
- 14
+ 18
1
0
0
@@ -373,7 +421,7 @@
3
- 15
+ 19
5
0
0
@@ -385,7 +433,7 @@
3
- 16
+ 20
1
0
0
@@ -397,7 +445,7 @@
3
- 17
+ 21
5
0
0
@@ -409,14 +457,6 @@
-
- Thyristors
- 0
- 0
- 0
- 0
-
-
Application/User/Core
1
@@ -424,8 +464,8 @@
0
0
- 5
- 18
+ 4
+ 22
1
0
0
@@ -436,8 +476,8 @@
0
- 5
- 19
+ 4
+ 23
1
0
0
@@ -448,8 +488,8 @@
0
- 5
- 20
+ 4
+ 24
1
0
0
@@ -460,8 +500,8 @@
0
- 5
- 21
+ 4
+ 25
1
0
0
@@ -472,8 +512,8 @@
0
- 5
- 22
+ 4
+ 26
1
0
0
@@ -484,8 +524,8 @@
0
- 5
- 23
+ 4
+ 27
1
0
0
@@ -496,8 +536,8 @@
0
- 5
- 24
+ 4
+ 28
1
0
0
@@ -508,8 +548,8 @@
0
- 5
- 25
+ 4
+ 29
1
0
0
@@ -520,8 +560,8 @@
0
- 5
- 26
+ 4
+ 30
1
0
0
@@ -532,8 +572,8 @@
0
- 5
- 27
+ 4
+ 31
1
0
0
@@ -544,8 +584,8 @@
0
- 5
- 28
+ 4
+ 32
1
0
0
@@ -556,8 +596,8 @@
0
- 5
- 29
+ 4
+ 33
1
0
0
@@ -568,8 +608,8 @@
0
- 5
- 30
+ 4
+ 34
1
0
0
@@ -588,8 +628,8 @@
0
0
- 6
- 31
+ 5
+ 35
5
0
0
@@ -600,8 +640,8 @@
0
- 6
- 32
+ 5
+ 36
5
0
0
@@ -612,8 +652,8 @@
0
- 6
- 33
+ 5
+ 37
5
0
0
@@ -624,8 +664,8 @@
0
- 6
- 34
+ 5
+ 38
5
0
0
@@ -636,8 +676,8 @@
0
- 6
- 35
+ 5
+ 39
5
0
0
@@ -648,8 +688,8 @@
0
- 6
- 36
+ 5
+ 40
5
0
0
@@ -660,8 +700,8 @@
0
- 6
- 37
+ 5
+ 41
1
0
0
@@ -672,8 +712,8 @@
0
- 6
- 38
+ 5
+ 42
5
0
0
@@ -692,8 +732,8 @@
0
0
- 7
- 39
+ 6
+ 43
1
0
0
@@ -704,8 +744,8 @@
0
- 7
- 40
+ 6
+ 44
1
0
0
@@ -716,8 +756,8 @@
0
- 7
- 41
+ 6
+ 45
1
0
0
@@ -728,8 +768,8 @@
0
- 7
- 42
+ 6
+ 46
1
0
0
@@ -740,8 +780,8 @@
0
- 7
- 43
+ 6
+ 47
1
0
0
@@ -752,8 +792,8 @@
0
- 7
- 44
+ 6
+ 48
1
0
0
@@ -764,8 +804,8 @@
0
- 7
- 45
+ 6
+ 49
1
0
0
@@ -776,8 +816,8 @@
0
- 7
- 46
+ 6
+ 50
1
0
0
@@ -788,8 +828,8 @@
0
- 7
- 47
+ 6
+ 51
1
0
0
@@ -800,8 +840,8 @@
0
- 7
- 48
+ 6
+ 52
1
0
0
@@ -812,8 +852,8 @@
0
- 7
- 49
+ 6
+ 53
1
0
0
@@ -824,8 +864,8 @@
0
- 7
- 50
+ 6
+ 54
1
0
0
@@ -844,8 +884,8 @@
0
0
- 8
- 51
+ 7
+ 55
1
0
0
@@ -856,8 +896,8 @@
0
- 8
- 52
+ 7
+ 56
1
0
0
@@ -871,13 +911,13 @@
PeriphGeneral
- 0
+ 1
0
0
0
- 9
- 53
+ 8
+ 57
1
0
0
@@ -888,8 +928,8 @@
0
- 9
- 54
+ 8
+ 58
1
0
0
@@ -900,8 +940,8 @@
0
- 9
- 55
+ 8
+ 59
1
0
0
@@ -912,8 +952,8 @@
0
- 9
- 56
+ 8
+ 60
1
0
0
@@ -924,8 +964,8 @@
0
- 9
- 57
+ 8
+ 61
1
0
0
@@ -944,8 +984,8 @@
0
0
- 10
- 58
+ 9
+ 62
1
0
0
@@ -956,8 +996,8 @@
0
- 10
- 59
+ 9
+ 63
1
0
0
@@ -968,8 +1008,8 @@
0
- 10
- 60
+ 9
+ 64
1
0
0
@@ -980,8 +1020,8 @@
0
- 10
- 61
+ 9
+ 65
1
0
0
@@ -992,8 +1032,8 @@
0
- 10
- 62
+ 9
+ 66
1
0
0
@@ -1004,8 +1044,8 @@
0
- 10
- 63
+ 9
+ 67
1
0
0
@@ -1016,8 +1056,8 @@
0
- 10
- 64
+ 9
+ 68
1
0
0
@@ -1028,8 +1068,8 @@
0
- 10
- 65
+ 9
+ 69
1
0
0
@@ -1040,8 +1080,8 @@
0
- 10
- 66
+ 9
+ 70
1
0
0
@@ -1052,8 +1092,8 @@
0
- 10
- 67
+ 9
+ 71
1
0
0
@@ -1064,8 +1104,8 @@
0
- 10
- 68
+ 9
+ 72
1
0
0
@@ -1076,8 +1116,8 @@
0
- 10
- 69
+ 9
+ 73
1
0
0
@@ -1088,8 +1128,8 @@
0
- 10
- 70
+ 9
+ 74
1
0
0
@@ -1100,8 +1140,8 @@
0
- 10
- 71
+ 9
+ 75
1
0
0
@@ -1112,8 +1152,8 @@
0
- 10
- 72
+ 9
+ 76
1
0
0
@@ -1124,8 +1164,8 @@
0
- 10
- 73
+ 9
+ 77
1
0
0
@@ -1136,8 +1176,8 @@
0
- 10
- 74
+ 9
+ 78
1
0
0
@@ -1148,8 +1188,8 @@
0
- 10
- 75
+ 9
+ 79
1
0
0
@@ -1160,8 +1200,8 @@
0
- 10
- 76
+ 9
+ 80
1
0
0
@@ -1172,8 +1212,8 @@
0
- 10
- 77
+ 9
+ 81
1
0
0
@@ -1184,8 +1224,8 @@
0
- 10
- 78
+ 9
+ 82
1
0
0
@@ -1196,8 +1236,8 @@
0
- 10
- 79
+ 9
+ 83
1
0
0
@@ -1208,8 +1248,8 @@
0
- 10
- 80
+ 9
+ 84
1
0
0
@@ -1220,8 +1260,8 @@
0
- 10
- 81
+ 9
+ 85
1
0
0
@@ -1240,8 +1280,8 @@
0
0
- 11
- 82
+ 10
+ 86
1
0
0
@@ -1260,8 +1300,8 @@
0
0
- 12
- 83
+ 11
+ 87
2
0
0
diff --git a/UPP/MDK-ARM/UPP.uvprojx b/UPP/MDK-ARM/UPP.uvprojx
index 6284731..585e041 100644
--- a/UPP/MDK-ARM/UPP.uvprojx
+++ b/UPP/MDK-ARM/UPP.uvprojx
@@ -445,6 +445,26 @@
5
..\Core\UPP\upp_main.h
+
+ pwm_thyristors.c
+ 1
+ ..\Core\UPP\pwm_thyristors.c
+
+
+ pwm_thyristors.h
+ 5
+ ..\Core\UPP\pwm_thyristors.h
+
+
+ angle_control.c
+ 1
+ ..\Core\UPP\angle_control.c
+
+
+ angle_control.h
+ 5
+ ..\Core\UPP\angle_control.h
+
@@ -482,9 +502,6 @@
-
- Thyristors
-
Application/User/Core
diff --git a/UPP/UPP.ioc b/UPP/UPP.ioc
index af2d530..5ed5897 100644
--- a/UPP/UPP.ioc
+++ b/UPP/UPP.ioc
@@ -54,13 +54,14 @@ Mcu.CPN=STM32F427ZGT6
Mcu.Family=STM32F4
Mcu.IP0=ADC3
Mcu.IP1=CAN1
-Mcu.IP10=TIM3
-Mcu.IP11=TIM5
-Mcu.IP12=TIM8
-Mcu.IP13=TIM11
-Mcu.IP14=TIM12
-Mcu.IP15=USART3
-Mcu.IP16=USART6
+Mcu.IP10=TIM2
+Mcu.IP11=TIM3
+Mcu.IP12=TIM5
+Mcu.IP13=TIM8
+Mcu.IP14=TIM11
+Mcu.IP15=TIM12
+Mcu.IP16=USART3
+Mcu.IP17=USART6
Mcu.IP2=DMA
Mcu.IP3=IWDG
Mcu.IP4=NVIC
@@ -69,7 +70,7 @@ Mcu.IP6=RTC
Mcu.IP7=SPI3
Mcu.IP8=SYS
Mcu.IP9=TIM1
-Mcu.IPNb=17
+Mcu.IPNb=18
Mcu.Name=STM32F427Z(G-I)Tx
Mcu.Package=LQFP144
Mcu.Pin0=PE2
@@ -127,17 +128,25 @@ Mcu.Pin55=VP_RTC_VS_RTC_Activate
Mcu.Pin56=VP_RTC_VS_RTC_Calendar
Mcu.Pin57=VP_SYS_VS_tim14
Mcu.Pin58=VP_TIM1_VS_ClockSourceINT
-Mcu.Pin59=VP_TIM3_VS_ClockSourceINT
+Mcu.Pin59=VP_TIM1_VS_OPM
Mcu.Pin6=PC14/OSC32_IN
-Mcu.Pin60=VP_TIM8_VS_ClockSourceINT
-Mcu.Pin61=VP_TIM11_VS_ClockSourceINT
-Mcu.Pin62=VP_TIM12_VS_ClockSourceINT
+Mcu.Pin60=VP_TIM2_VS_ClockSourceINT
+Mcu.Pin61=VP_TIM2_VS_no_output1
+Mcu.Pin62=VP_TIM2_VS_no_output2
+Mcu.Pin63=VP_TIM2_VS_no_output3
+Mcu.Pin64=VP_TIM3_VS_ControllerModeTrigger
+Mcu.Pin65=VP_TIM3_VS_ClockSourceINT
+Mcu.Pin66=VP_TIM3_VS_ClockSourceITR
+Mcu.Pin67=VP_TIM3_VS_OPM
+Mcu.Pin68=VP_TIM8_VS_ClockSourceINT
+Mcu.Pin69=VP_TIM11_VS_ClockSourceINT
Mcu.Pin7=PC15/OSC32_OUT
+Mcu.Pin70=VP_TIM12_VS_ClockSourceINT
Mcu.Pin8=PF6
Mcu.Pin9=PF7
-Mcu.PinsNb=63
+Mcu.PinsNb=71
Mcu.ThirdPartyNb=0
-Mcu.UserConstants=mb_huart,huart3;mbdbg_htim,htim11;PWM_CHANNEL_1,TIM_CHANNEL_1;PWM_CHANNEL_2,TIM_CHANNEL_2;PWM_CHANNEL_3,TIM_CHANNEL_3;PWM_CHANNEL_4,TIM_CHANNEL_4;mem_hspi,hspi3;PWM_CHANNEL_5,TIM_CHANNEL_3;PWM_CHANNEL_6,TIM_CHANNEL_4;mb_htim,htim12;adc_tim,htim8;hpwm2,htim2;mb_dbg_huart,huart6;ustim,htim5;hpwm1,htim1;usTick,ustim.Instance->CNT
+Mcu.UserConstants=mb_huart,huart3;mbdbg_htim,htim11;PWM_CHANNEL_1,TIM_CHANNEL_1;PWM_CHANNEL_2,TIM_CHANNEL_2;PWM_CHANNEL_3,TIM_CHANNEL_3;PWM_CHANNEL_4,TIM_CHANNEL_4;mem_hspi,hspi3;PWM_CHANNEL_5,TIM_CHANNEL_3;PWM_CHANNEL_6,TIM_CHANNEL_4;mb_htim,htim12;adc_tim,htim8;usTick,ustim.Instance->CNT;hpwm2,htim3;mb_dbg_huart,huart6;ustim,htim5;hpwm1,htim1;ANGLE_CHANNEL_1,TIM_CHANNEL_1;ANGLE_CHANNEL_2,TIM_CHANNEL_2;ANGLE_CHANNEL_3,TIM_CHANNEL_3;angletim,htim2
Mcu.UserName=STM32F427ZGTx
MxCube.Version=6.12.1
MxDb.Version=DB.6.0.121
@@ -152,6 +161,8 @@ NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false
+NVIC.TIM1_UP_TIM10_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
+NVIC.TIM2_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.TIM8_TRG_COM_TIM14_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:true
NVIC.TimeBase=TIM8_TRG_COM_TIM14_IRQn
NVIC.TimeBaseIP=TIM14
@@ -395,7 +406,7 @@ ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath=
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_TIM13_Init-TIM13-false-HAL-true,8-MX_RTC_Init-RTC-false-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
+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-false-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.AHBFreq_Value=180000000
RCC.APB1CLKDivider=RCC_HCLK_DIV4
@@ -461,19 +472,30 @@ SPI3.Direction=SPI_DIRECTION_2LINES
SPI3.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate
SPI3.Mode=SPI_MODE_MASTER
SPI3.VirtualType=VM_MASTER
+TIM1.Channel-Output\ Compare2\ CH2=TIM_CHANNEL_2
TIM1.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
TIM1.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
TIM1.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
TIM1.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4
-TIM1.IPParameters=Channel-PWM Generation1 CH1,Channel-PWM Generation2 CH2,Channel-PWM Generation3 CH3,Channel-PWM Generation4 CH4,Prescaler
-TIM1.Prescaler=180-1
+TIM1.IPParameters=Prescaler,Channel-Output Compare2 CH2,Channel-PWM Generation1 CH1,Channel-PWM Generation2 CH2,Channel-PWM Generation4 CH4,Channel-PWM Generation3 CH3,TIM_MasterOutputTrigger
+TIM1.Prescaler=0
+TIM1.TIM_MasterOutputTrigger=TIM_TRGO_UPDATE
TIM11.IPParameters=Prescaler
TIM11.Prescaler=180-1
TIM12.IPParameters=Prescaler
TIM12.Prescaler=90-1
+TIM2.Channel-Output\ Compare1\ No\ Output=TIM_CHANNEL_1
+TIM2.Channel-Output\ Compare2\ No\ Output=TIM_CHANNEL_2
+TIM2.Channel-Output\ Compare3\ No\ Output=TIM_CHANNEL_3
+TIM2.IPParameters=Channel-Output Compare2 No Output,Channel-Output Compare1 No Output,Channel-Output Compare3 No Output,OCMode_1,OCMode_2,OCMode_3
+TIM2.OCMode_1=TIM_OCMODE_TIMING
+TIM2.OCMode_2=TIM_OCMODE_TIMING
+TIM2.OCMode_3=TIM_OCMODE_TIMING
TIM3.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
TIM3.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4
-TIM3.IPParameters=Channel-PWM Generation3 CH3,Channel-PWM Generation4 CH4
+TIM3.IPParameters=Channel-PWM Generation3 CH3,Channel-PWM Generation4 CH4,TIM_MasterSlaveMode,TIM_MasterOutputTrigger
+TIM3.TIM_MasterOutputTrigger=TIM_TRGO_RESET
+TIM3.TIM_MasterSlaveMode=TIM_MASTERSLAVEMODE_ENABLE
TIM5.Channel-Input_Capture1_from_TI1=TIM_CHANNEL_1
TIM5.IPParameters=Channel-Input_Capture1_from_TI1,Prescaler
TIM5.Prescaler=90-1
@@ -500,8 +522,24 @@ VP_TIM12_VS_ClockSourceINT.Mode=Internal
VP_TIM12_VS_ClockSourceINT.Signal=TIM12_VS_ClockSourceINT
VP_TIM1_VS_ClockSourceINT.Mode=Internal
VP_TIM1_VS_ClockSourceINT.Signal=TIM1_VS_ClockSourceINT
+VP_TIM1_VS_OPM.Mode=OPM_bit
+VP_TIM1_VS_OPM.Signal=TIM1_VS_OPM
+VP_TIM2_VS_ClockSourceINT.Mode=Internal
+VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT
+VP_TIM2_VS_no_output1.Mode=Output Compare1 No Output
+VP_TIM2_VS_no_output1.Signal=TIM2_VS_no_output1
+VP_TIM2_VS_no_output2.Mode=Output Compare2 No Output
+VP_TIM2_VS_no_output2.Signal=TIM2_VS_no_output2
+VP_TIM2_VS_no_output3.Mode=Output Compare3 No Output
+VP_TIM2_VS_no_output3.Signal=TIM2_VS_no_output3
VP_TIM3_VS_ClockSourceINT.Mode=Internal
VP_TIM3_VS_ClockSourceINT.Signal=TIM3_VS_ClockSourceINT
+VP_TIM3_VS_ClockSourceITR.Mode=TriggerSource_ITR0
+VP_TIM3_VS_ClockSourceITR.Signal=TIM3_VS_ClockSourceITR
+VP_TIM3_VS_ControllerModeTrigger.Mode=Trigger Mode
+VP_TIM3_VS_ControllerModeTrigger.Signal=TIM3_VS_ControllerModeTrigger
+VP_TIM3_VS_OPM.Mode=OPM_bit
+VP_TIM3_VS_OPM.Signal=TIM3_VS_OPM
VP_TIM8_VS_ClockSourceINT.Mode=Internal
VP_TIM8_VS_ClockSourceINT.Signal=TIM8_VS_ClockSourceINT
board=custom