Pages: [1]   Go Down
Author Topic: Arduino DUE PWM and ADC interrupt Triggering  (Read 2027 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

#define PWM_FREQUENCY               2
#define MAX_DUTY_CYCLE              1000

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

}

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

void ConfigureTriggerPWM(void)
{
  /* Enable PWMC peripheral clock. */
  pmc_enable_periph_clk(ID_PWM);

  /* Disable PWM channel 0. */
  PWMC_DisableChannel(PWM, 0);
 
  /* Set clock A to run at PWM_FREQUENCY * MAX_DUTY_CYCLE */
  PWMC_ConfigureClocks((PWM_FREQUENCY * MAX_DUTY_CYCLE), 0, VARIANT_MCK ) ;
 
  /* 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. */
  pmc_enable_periph_clk(ID_ADC);

  /* Initialize ADC. */
  adc_init(ADC, VARIANT_MCK, 6400000, 8);
 
  /* Set ADC timing. */
  adc_configure_timing(ADC, 0, ADC_SETTLING_TIME_3, 1);
 
  /* Disable sequencer. */
  adc_stop_sequencer(ADC);
 
  /* 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. */
  NVIC_EnableIRQ(ADC_IRQn);
}

// 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);
    Serial.println(ul_temp);
  }
}
Logged

Ottawa,Canada
Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: February 03, 2013, 09:08:00 am by JollyRogers » Logged

Ottawa,Canada
Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 
 
Logged

Pages: [1]   Go Up
Jump to: