Go Down

Topic: Changing variant.h does not change PWM frequency (Read 334 times) previous topic - next topic

dgelman

Jul 19, 2018, 05:54 pm Last Edit: Jul 19, 2018, 05:55 pm by dgelman
Hello,

I am trying change the PMW frequency on pins 7, 8, and 9 to 20kHz. I used to be able to change it by changing PWM_FREQUENCY and TC_FREQUENCY in the variant.h file.


Code: [Select]
* PWM
 */
#define PWM_INTERFACE PWM
#define PWM_INTERFACE_ID ID_PWM
#define PWM_FREQUENCY 20000
#define PWM_MAX_DUTY_CYCLE 255
#define PWM_MIN_DUTY_CYCLE 0
#define PWM_RESOLUTION 8

/*
 * TC
 */
#define TC_INTERFACE        TC0
#define TC_INTERFACE_ID     ID_TC0
#define TC_FREQUENCY        20000
#define TC_MAX_DUTY_CYCLE   255
#define TC_MIN_DUTY_CYCLE   0
#define TC_RESOLUTION 8


For some reason this method is not working any more. I am using Arduino 1.8.5 with SAM 1.6.11 installed. Reboot Arduino software does nothing.

Is there a different way of changing the PWM frequency?
Dialup is the future.

ard_newbie

#1
Jul 19, 2018, 06:20 pm Last Edit: Jul 19, 2018, 08:02 pm by ard_newbie
There are numerous example sketches of PWM programming in the DUE subforum. All you need is the Greynomad pinout diagram plus the PWM section of Sam3x datasheet. An other solution would be using PWM_lib from antodom.

Here is an example with PWMH0 at 1 MHz with a duty cycle of 50%:


Code: [Select]

/******************************************************************************/
/*                         PWMH0 1 MHz                                        */
/******************************************************************************/

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);

  PMC->PMC_PCER1 |= PMC_PCER1_PID36;                   // PWM power ON

  PIOC->PIO_PDR |= PIO_PDR_P3;                         // Set PWM pin to a peripheral
  PIOC->PIO_ABSR |= PIO_PC3B_PWMH0;                    // Set PWM pin peripheral type B for PWMH0 (Arduino pin 35)

  PWM->PWM_CLK = PWM_CLK_PREB(0) | PWM_CLK_DIVB(2);    // select Frequency for clock B: Mck/2 = 42 MHz

  PWM->PWM_CH_NUM[0].PWM_CMR = PWM_CMR_CPRE_CLKB;      // The period is left aligned, clock source as CLKB on channel 0
  PWM->PWM_CH_NUM[0].PWM_CPRD = 42;                    // Set the PWM frequency 42 MHz/42 = 1 MHz
  PWM->PWM_CH_NUM[0].PWM_CDTY = 21;                     // Set the PWM duty cycle = (CPRD/CDTY) * 100 %

  PWM->PWM_IER1 = PWM_IER1_CHID0;                      // Interrupt on PWM Channel 0 counter
  NVIC_EnableIRQ(PWM_IRQn);                            // Enable interrupt

  PWM->PWM_ENA = PWM_ENA_CHID0;                        // Enable PWM channel 0
}

void loop() {

}

void PWM_Handler() {
  static uint32_t Count;
  
  PWM->PWM_ISR1;      // Read and Clear status register
  if (Count++ == 1000000) {
    PIOB->PIO_ODSR ^= PIO_ODSR_P27;  // Toggle LED_BUILTIN every 1 Hz
    Count = 0;
  
  }
 
}


dgelman

#2
Jul 19, 2018, 06:54 pm Last Edit: Jul 19, 2018, 06:54 pm by dgelman
Code: [Select]

/******************************************************************************/
/*                         PWMH0 1 MHz                                        */
/******************************************************************************/

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);

  PMC->PMC_PCER1 |= PMC_PCER1_PID36;                   // PWM power ON

  PIOC->PIO_PDR |= PIO_PDR_P3;                         // Set PWM pin to a peripheral
  PIOB->PIO_ABSR |= PIO_PC3B_PWMH0;                    // Set PWM pin peripheral type B for PWMH0 (Arduino pin 35)

  PWM->PWM_CLK = PWM_CLK_PREB(0) | PWM_CLK_DIVB(2);    // select Frequency for clock B: Mck/2 = 42 MHz

  PWM->PWM_CH_NUM[0].PWM_CMR = PWM_CMR_CPRE_CLKB;      // The period is left aligned, clock source as CLKB on channel 0
  PWM->PWM_CH_NUM[0].PWM_CPRD = 42;                    // Set the PWM frequency 42 MHz/42 = 1 MHz
  PWM->PWM_CH_NUM[0].PWM_CDTY = 21;                     // Set the PWM duty cycle = (CPRD/CDTY) * 100 %

  PWM->PWM_IER1 = PWM_IER1_CHID0;                      // Interrupt on PWM Channel 0 counter
  NVIC_EnableIRQ(PWM_IRQn);                            // Enable interrupt

  PWM->PWM_ENA = PWM_ENA_CHID0;                        // Enable PWM channel 0
}

void loop() {

}

void PWM_Handler() {
  static uint32_t Count;
 
  PWM->PWM_ISR1;      // Read and Clear status register
  if (Count++ == 1000000) {
    PIOB->PIO_ODSR ^= PIO_ODSR_P27;  // Toggle LED_BUILTIN every 1 Hz
    Count = 0;
   
  }
 
}


I tried this code and there is nothing scoped on pin 35.
Dialup is the future.

ard_newbie

Yes, it's PIOC->PIO_ABSR |= PIO_PC3B_PWMH0; !!

Go Up