Go Down

Topic: Due PWM frequency (Read 14364 times) previous topic - next topic

sepehrdidevar

I at least have 10bit ADC input now

Code: [Select]
int Feedback = A0;   // feedback connected to pin 0
int val = 0;         // variable to store the read value

void setup() {
  // PWM Set-up on pin: DAC1
   
  REG_PMC_PCER1 |= PMC_PCER1_PID36;                     // Enable PWM
  REG_PIOB_ABSR |= PIO_ABSR_P16;                        // Set PWM pin perhipheral type A or B, in this case B
  REG_PIOB_PDR |= PIO_PDR_P16;                          // Set PWM pin to an output
  REG_PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(1);      // Set the PWM clock rate to 84MHz (84MHz/1)
  REG_PWM_CMR0 = PWM_CMR_CPRE_CLKA;                     // Enable single slope PWM and set the clock source as CLKA
  REG_PWM_CPRD0 = 2100;                                  // Set the PWM frequency 84MHz/40kHz = 2100                                   // Set the PWM duty cycle 50% (2100/2=1050)
  REG_PWM_ENA = PWM_ENA_CHID0;                          // Enable the PWM channel     
}

void loop()
{
val = analogRead(Feedback);
REG_PWM_CDTY0 = val * 2;
}

 

why did you write  the val*2 ?
and what is the "feedback" value?
is it converter output voltage ?

generatorlabs

MartinL,

Thank you so much for that snippet of code. It works very well. The DUE is a completely different beast from the AVR stuff and trying to move a project from a UNO to the DUE has proven to be very challenging. Even looking up these completely different timer registers is a daunting task.

I have seen a library that can do some of what you have shared. I would like to keep the code as simple as possible. My needs are simple. I need two fixed frequency PWM clocks to drive external chips. They do not have to be super precise and they will never change. I need approx 104kHz and 150kHz on each clock.

I would like to ask, what must I change/add in the code snippet to have a second timer with its own PWM freq and Duty on another unused pin, like DAC2?

Thanks for any help.

Hi buckboostbill,

The code below uses register manipulation to create a 40kHz, 50% duty cycle PWM signal on pin DAC1 (PWML0):

Code: [Select]
// Output a 40kHz PWM waveform at a resolution of 11-bits on pin DAC1 (PWML0)
void setup() {
  // PWM Set-up on pin: DAC1
  REG_PMC_PCER1 |= PMC_PCER1_PID36;                     // Enable PWM
  REG_PIOB_ABSR |= PIO_ABSR_P16;                        // Set PWM pin perhipheral type A or B, in this case B
  REG_PIOB_PDR |= PIO_PDR_P16;                          // Set PWM pin to an output
  REG_PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(1);      // Set the PWM clock rate to 84MHz (84MHz/1)
  REG_PWM_CMR0 = PWM_CMR_CPRE_CLKA;                     // Enable single slope PWM and set the clock source as CLKA
  REG_PWM_CPRD0 = 2100;                                  // Set the PWM frequency 84MHz/40kHz = 2100
  REG_PWM_CDTY0 = 1050;                                  // Set the PWM duty cycle 50% (2100/2=1050)
  REG_PWM_ENA = PWM_ENA_CHID0;                          // Enable the PWM channel    
}

void loop() {}

This will give you 11-bit resolution, which is the best that can be achieved by the 84MHz Due at this (40kHz) frequency.

Go Up