#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; #ifdef SIMULATION_MODE_XILINX XilinkTkPhaseSimHandle XilinxTkPhaseA1; XilinkTkPhaseSimHandle XilinxTkPhaseB1; XilinkTkPhaseSimHandle XilinxTkPhaseC1; XilinkTkPhaseSimHandle XilinxTkPhaseA2; XilinkTkPhaseSimHandle XilinxTkPhaseB2; XilinkTkPhaseSimHandle XilinxTkPhaseC2; #endif void Simulate_Timers(void) { SimulateMainPWM(&t1sim, xpwm_time.Ta0_1); SimulateSimplePWM(&t2sim, xpwm_time.Ta0_0); SimulateSimplePWM(&t3sim, xpwm_time.Tb0_1); SimulateSimplePWM(&t4sim, xpwm_time.Tb0_0); SimulateSimplePWM(&t5sim, xpwm_time.Tc0_1); SimulateSimplePWM(&t6sim, xpwm_time.Tc0_0); SimulateSimplePWM(&t7sim, xpwm_time.Ta1_1); SimulateSimplePWM(&t8sim, xpwm_time.Ta1_0); SimulateSimplePWM(&t9sim, xpwm_time.Tb1_1); SimulateSimplePWM(&t10sim, xpwm_time.Tb1_0); SimulateSimplePWM(&t11sim, xpwm_time.Tc1_1); SimulateSimplePWM(&t12sim, xpwm_time.Tc1_0); } void Init_Timers(void) { initSimulateTim(&t1sim, FREQ_INTERNAL_GENERATOR_XILINX_TMS / FREQ_PWM, FREQ_INTERNAL_GENERATOR_XILINX_TMS * hmcu.sSimSampleTime); initSimulateTim(&t2sim, FREQ_INTERNAL_GENERATOR_XILINX_TMS / FREQ_PWM, FREQ_INTERNAL_GENERATOR_XILINX_TMS * hmcu.sSimSampleTime); initSimulateTim(&t3sim, FREQ_INTERNAL_GENERATOR_XILINX_TMS / FREQ_PWM, FREQ_INTERNAL_GENERATOR_XILINX_TMS * hmcu.sSimSampleTime); initSimulateTim(&t4sim, FREQ_INTERNAL_GENERATOR_XILINX_TMS / FREQ_PWM, FREQ_INTERNAL_GENERATOR_XILINX_TMS * hmcu.sSimSampleTime); initSimulateTim(&t5sim, FREQ_INTERNAL_GENERATOR_XILINX_TMS / FREQ_PWM, FREQ_INTERNAL_GENERATOR_XILINX_TMS * hmcu.sSimSampleTime); initSimulateTim(&t6sim, FREQ_INTERNAL_GENERATOR_XILINX_TMS / FREQ_PWM, FREQ_INTERNAL_GENERATOR_XILINX_TMS * hmcu.sSimSampleTime); initSimulateTim(&t7sim, FREQ_INTERNAL_GENERATOR_XILINX_TMS / FREQ_PWM, FREQ_INTERNAL_GENERATOR_XILINX_TMS * hmcu.sSimSampleTime); initSimulateTim(&t8sim, FREQ_INTERNAL_GENERATOR_XILINX_TMS / FREQ_PWM, FREQ_INTERNAL_GENERATOR_XILINX_TMS * hmcu.sSimSampleTime); initSimulateTim(&t9sim, FREQ_INTERNAL_GENERATOR_XILINX_TMS / FREQ_PWM, FREQ_INTERNAL_GENERATOR_XILINX_TMS * hmcu.sSimSampleTime); initSimulateTim(&t10sim, FREQ_INTERNAL_GENERATOR_XILINX_TMS / FREQ_PWM, FREQ_INTERNAL_GENERATOR_XILINX_TMS * hmcu.sSimSampleTime); initSimulateTim(&t11sim, FREQ_INTERNAL_GENERATOR_XILINX_TMS / FREQ_PWM, FREQ_INTERNAL_GENERATOR_XILINX_TMS * hmcu.sSimSampleTime); initSimulateTim(&t12sim, FREQ_INTERNAL_GENERATOR_XILINX_TMS / FREQ_PWM, FREQ_INTERNAL_GENERATOR_XILINX_TMS * hmcu.sSimSampleTime); } void Init_Xilinx(XilinkTkPhaseSimHandle tksim) { initSimulateTim(&t1sim, FREQ_INTERNAL_GENERATOR_XILINX_TMS / FREQ_PWM, FREQ_INTERNAL_GENERATOR_XILINX_TMS * hmcu.sSimSampleTime); initSimulateTim(&t2sim, FREQ_INTERNAL_GENERATOR_XILINX_TMS / FREQ_PWM, FREQ_INTERNAL_GENERATOR_XILINX_TMS * hmcu.sSimSampleTime); } void initSimulateTim(TimerSimHandle* tsim, int period, double step) { tsim->dtsim.stateDt = 1; tsim->TPr = period; tsim->TxCntPlus = step * 2; tsim->dtsim.DtCntPeriod = (int)(DT / hmcu.sSimSampleTime); } void SimulateMainPWM(TimerSimHandle* tsim, int compare) { #ifdef UNITED_COUNTER tsim->tcntAuxPrev = tsim->tcntAux; tsim->tcntAux += tsim->TxCntPlus; #endif if (simulateTimAndGetCompare(tsim, compare)) mcu_simulate_step(); #ifdef SIMULATION_MODE_REGULAR_PWM simulateActionActionQualifierSubmodule(tsim); simulateDeadBendSubmodule(tsim); simulateTripZoneSubmodule(tsim); #endif } void SimulateSimplePWM(TimerSimHandle* tsim, int compare) { simulateTimAndGetCompare(tsim, compare, 0); simulateActionActionQualifierSubmodule(tsim); #ifdef SIMULATION_MODE_REGULAR_PWM simulateActionActionQualifierSubmodule(tsim); simulateDeadBendSubmodule(tsim); simulateTripZoneSubmodule(tsim); #endif } int simulateTimAndGetCompare(TimerSimHandle* tsim, int compare) { int interruptflag = 0; #ifdef UNITED_COUNTER tsim->tcntAuxPrev = t1sim.tcntAuxPrev; tsim->tcntAux = t1sim.tcntAux; #else tsim->tcntAuxPrev = tsim->tcntAux; tsim->tcntAux += tsim->TxCntPlus; #endif if (tsim->tcntAux > tsim->TPr) { tsim->tcntAux -= tsim->TPr * 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(XilinkTkPhaseSimHandle *tksim) { TimerSimHandle* tsim1 = tksim->tsim1; TimerSimHandle* tsim2 = tksim->tsim2; //Phase Uni if ((tsim1->cmpA < tsim1->tcnt) && (tsim2->cmpA < tsim2->tcnt)) { tsim1->tkLine = 0; tsim2->tkLine = 1; } else if ((tsim1->cmpA > tsim1->tcnt) && (tsim2->cmpA > tsim2->tcnt)) { tsim1->tkLine = 1; tsim2->tkLine = 0; } else if ((tsim1->cmpA < tsim1->tcnt) && (tsim2->cmpA > tsim2->tcnt)) { //Ошибка. Задание на открытие верхних и нижних ключей одновременно. Закрываем. tsim1->tkLine = 1; tsim2->tkLine = 1; } else { tsim1->tkLine = 0; tsim2->tkLine = 1; } } void xilinxPwm3LevelSimulation(XilinkTkPhaseSimHandle *tksim) { TimerSimHandle* tsim1 = tksim->tsim1; TimerSimHandle* tsim2 = tksim->tsim2; //Преобразуем состояние линий ТК в сигналы управления ключами //PhaseA Uni1 if (tsim1->tkLine == 0 && tsim2->tkLine == 1) { if ((tsim1->ciA == 0 || tsim1->ciB == 0) && tksim->dtsim.stateDt == stateDtReady) { tsim2->ciA = 0; tsim2->ciB = 0; tksim->dtsim.dtcnt = tksim->dtsim.DtCntPeriod; tksim->dtsim.stateDt = stateDtWait; } if (tksim->dtsim.stateDt == stateDtWait) { if (tksim->dtsim.dtcnt > 0) tksim->dtsim.dtcnt--; else tksim->dtsim.stateDt = stateDtReady; } if (tksim->dtsim.stateDt == stateDtReady) { tsim1->ciA = 1; tsim1->ciB = 1; tsim2->ciA = 0; tsim2->ciB = 0; } } else if (tsim1->tkLine == 1 && tsim2->tkLine == 0) { if ((tsim2->ciA == 0 || tsim2->ciB == 0) && tksim->dtsim.stateDt == stateDtReady) { tsim1->ciA = 0; tsim1->ciB = 0; tksim->dtsim.dtcnt = tksim->dtsim.DtCntPeriod; tksim->dtsim.stateDt = stateDtWait; } if (tksim->dtsim.stateDt == stateDtWait) { if (tksim->dtsim.dtcnt > 0) tksim->dtsim.dtcnt--; else tksim->dtsim.stateDt = stateDtReady; } if (tksim->dtsim.stateDt == stateDtReady) { tsim1->ciA = 0; tsim1->ciB = 0; tsim2->ciA = 1; tsim2->ciB = 1; } } else if (tsim1->tkLine == 0 && tsim2->tkLine == 0) { if ((tsim1->ciB == 0 || tsim2->ciA == 0) && tksim->dtsim.stateDt == stateDtReady) { tsim1->ciA = 0; tsim2->ciB = 0; tksim->dtsim.dtcnt = tksim->dtsim.DtCntPeriod; tksim->dtsim.stateDt = stateDtWait; } if (tksim->dtsim.stateDt == stateDtWait) { if (tksim->dtsim.dtcnt > 0) tksim->dtsim.dtcnt--; else tksim->dtsim.stateDt = stateDtReady; } if (tksim->dtsim.stateDt == stateDtReady) { tsim1->ciA = 0; tsim1->ciB = 1; tsim2->ciA = 1; tsim2->ciB = 0; } } else { tsim1->ciA = 0; tsim1->ciB = 0; tsim2->ciA = 0; tsim2->ciB = 0; } } void simulateActionActionQualifierSubmodule(TimerSimHandle* tsim) { // Моделируем Action-Qualifier Submodule if (tsim->cmpA > tsim->tcnt) { tsim->dtsim.pre_ciA = 0; tsim->dtsim.pre_ciB = 1; } else if (tsim->cmpA < tsim->tcnt) { tsim->dtsim.pre_ciA = 1; tsim->dtsim.pre_ciB = 0; } } void simulateDeadBendSubmodule(TimerSimHandle* tsim) { // Моделируем Dead-Band Submodule if (tsim->dtsim.stateDt == 1) { tsim->ciA = tsim->dtsim.pre_ciA; tsim->ciB = 0; if (tsim->dtsim.pre_ciA == 1) tsim->dtsim.dtcnt = tsim->dtsim.DtCntPeriod; if (tsim->dtsim.dtcnt > 0) tsim->dtsim.dtcnt--; else tsim->dtsim.stateDt = 2; } else if (tsim->dtsim.stateDt == 2) { tsim->ciA = 0; tsim->ciB = tsim->dtsim.pre_ciB; if (tsim->dtsim.pre_ciB == 1) tsim->dtsim.dtcnt = tsim->dtsim.DtCntPeriod; if (tsim->dtsim.dtcnt > 0) tsim->dtsim.dtcnt--; else tsim->dtsim.stateDt = 1; } } 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; }