Go Down

Topic: Complementary PWM channels Output (Read 855 times) previous topic - next topic

MartinL

Quote
When I try using the code in #28, the IDE tells me "PWM_DT_DTHUPD" and "PWM_DT_DTLUPD" was not declared in this scope.
I've now corrected it above, it's

Code: [Select]
PWM->PWM_CH_NUM[0].PWM_DTUPD = PWM_DTUPD_DTHUPD(0) | PWM_DTUPD_DTLUPD(2);

MartinL

Are your looking at the low side channel outputs, PWMLx, on your scope?

jonnygainz

I'm looking at both low side and high side for each channel in turn to compare.

jonnygainz

I tried the code in #30 and still nothing. This is my code:

Code: [Select]
/* 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
 
  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

  calcCPRDV();
  /*Serial.print("CPRDV = ");
  Serial.print(CPRDV);
  Serial.print("\n");*/
  PWM->PWM_CH_NUM[0].PWM_CPRD = CPRDV;                // Channel 0 Period f = 2MHz/(CPRD)= 100Hz = 0.01s |CPRD = 2MHz/f
  PWM->PWM_CH_NUM[0].PWM_CMR = PWM_CMR_CPRE_CLKA | PWM_CMR_DTE;     // 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(200);
  //PWM->PWM_CH_NUM[1].PWM_DT = PWM_DT_DTH(0)| PWM_DT_DTL(200);
  //PWM->PWM_CH_NUM[2].PWM_DT = PWM_DT_DTH(0)| PWM_DT_DTL(200);
 
  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_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(2);
            PWM->PWM_CH_NUM[1].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(2);
            PWM->PWM_CH_NUM[2].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(2);
           
            PWM->PWM_CH_NUM[0].PWM_CDTYUPD = p;
            PWM->PWM_CH_NUM[1].PWM_CDTYUPD = n;
            PWM->PWM_CH_NUM[2].PWM_CDTYUPD = n;
          break;
          case 1: //ppn = 110 => 012
            PWM->PWM_CH_NUM[0].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(2);
            PWM->PWM_CH_NUM[1].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(2);
            PWM->PWM_CH_NUM[2].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(2);
           
            PWM->PWM_CH_NUM[0].PWM_CDTYUPD = p;
            PWM->PWM_CH_NUM[1].PWM_CDTYUPD = p;
            PWM->PWM_CH_NUM[2].PWM_CDTYUPD = n;
          break;
          case 2: //npn = 010 => 012
            PWM->PWM_CH_NUM[0].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(2);
            PWM->PWM_CH_NUM[1].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(2);
            PWM->PWM_CH_NUM[2].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(2);
           
            PWM->PWM_CH_NUM[0].PWM_CDTYUPD = n;
            PWM->PWM_CH_NUM[1].PWM_CDTYUPD = p;
            PWM->PWM_CH_NUM[2].PWM_CDTYUPD = n;
          break;
          case 3: //npp = 011 => 012
            PWM->PWM_CH_NUM[0].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(2);
            PWM->PWM_CH_NUM[1].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(2);
            PWM->PWM_CH_NUM[2].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(2);
           
            PWM->PWM_CH_NUM[0].PWM_CDTYUPD = n;
            PWM->PWM_CH_NUM[1].PWM_CDTYUPD = p;
            PWM->PWM_CH_NUM[2].PWM_CDTYUPD = p;
          break;
          case 4: //nnp = 001 => 012
            PWM->PWM_CH_NUM[0].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(2);
            PWM->PWM_CH_NUM[1].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(2);
            PWM->PWM_CH_NUM[2].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(2);
           
            PWM->PWM_CH_NUM[0].PWM_CDTYUPD = n;
            PWM->PWM_CH_NUM[1].PWM_CDTYUPD = n;
            PWM->PWM_CH_NUM[2].PWM_CDTYUPD = p;
          break;
          case 5: //pnp = 101 => 012
            PWM->PWM_CH_NUM[0].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(2);
            PWM->PWM_CH_NUM[1].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(2);
            PWM->PWM_CH_NUM[2].PWM_DTUPD = PWM_DTUPD_DTHUPD(0)| PWM_DTUPD_DTLUPD(2);
           
            PWM->PWM_CH_NUM[0].PWM_CDTYUPD = p;
            PWM->PWM_CH_NUM[1].PWM_CDTYUPD = n;
            PWM->PWM_CH_NUM[2].PWM_CDTYUPD = p;

          break;
          default:
          break;
        }
        count = (count + 1) % 6;


    }
}

jonnygainz

Could it be that the UPDULOCK bit must be set in order to allow the dead time registers to be updated?

jonnygainz

Any luck? I've tried everything I can think of, and it's not working.

Go Up