#include "pwm_sim.h" TimerSimHandle t1sim; TimerSimHandle t2sim; TimerSimHandle t3sim; TimerSimHandle t4sim; TimerSimHandle t5sim; TimerSimHandle t6sim; TimerSimHandle t7sim; TimerSimHandle t8sim; TimerSimHandle t9sim; TimerSimHandle t10sim; TimerSimHandle t11sim; TimerSimHandle t12sim; PWMPhaseSimHandle PWMPhaseA1; PWMPhaseSimHandle PWMPhaseB1; PWMPhaseSimHandle PWMPhaseC1; PWMPhaseSimHandle PWMPhaseA2; PWMPhaseSimHandle PWMPhaseB2; PWMPhaseSimHandle PWMPhaseC2; void Simulate_PWM(void) { Simulate_PWMPhase(&PWMPhaseA1, xpwm_time.Ta0_1, xpwm_time.Ta0_0); Simulate_PWMPhase(&PWMPhaseB1, xpwm_time.Tb0_1, xpwm_time.Tb0_0); Simulate_PWMPhase(&PWMPhaseC1, xpwm_time.Tc0_1, xpwm_time.Tc0_0); Simulate_PWMPhase(&PWMPhaseA2, xpwm_time.Ta1_1, xpwm_time.Ta1_0); Simulate_PWMPhase(&PWMPhaseB2, xpwm_time.Tb1_1, xpwm_time.Tb1_0); Simulate_PWMPhase(&PWMPhaseC2, xpwm_time.Tc1_1, xpwm_time.Tc1_0); } void Init_PWM_Simulation(void) { Init_PWMPhase_Simulation(&PWMPhaseA1, &t1sim, &t2sim, PWM_PERIOD, PWM_TICK_STEP); Init_PWMPhase_Simulation(&PWMPhaseB1, &t3sim, &t4sim, PWM_PERIOD, PWM_TICK_STEP); Init_PWMPhase_Simulation(&PWMPhaseC1, &t5sim, &t6sim, PWM_PERIOD, PWM_TICK_STEP); Init_PWMPhase_Simulation(&PWMPhaseA2, &t7sim, &t8sim, PWM_PERIOD, PWM_TICK_STEP); Init_PWMPhase_Simulation(&PWMPhaseB2, &t9sim, &t10sim, PWM_PERIOD, PWM_TICK_STEP); Init_PWMPhase_Simulation(&PWMPhaseC2, &t11sim, &t12sim, PWM_PERIOD, PWM_TICK_STEP); t1sim.simulatePwm = (void (*)())Simulate_MainTIM; } void Simulate_PWMPhase(PWMPhaseSimHandle* tksim, int T1, int T0) { tksim->tsim1->simulatePwm(tksim->tsim1, T1); tksim->tsim2->simulatePwm(tksim->tsim2, T0); #ifdef PWM_SIMULATION_MODE_TK_LINES convertSVGenTimesToTkLines(tksim); xilinxPwm3LevelSimulation(tksim); #endif #ifdef PWM_SIMULATION_MODE_REGULAR_PWM simulateActionActionQualifierSubmodule(tksim->tsim1); simulateDeadBendSubmodule(tksim->tsim1, &tksim->pwmOut.ci1A, &tksim->pwmOut.ci1B); simulateTripZoneSubmodule(tksim->tsim1); simulateActionActionQualifierSubmodule(tksim->tsim2); simulateDeadBendSubmodule(tksim->tsim2, &tksim->pwmOut.ci2A, &tksim->pwmOut.ci2B); simulateTripZoneSubmodule(tksim->tsim2); #endif } void Simulate_MainTIM(TimerSimHandle* tsim, int compare) { #ifdef ENABLE_UNITED_COUNTER_FOR_ALL_PWM tsim->tcntAuxPrev = tsim->tcntAux; tsim->tcntAux += tsim->TxCntPlus; #endif if (simulateTimAndGetCompare(tsim, compare)) mcu_simulate_step(); } void Simulate_SimpleTIM(TimerSimHandle* tsim, int compare) { simulateTimAndGetCompare(tsim, compare); } int simulateTimAndGetCompare(TimerSimHandle* tsim, int compare) { int interruptflag = 0; #ifdef ENABLE_UNITED_COUNTER_FOR_ALL_PWM tsim->tcntAuxPrev = t1sim.tcntAuxPrev; tsim->tcntAux = t1sim.tcntAux; #else tsim->tcntAuxPrev = tsim->tcntAux; tsim->tcntAux += tsim->TxCntPlus; #endif if (tsim->tcntAux > tsim->TxPeriod) { tsim->tcntAux -= tsim->TxPeriod * 2.; tsim->cmpA = compare; interruptflag = 1; } if ((tsim->tcntAuxPrev < 0) && (tsim->tcntAux >= 0)) { tsim->cmpA = compare; interruptflag = 1; } tsim->tcnt = fabs(tsim->tcntAux); return interruptflag; } void convertSVGenTimesToTkLines(PWMPhaseSimHandle *tksim) { TimerSimHandle* tsim1 = tksim->tsim1; TimerSimHandle* tsim2 = tksim->tsim2; //Phase Uni if ((tsim1->cmpA < tsim1->tcnt) && (tsim2->cmpA < tsim2->tcnt)) { tksim->tkLineA = 0; tksim->tkLineB = 1; } else if ((tsim1->cmpA > tsim1->tcnt) && (tsim2->cmpA > tsim2->tcnt)) { tksim->tkLineA = 1; tksim->tkLineB = 0; } else if ((tsim1->cmpA < tsim1->tcnt) && (tsim2->cmpA > tsim2->tcnt)) { //Ошибка. Задание на открытие верхних и нижних ключей одновременно. Закрываем. tksim->tkLineA = 1; tksim->tkLineB = 1; } else { tksim->tkLineA = 0; tksim->tkLineB = 0; } } void xilinxPwm3LevelSimulation(PWMPhaseSimHandle *tksim) { TimerSimHandle* tsim1 = tksim->tsim1; TimerSimHandle* tsim2 = tksim->tsim2; DeadTimeSimHandle* deadtime = &tksim->deadtime; PWMPhaseOutput* pwmOut = &tksim->pwmOut; //Преобразуем состояние линий ТК в сигналы управления ключами //PhaseA Uni1 if (tksim->tkLineB == 0 && tksim->tkLineA == 1) { if ((pwmOut->ci1A == 0 || pwmOut->ci2A == 0) && deadtime->stateDt == stateDtReady) { pwmOut->ci1B = 0; pwmOut->ci2B = 0; deadtime->dtcnt = deadtime->DtPeriod; deadtime->stateDt = stateDtWait; } if (deadtime->stateDt == stateDtWait) { if (deadtime->dtcnt > 0) deadtime->dtcnt--; else deadtime->stateDt = stateDtReady; } if (deadtime->stateDt == stateDtReady) { pwmOut->ci1A = 1; pwmOut->ci2A = 1; pwmOut->ci1B = 0; pwmOut->ci2B = 0; } } else if (tksim->tkLineB == 1 && tksim->tkLineA == 0) { if ((pwmOut->ci1B == 0 || pwmOut->ci2B == 0) && deadtime->stateDt == stateDtReady) { pwmOut->ci1A = 0; pwmOut->ci2B = 0; deadtime->dtcnt = deadtime->DtPeriod; deadtime->stateDt = stateDtWait; } if (deadtime->stateDt == stateDtWait) { if (deadtime->dtcnt > 0) deadtime->dtcnt--; else deadtime->stateDt = stateDtReady; } if (deadtime->stateDt == stateDtReady) { pwmOut->ci1A = 0; pwmOut->ci2A = 0; pwmOut->ci1B = 1; pwmOut->ci2B = 1; } } else if (tksim->tkLineA == 0 && tksim->tkLineB == 0) { if ((pwmOut->ci1B == 0 || pwmOut->ci2A == 0) && deadtime->stateDt == stateDtReady) { pwmOut->ci1A = 0; pwmOut->ci2B = 0; deadtime->dtcnt = deadtime->DtPeriod; deadtime->stateDt = stateDtWait; } if (deadtime->stateDt == stateDtWait) { if (deadtime->dtcnt > 0) deadtime->dtcnt--; else deadtime->stateDt = stateDtReady; } if (deadtime->stateDt == stateDtReady) { pwmOut->ci1A = 0; pwmOut->ci2A = 1; pwmOut->ci1B = 1; pwmOut->ci2B = 0; } } else { pwmOut->ci1A = 0; pwmOut->ci2A = 0; pwmOut->ci1B = 0; pwmOut->ci2B = 0; } } void simulateActionActionQualifierSubmodule(TimerSimHandle* tsim) { // Моделируем Action-Qualifier Submodule if (tsim->cmpA > tsim->tcnt) { tsim->deadtime.pre_ciA = 0; tsim->deadtime.pre_ciB = 1; } else if (tsim->cmpA < tsim->tcnt) { tsim->deadtime.pre_ciA = 1; tsim->deadtime.pre_ciB = 0; } } void simulateDeadBendSubmodule(TimerSimHandle* tsim, int* ciA, int* ciB) { // Моделируем Dead-Band Submodule if (tsim->deadtime.stateDt == 0) { *ciA = tsim->deadtime.pre_ciA; *ciB = 0; if (tsim->deadtime.pre_ciA == 1) tsim->deadtime.dtcnt = tsim->deadtime.DtPeriod; if (tsim->deadtime.dtcnt > 0) tsim->deadtime.dtcnt--; else tsim->deadtime.stateDt = 1; } else if (tsim->deadtime.stateDt == 1) { *ciA = 0; *ciB = tsim->deadtime.pre_ciB; if (tsim->deadtime.pre_ciB == 1) tsim->deadtime.dtcnt = tsim->deadtime.DtPeriod; if (tsim->deadtime.dtcnt > 0) tsim->deadtime.dtcnt--; else tsim->deadtime.stateDt = 0; } } void simulateTripZoneSubmodule(TimerSimHandle* tsim) { // Моделируем Trip-Zone Submodule // ... clear flag for one-shot trip latch // // ... clear flag for one-shot trip latch //if (EPwm1Regs.TZCLR.all == 0x0004) { // EPwm1Regs.TZCLR.all = 0x0000; // EPwm1Regs.TZFRC.all = 0x0000; //} // ... forces a one-shot trip event //if (EPwm1Regs.TZFRC.all == 0x0004) // ci1A_DT = ci1B_DT = 0; } void Init_PWMPhase_Simulation(PWMPhaseSimHandle* tksim, TimerSimHandle* tsim1, TimerSimHandle* tsim2, int period, double step) { tksim->tsim1 = tsim1; tksim->tsim2 = tsim2; Init_TIM_Simulation(tksim->tsim1, period, step); Init_TIM_Simulation(tksim->tsim2, period, step); } void Init_TIM_Simulation(TimerSimHandle* tsim, int period, double step) { tsim->deadtime.stateDt = stateDtWait; tsim->TxPeriod = period; tsim->TxCntPlus = step * 2; tsim->deadtime.DtPeriod = (int)(DT / hmcu.sSimSampleTime); tsim->simulatePwm = (void (*)())Simulate_SimpleTIM; }