Author Topic: Timer Based Operation of the ADC  (Read 10229 times)

Offline mhoneywill

  • Full Member
  • ***
  • Posts: 173
    • View Profile
Timer Based Operation of the ADC
« on: June 12, 2010, 06:54:24 PM »
Hi Mark,

I want the ADC in my LM3S1968 based project to just run in the background continuously just reading the 8 ADC inputs. In fact in my application I'm just using the ADC inputs as another 8 logic input lines. I've setup a 1ms hardware timer that I'm using to sample some input lines (3 lines used to sample a 3phase mains supply so I can work out the mains sequence).

By a bit of trial and error I've got something that works in the simulator (I've no access to the hardware until Monday).

I couldn't find much info on ADC configuration on the forum or in the documentation so I'm posting here describing what I've done. So that it will be of help to other users and you can also tell me if I've done something wrong.

Firstly I setup the hardware Timer as shown below

Code: [Select]
unsigned long MSTimerTick = 0;

static void timer_int(void)
{
    MSTimerTick++;
    PhaseMap();
}

static void fnConfigure_Timer(void)
{
    static TIMER_INTERRUPT_SETUP timer_setup = {0};                      // interrupt configuration parameters

    timer_setup.timer_reference = 2;                                     // timer channel 2
    timer_setup.int_type = TIMER_INTERRUPT;
    timer_setup.int_priority = PRIORITY_TIMERS;
    timer_setup.int_handler = timer_int;                                // set to 0 for no handler
    timer_setup.timer_mode = (TIMER_TRIGGER_ADC | TIMER_PERIODIC | TIMER_MS_VALUE); // period timer
    timer_setup.timer_value = 1;                                        // ms delay
    fnConfigureInterrupt((void *)&timer_setup);                          // enter interrupt for timer test
}

Am I correct in using TIMER_TRIGGER_ADC in the timer_mode setting?

Next I set-up the ADC as shown below

Code: [Select]

static void fnConfigureADC(void)
{
    ADC_SETUP adc_setup;                                                 // interrupt configuration parameters
    adc_setup.int_type = ADC_INTERRUPT;                                  // identifier when configuring
    adc_setup.int_handler = 0;                                          // handling function
    adc_setup.int_priority = PRIORITY_ADC;                               // ADC interrupt priority
    adc_setup.int_adc_single_ended_inputs = (ADC_CHANNEL_0 | ADC_CHANNEL_1 | ADC_CHANNEL_2 | ADC_CHANNEL_3 | ADC_CHANNEL_4 | ADC_CHANNEL_5 | ADC_CHANNEL_6 | ADC_CHANNEL_7); // ADC channels 0..3 as single ended inputs
    adc_setup.int_adc_differential_inputs = 0; // No ADC channels as differential inputs
    adc_setup.int_adc_mode = (ADC_CONFIGURE_ADC | ADC_TRIGGER_TIMER);  // start under timer control
    adc_setup.int_adc_averaging = HW_AVERAGING_64;                       // basic sampling speed is 1MHz but can be averaged to improve accuracy or reduce speed
    adc_setup.int_adc_result = usADC_samples;                            // location to save the samples to
    adc_setup.int_sequence_count = ADC_SEQUENCES;
    fnConfigureInterrupt((void *)&adc_setup);                            // configure and start sequence
}

I presume this is the correct way to set the ADC mode?
 
adc_setup.int_adc_mode = (ADC_CONFIGURE_ADC | ADC_TRIGGER_TIMER);

Next it is all started off in my application startup with the following lines

        fnConfigureADC();                                                //
        fnConfigure_Timer();                                            // Hardware timer used for Phase detection and ADC trigger

As I say this seems to work in the Simulator I just wanted to ensure I was doing the right thing.

Cheers

Martin

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Timer Based Operation of the ADC
« Reply #1 on: June 13, 2010, 02:53:02 PM »
Hi Martin

It looks correct as you have done it - if the simulator works it should also work on the HW (the simulator checks things quite strictly so didn't see anything wrong - thus performing the conversions).

The ADC can be triggered from various sources (comparators, PWM, port PB4, timers). The ADC configuration flag ADC_TRIGGER_TIMER causes configuration of a trigger from any enabled timer. The timer then needs to be configured separately and is connected to ADC trigger internally when the flag TIMER_TRIGGER_ADC is used.

Note that Timer 3 doesn't seem to work as ADC trigger. There are also some errata concerning ADC triggering so check the latest errata sheet and silicon revision to see whether it could be a problem.

Regards

Mark



Offline mhoneywill

  • Full Member
  • ***
  • Posts: 173
    • View Profile
Re: Timer Based Operation of the ADC
« Reply #2 on: June 13, 2010, 05:54:11 PM »
Thanks for the heads up about the Errata, looks like there are some nasty gotcha's there

Regards

Martin