Other Parts Discussed in Thread: C2000WARE
Hi,
I'm trying to implement soft start on PWM. In this feature, I'm trying to increase the duty cycle of ePWM incrementally starting from 0% to the desired value. The module also contains other features like turning on and off complement mode, dead time. Below is my code for the same.
period_register = 60000/frequency;
rising_edge_dead_time_register = 120 * dead_time;
falling_edge_dead_time_register = rising_edge_dead_time_register;
compare_register = (((100 - duty_cycle)*(period_register * 0.01)) - (60 * dead_time));
if(complement_required){
GPIO_setPinConfig(GPIO_0_EPWM1_A);
GPIO_setPinConfig(GPIO_1_EPWM1_B);
EPWM_setDeadBandDelayPolarity(GATE_HB1_BASE, EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_LOW);
EPWM_setDeadBandDelayMode(GATE_HB1_BASE, EPWM_DB_RED, true);
EPWM_setDeadBandDelayMode(GATE_HB1_BASE, EPWM_DB_FED, true);
EPWM_setRisingEdgeDelayCount(GATE_HB1_BASE, rising_edge_dead_time_register);
EPWM_setFallingEdgeDelayCount(GATE_HB1_BASE, falling_edge_dead_time_register);
if(primary_pin == HS){
EPWM_setDeadBandOutputSwapMode(GATE_HB1_BASE, EPWM_DB_OUTPUT_A, false);
EPWM_setDeadBandOutputSwapMode(GATE_HB1_BASE, EPWM_DB_OUTPUT_B, false);
}
else{
EPWM_setDeadBandOutputSwapMode(GATE_HB1_BASE, EPWM_DB_OUTPUT_A, true);
EPWM_setDeadBandOutputSwapMode(GATE_HB1_BASE, EPWM_DB_OUTPUT_B, true);
}
}
else{
if(primary_pin == HS){
GPIO_setPinConfig(GPIO_0_EPWM1_A);
GPIO_setDirectionMode(GATE_HB1_LS, GPIO_DIR_MODE_OUT);
GPIO_setPadConfig(GATE_HB1_LS, GPIO_PIN_TYPE_STD);
GPIO_setMasterCore(GATE_HB1_LS, GPIO_CORE_CPU1);
GPIO_setQualificationMode(GATE_HB1_LS, GPIO_QUAL_SYNC);
GPIO_writePin(GATE_HB1_LS, 0);
}
else{
compare_register = (((duty_cycle)*(period_register * 0.01)) - (60 * dead_time));
GPIO_setPinConfig(GPIO_1_EPWM1_B);
GPIO_setDirectionMode(GATE_HB1_HS, GPIO_DIR_MODE_OUT);
GPIO_setPadConfig(GATE_HB1_HS, GPIO_PIN_TYPE_STD);
GPIO_setMasterCore(GATE_HB1_HS, GPIO_CORE_CPU1);
GPIO_setQualificationMode(GATE_HB1_HS, GPIO_QUAL_SYNC);
GPIO_writePin(GATE_HB1_HS, 0);
}
}
EPWM_setClockPrescaler(GATE_HB1_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);
EPWM_setTimeBaseCounterMode(GATE_HB1_BASE, EPWM_COUNTER_MODE_UP_DOWN);
EPWM_disablePhaseShiftLoad(GATE_HB1_BASE);
EPWM_setCounterCompareShadowLoadMode(GATE_HB1_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);
EPWM_setCounterCompareShadowLoadMode(GATE_HB1_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO);
EPWM_setActionQualifierAction(GATE_HB1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(GATE_HB1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
EPWM_setActionQualifierAction(GATE_HB1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
EPWM_setActionQualifierAction(GATE_HB1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
EPWM_setActionQualifierAction(GATE_HB1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
EPWM_setActionQualifierAction(GATE_HB1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
EPWM_setActionQualifierAction(GATE_HB1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(GATE_HB1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
EPWM_setActionQualifierAction(GATE_HB1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
EPWM_setActionQualifierAction(GATE_HB1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
EPWM_setActionQualifierAction(GATE_HB1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
EPWM_setActionQualifierAction(GATE_HB1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
EPWM_setTimeBasePeriod(GATE_HB1_BASE, period_register);
if(soft_start > 0){
start_soft_start(soft_start, 10, compare_register);
}
else{
EPWM_setCounterCompareValue(GATE_HB1_BASE, EPWM_COUNTER_COMPARE_A, compare_register);
}
In the start_soft_start function, i'm calculating timer duration and starting a timer. below is the code for same.
float compare_value_multiplication_factor;
uint16_t soft_start_steps;
void start_soft_start(float soft_start_uS, uint16_t steps, float final_compare_value){
/*
*
*/
extern uint16_t current_pulse_count;
current_pulse_count = 0;
compare_value_multiplication_factor = final_compare_value/steps;
soft_start_steps = steps;
uint16_t tick_time = (120 * soft_start_uS)/steps;
CPUTimer_setPeriod(SOFT_START_TIMER_BASE, tick_time);
CPUTimer_startTimer(SOFT_START_TIMER_BASE);
}
In ISR, I'm writing into CMPA value for the duty cycle
extern float compare_value_multiplication_factor;
extern uint16_t soft_start_steps;
__interrupt void INT_SOFT_START_TIMER_ISR(void){
Interrupt_clearACKGroup(INTERRUPT_CPU_INT13);
if(current_pulse_count > soft_start_steps){
CPUTimer_stopTimer(SOFT_START_TIMER_BASE);
}
GPIO_togglePin(EXT_DIGITAL_IN_0);
uint16_t this_compare_count = (uint16_t)(compare_value_multiplication_factor * current_pulse_count);
EPWM_setCounterCompareValue(GATE_HB1_BASE, EPWM_COUNTER_COMPARE_A, this_compare_count);
current_pulse_count++;
}
Now, I'm able to achieve what I want except, my PWM is starting before my soft start interrupts. I understand probably the sequence of my code is wrong. Can you suggest what do I need to do at the end for the PWM to start after compare register value is set. After what function does the PWM actually start? See the attached image for reference. Green Waveform are my interrupt pulses where I am changing the compare register value, the white border marked portion is undesirable.
