I'm trying to drive an inverter circuit using the Arduino Due to drive the gate signals of IGBT's and I need dead time to drive the circuit safely. I tried implementing the dead times and they just aren't working. Can anyone tell me what I'm doing wrong?
/* This code generates Quasi-Square Waves at 60Hz*/
static byte stateCount = 0;
static float CPRDV = 0;
static float inverterFrequency = 60;
int divA = 42;
void setup()
{
//Serial.begin(57600);
PMC->PMC_PCER1 |= PMC_PCER1_PID36; // Enable PWM (Power On)
PIOC->PIO_PDR |= PIO_PDR_P3 | PIO_PDR_P5 | PIO_PDR_P7; // Setting pins 3,5,7 (DUE Pins 35, 37, 39) to PWM Peripheral, not GPIO
PIOC->PIO_ABSR |= PIO_ABSR_P3 | PIO_ABSR_P5 | PIO_ABSR_P7; // Setting pins to Peripheral B
PIOC->PIO_PDR |= PIO_PDR_P2 | PIO_PDR_P4 | PIO_PDR_P6; // Setting pins 2,4,6 (DUE Pins 34, 36, 38) to PWM Peripheral, not GPIO
PIOC->PIO_ABSR |= PIO_ABSR_P2 | PIO_ABSR_P4 | PIO_ABSR_P6; // Setting pins to Peripheral B
PWM->PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(divA); // Set PWM clocke rate to 2MHz (84MHz/42)
PWM->PWM_SCM |= PWM_SCM_SYNC0 | PWM_SCM_SYNC1 | PWM_SCM_SYNC2; // Synchronizing of Channels 0, 1 and 2
PWM->PWM_SCM |= PWM_SCM_UPDM_MODE1; // Manual Write of duty-cycle automatic trigger of the update
calcCPRDV();
/*Serial.print("CPRDV = ");
Serial.print(CPRDV);
Serial.print("\n");*/
PWM->PWM_CH_NUM[0].PWM_CPRD = CPRDV; // Channel 0 Period f = 2MHz/(CPRD)= 360Hz
PWM->PWM_CH_NUM[0].PWM_CMR = PWM_CMR_DTE | PWM_CMR_CPRE_CLKA; // Period is left aligned,clock source is CLKA on Channel 0
PWM->PWM_CH_NUM[1].PWM_CMR = PWM_CMR_DTE;
PWM->PWM_CH_NUM[2].PWM_CMR = PWM_CMR_DTE;
PWM->PWM_CH_NUM[0].PWM_DT = PWM_DT_DTH(0) | PWM_DT_DTL(555); // Set channel dead-time for 10% 0f CPRD delay on output PWML0
PWM->PWM_CH_NUM[1].PWM_DT = PWM_DT_DTH(0) | PWM_DT_DTL(555); // Set channel dead-time for 10% 0f CPRD delay on output PWML1
PWM->PWM_CH_NUM[2].PWM_DT = PWM_DT_DTH(0) | PWM_DT_DTL(555);
NVIC_SetPriority(PWM_IRQn, 0); // Set the Nested Vector Interrupt Controller (NVIC) priority for the PWM controller to 0 (highest)
NVIC_EnableIRQ(PWM_IRQn); // Connect PWM Controller to Nested Vector Interrupt Controller (NVIC)
PWM->PWM_IER1 = PWM_IER1_CHID0; // Enable interrupt on PWM channel 0 triggered at end of PWM period
//PWM->PWM_CH_NUM[0].PWM_CDTY = 0; // Channel 0 duty-cycle at 0%
//PWM->PWM_CH_NUM[1].PWM_CDTY = 0; // Channel 1 duty-cycle at 0%
//PWM->PWM_CH_NUM[2].PWM_CDTY = 0; // Channel 2 duty-cycle at 0%
//PWM->PWM_CH_NUM[0].PWM_DT = PWM_DT_DTH(420)| PWM_DT_DTL(420);
//PWM->PWM_CH_NUM[1].PWM_DT = PWM_DT_DTH(420)| PWM_DT_DTL(420);
//PWM->PWM_CH_NUM[2].PWM_DT = PWM_DT_DTH(420)| PWM_DT_DTL(420);
//PWM->PWM_CH_NUM[0].PWM_DT = 42;
//PWMC_SetDeadTime(PWM, 0, 42, 42);
PWM->PWM_ENA = PWM_ENA_CHID0; // Enable synchronous PWM on Channel 0
}
void loop()
{
}
void PWM_Handler() // PWM Interrupt Service Routine (ISR)
{
if (PWM->PWM_ISR1 & PWM_ISR1_CHID0) // Check if an update condition has occured
{
update_Duty_Cycle(); // Update the duty cycles
}
}
void calcCPRDV ()
{
//inverterFrequency = 60;
static float numOfVectors = 6;
static float adMCKFreq = 84000000;
static float timerFreq = (adMCKFreq/divA); //2MHz
static float period = 1/inverterFrequency;
static float Ts = period/numOfVectors;
static float switchingFreq = 1/Ts;
CPRDV = (timerFreq/(1*switchingFreq));
/*Serial.print("Inverter Frequency = "); Serial.print(inverterFrequency);Serial.print("\n");
Serial.print("Num of Vectors = "); Serial.print(numOfVectors); Serial.print("\n");
Serial.print("Timer Freq = "); Serial.print(timerFreq); Serial.print("\n");
Serial.print("Period = "); Serial.print(period, 8); Serial.print("\n");
Serial.print("SSV Period = "); Serial.print(Ts, 8); Serial.print("\n");
Serial.print("Switching Freq = "); Serial.print(switchingFreq); Serial.print("\n");*/
}
void update_Duty_Cycle()
{
if(stateCount < 6)
{
PWM->PWM_CH_NUM[0].PWM_CDTYUPD = 0;
PWM->PWM_CH_NUM[1].PWM_CDTYUPD = 0;
PWM->PWM_CH_NUM[2].PWM_CDTYUPD = 0;
stateCount++;
/*Serial.print("Counter = ");
Serial.print(stateCount); Serial.print("\n");*/
}
else
{
static byte count = 0;
static float p = CPRDV;
static float n = 0;
//Serial.print("Sector = "); Serial.print(count); Serial.print("\n");
switch(count)
{
case 0: //pnn = 100 => 012
PWM->PWM_CH_NUM[0].PWM_CDTYUPD = p;
PWM->PWM_CH_NUM[1].PWM_CDTYUPD = n;
PWM->PWM_CH_NUM[2].PWM_CDTYUPD = n;
PWM->PWM_CH_NUM[0].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(555);
PWM->PWM_CH_NUM[1].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(555);
PWM->PWM_CH_NUM[2].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(555);
break;
case 1: //ppn = 110 => 012
//PWM->PWM_CH_NUM[0].PWM_CDTYUPD = p;
PWM->PWM_CH_NUM[1].PWM_CDTYUPD = p;
//PWM->PWM_CH_NUM[2].PWM_CDTYUPD = n;
PWM->PWM_CH_NUM[0].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(555);
PWM->PWM_CH_NUM[1].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(555);
PWM->PWM_CH_NUM[2].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(555);
break;
case 2: //npn = 010 => 012
PWM->PWM_CH_NUM[0].PWM_CDTYUPD = n;
//PWM->PWM_CH_NUM[1].PWM_CDTYUPD = p;
//PWM->PWM_CH_NUM[2].PWM_CDTYUPD = n;
PWM->PWM_CH_NUM[0].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(555);
PWM->PWM_CH_NUM[1].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(555);
PWM->PWM_CH_NUM[2].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(555);
break;
case 3: //npp = 011 => 012
//PWM->PWM_CH_NUM[0].PWM_CDTYUPD = n;
//PWM->PWM_CH_NUM[1].PWM_CDTYUPD = p;
PWM->PWM_CH_NUM[2].PWM_CDTYUPD = p;
PWM->PWM_CH_NUM[0].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(555);
PWM->PWM_CH_NUM[1].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(555);
PWM->PWM_CH_NUM[2].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(555);
break;
case 4: //nnp = 001 => 012
//PWM->PWM_CH_NUM[0].PWM_CDTYUPD = n;
PWM->PWM_CH_NUM[1].PWM_CDTYUPD = n;
//PWM->PWM_CH_NUM[2].PWM_CDTYUPD = p;
PWM->PWM_CH_NUM[0].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(555);
PWM->PWM_CH_NUM[1].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(555);
PWM->PWM_CH_NUM[2].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(555);
break;
case 5: //pnp = 101 => 012
PWM->PWM_CH_NUM[0].PWM_CDTYUPD = p;
//PWM->PWM_CH_NUM[1].PWM_CDTYUPD = n;
//PWM->PWM_CH_NUM[2].PWM_CDTYUPD = p;
PWM->PWM_CH_NUM[0].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(555);
PWM->PWM_CH_NUM[1].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(555);
PWM->PWM_CH_NUM[2].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(555);
break;
default:
break;
}
count = (count + 1) % 6;
}
}
I also tried setting the update unlock bit in the 'update_Duty_Cycle().'
PWM->PWM_SCUC = PWM_SCUC_UPDULOCK;
But that still doesn't work.