lpcware

Issue about ADC conversion triggered by TIM0  timer

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by erodrigues on Sun Nov 04 14:27:27 MST 2012
Hi!


I have been exploring the LPC1769 board made by Embedded Artists.  For the moment my attention is on ADC peripheral. Enabling manual trigger mode is easy. Applying the procedure of triggering through a timer interruption service routine is also trivial. But when it comes to fire the peripheral by using the timer as a trigger signal without enabling the timer ISR, the result I have found differs from what I was expecting.



  In my test the Timer0 was defined to generate a tick pulse of 10us (100kHz). By setting the external match register (EMR) for toggling the corresponding external match output (MAT0.1), I was able to confirm that the signal generated at pin 1.29 (MAT0.1) is a square wave of 50kHz.


  To ensure that the ADC interrupt routine is invoked with the same frequency as the square wave, I signalized the execution of routine using pin 0.20 as an external signal. When I checked this pin with the oscilloscope I have discovered the ADC ISR is executed at half (25kHz) of MAT0.1 signal frequency (50kHz).
  Is it correct to conclude the ADC sampling frequency through this method is always half of MAT signal frequency?


  Below I have attached the code used in my test.
  
  I would like receive opinions and confirmations about this technical issue.
   
  Thanks in advance.


  Eduardo Rodrigues




#include <cr_section_macros.h>
#include <NXP/crp.h>

#include "LPC17xx.h"
__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;

volatile uint32_t resultadoADC;

void config_Timer0(void);
void config_ADC(void);

int main(void)

{   
    //Pin P0.20 used for checking the frequency of ADC ISR execution
    LPC_GPIO0->FIODIR|=(1<<20); // P0.20 Output
    LPC_GPIO0->FIOCLR|=(1<<20); // P0.20 Set low level

    config_Timer0();
    config_ADC();

    while(1);
}

void config_Timer0(void)
{
     LPC_SC->PCONP|=(1<<1);
     LPC_SC->PCLKSEL0|=(0x01<<2); // ADC Clock = SystemCoreClock (100MHz)

// Timer0 configured to generate a square wave on MAT0.1 at a rate of 50kHz
     LPC_TIM0->TCR = 0x2;            // timer0 in reset mode
     LPC_TIM0->TCR = 0;                // timer mode
     LPC_TIM0->PR = 100-1;          //

     LPC_TIM0->MCR = (1 << 4);        // reset on MR1

     LPC_TIM0->MR1 = 10-1;            //

    

     LPC_TIM0->EMR = (1<<1)|(0x3<<6);        // toggle EM1 on match
}


/*                                                    */

void config_ADC(void)
{

  LPC_SC->PCONP|=(1<<12);
  LPC_SC->PCLKSEL0|=(3<<24);

  LPC_PINCON->PINSEL1|=(1<<20); // AD03
  LPC_PINCON->PINMODE0|=(2<<6);


  //
  LPC_ADC->ADCR = 0;
  LPC_ADC->ADCR=(1<<3)|(0<16)|(1<<21)|(0<<27); //AD03+Software mode+Start conversion triggered by MAT signal
  LPC_ADC->ADINTEN|=(1<<3); //Enable AD03 interrupt
  LPC_ADC->ADINTEN&=~(1<<8);

  LPC_ADC->ADCR|=(4<<24); // Start conversion when the edge selected by bit 27 occurs on MAT0.1

  LPC_TIM0->TCR|=0x01; //

  NVIC_EnableIRQ(ADC_IRQn);

  LPC_PINCON->PINSEL3|=(3<<26);

}

void ADC_IRQHandler(void)
{


LPC_GPIO0->FIOSET|=(1<<20);


if(LPC_ADC->ADDR3 & (1 << 31))
{
     resultadoADC=LPC_ADC->ADDR3;
}

LPC_GPIO0->FIOCLR|=(1<<20);

}

Outcomes