Search This Blog

Tuesday, November 27, 2018

SPWM - ATSAM3X8E Arduino UNO PWM Setup code

ATSAM3X8E Arduino UNO PWM Setup code

I have used this code for SPWM (sine wave PWM) with dead time
sine wave table generated separately and duty cycle of PWM is updated after particular interrupt.
Only setting up pwm with top, inverting with dead time is given below.
---------------------------------------------------------------------------------
void pwmSetup() 
  {
    //Configure PWM channels 0,1,2,3 PWML0,PWMH0,PWML1,PWMH1,PWML2,PWMH2,PWML3,PWMH3),
( arduino pins P34,P35,P36,P37,P38,P39,P40,P41)

    REG_PIOC_PDR = 0x3FC;  //B1111111100,
    REG_PIOC_ABSR = REG_PIOC_ABSR | 0x3FCu; //B1111111100,
    REG_PMC_PCER1 = REG_PMC_PCER1 | 16;

 //Register 1 (activate clock for PWM, id36, bit5 of PMC_PCSR1)
    REG_PWM_ENA = REG_PWM_SR | B1111; //PWM Enable Register | PWM
    PMC->PMC_PCER1 |= PMC_PCER1_PID36;                // PWM power ON
    PWM->PWM_DIS = PWM_DIS_CHID2;                         //

      PWM->PWM_CH_NUM[2].PWM_CMR = PWM_CMR_CPRE_CLKB;   
      PWM->PWM_CH_NUM[2].PWM_CPRD = 2000;                   //
      PWM->PWM_CH_NUM[2].PWM_CDTY = 100;                    //
      PWM->PWM_IER1 = PWM_IER1_CHID2;                       //
 
      PWM->PWM_ENA = PWM_ENA_CHID2;                         //

      REG_PIOC_PDR = 0x3FC;                     //B1111111100, PIO
      REG_PIOC_ABSR = REG_PIOC_ABSR | 0x3FCu;   //B1111111100,
 
      REG_PMC_PCER1 = REG_PMC_PCER1 | 16; //Peripheral Clock Enable
      REG_PWM_ENA = REG_PWM_SR | B1111;

PWM_SCM_SYNC5 | PWM_SCM_SYNC4 | PWM_SCM_SYNC3 | PWM_SCM_SYNC2 |
PWM_SCM_SYNC1 | PWM_SCM_SYNC0; // Set the PWM channels as sync
   
      REG_PWM_CMR0 = 0x10100; //Channe0 Mode Register: Dead Time
      REG_PWM_CMR1 = 0x10100; //Channe1 Mode Register: Dead Time
      REG_PWM_CMR2 = 0x10100; //Channe2 Mode Register: Dead Time
      REG_PWM_CMR3 = 0x10100; //Channe3 Mode Register: Dead Time

      //dead time calc according to if clk is 84Mhz
      // 0xFC00FC  - 3us       // 0xA800A8  - 2us    // 0x540054  -
      //       1us      //0x1500150  -  4us        //  0x01680168   - 5us   make   all same
      REG_PWM_DT0 = 0xFC00FC;  // 0xA800A8; // 2us  ;//0x1500150;
      REG_PWM_DT1 = 0xFC00FC;  // 0xA800A8;   ;//0x01680168;//
      REG_PWM_DT2 = 0xFC00FC;  // 0xA800A8;   ;//0xA800A8;
      REG_PWM_DT3 = 0xFC00FC;  // 0xA800A8;   ;//0xA800A8;
 
// top has to decide what should be your interupt rate
      REG_PWM_CPRD0 = top; //Cha0nne0 Period Register
      REG_PWM_CPRD1 = top; //Channe1 Period Register
      REG_PWM_CPRD2 = top; //Channe2 Period Register
      REG_PWM_CPRD3 = top; //Channe3 Period Register


      PWM->PWM_IER1 = PWM_IER1_CHID2;                       //
//Interrupt on Channel 2 Counter match
      NVIC_EnableIRQ(PWM_IRQn);                             //

  }

No comments:

Post a Comment