Go Down

Topic: Arduino DUE PWM and ADC interrupt Triggering (Read 5843 times) previous topic - next topic


Using an Arduino DUE, I would like to use PWM to trigger the an ADC interrupt.

My problem is a lack of understanding of the Sam3x8e architecture and the programmer API.

I wrote some code, aimed at triggering the ADC interrupts at 5 hz.

But the interrupt trigger runs at some ridiculous speed.

Could anyone tell me what I am doing wrong, or at least point to a working example of where the user can set
an desired ADC triggering frequency using PWM or Timer Counter triggering?

Code: [Select]

#define PWM_FREQUENCY               2
#define MAX_DUTY_CYCLE              1000

void setup()
  // put your setup code here, to run once:
  Serial.println("PWM Inited");


void loop()
  // put your main code here, to run repeatedly:

void ConfigureTriggerPWM(void)
  /* Enable PWMC peripheral clock. */

  /* Disable PWM channel 0. */
  PWMC_DisableChannel(PWM, 0);
  /* Set clock A to run at PWM_FREQUENCY * MAX_DUTY_CYCLE */
  /* Configure PWMC for channel 0 */
  PWMC_SetPeriod( PWM, 0, MAX_DUTY_CYCLE ) ;
  PWMC_SetDutyCycle( PWM, 0, (MAX_DUTY_CYCLE / 2) ) ;
  PWMC_ConfigureChannel(PWM, 0, PWM_CMR_CPRE_CLKA, (0 << 8), LOW);
  PWMC_ConfigureEventLineMode( PWM, 0, 1 ) ;
  PWMC_ConfigureComparisonUnit( PWM, 0, (MAX_DUTY_CYCLE / 2), 1 ) ;
  PWMC_EnableChannel(PWM, 0);
  adc_configure_trigger(ADC, ADC_TRIG_PWM_EVENT_LINE_0, 0);

void ConfigureADC(void)
  /* Enable peripheral clock. */

  /* Initialize ADC. */
  adc_init(ADC, VARIANT_MCK, 6400000, 8);
  /* Set ADC timing. */
  adc_configure_timing(ADC, 0, ADC_SETTLING_TIME_3, 1);
  /* Disable sequencer. */
  /* Enable channels. */
  adc_enable_channel(ADC, (adc_channel_num_t)0);
  /* Enable Data ready interrupt. */
  adc_enable_interrupt(ADC, ADC_IER_DRDY);
  /* Enable ADC interrupt. */

// ADC Interrupt handler.
void ADC_Handler(void)
  uint32_t ul_temp;
  if ((adc_get_status(ADC) & ADC_ISR_DRDY) == ADC_ISR_DRDY)
    // The serial prints are only here for debugging.
    Serial.println("ADC interrupt triggered.");
    ul_temp = adc_get_latest_value(ADC);


check your clk freq..... you might get a surprize

Code: [Select]
testPWM_clkA ()
  uint32_t clkvalue, clkhz;
  clkvalue = PWM->PWM_CLK;
  if (clkvalue & 0x000000ff)
      clkhz =
(VARIANT_MCK / (1 << ((clkvalue & 0x00000f00) >> 8))) /
(clkvalue & 0x000000ff);
    //print clkhz --------------------------------------//


Feb 03, 2013, 11:46 am Last Edit: Feb 03, 2013, 03:08 pm by JollyRogers Reason: 1
Okay, yes the frequency is fast, It was 1000000. Is there a reference for the arduino PWM functions, or just the Atmel SAM3X8E datasheet?

Correct me if I am wrong, but do I also need to call the PIO_Configure function with these parameters PIN_PWMC_PWMH0_TRIG, PIN_PWMC_PWMH0_TRIG_FLAG ?

Looking inside the Arduino Libs, it appears that of the Timer Counters, TC0 is able to trigger the ADC interrupts. Is this true? Or can the other Timer Counters trigger the ADC.

More importantly, is there one working example with ADC being trigged by PWM or Timer Counters with an arbitrary frequency?

I would love to see it.

I found FPGA's easier. Less abstraction, to the point.


i've been ripping code out from two of the examples in Atmel Studio .. best sources so far
(adc/pwm example & the synchronous pwm examples)
and re reading the data sheet a couple hundred times ...

i had found that there is a lower limit of time the pwm will work at ..
but don't have the code any more it morphed into other things ...  took some experimentation ..

I'm using the pwm/adc with the PDC  (sampling bursts of 5636 samples in ~15 ms  every 25ms or so )  still adjusting the timing  & have put off futher work till i get new sd card shields 


Apr 22, 2016, 06:35 am Last Edit: Apr 22, 2016, 03:13 pm by souravg009
Is there any way to just make an ISR for the PWM module to perform some other tasks also? so that it would be able to start a process after updating duty values in PWM.

Go Up