This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Timer0 Set for data aquisition in 3Khz frequency.

Hi Guys, i'm  try make a data aquisition (6 Analog channel) in 3 Khz frequency. But Timer0 is not count with precision.

Can you have a suggestion for resolve this ?

My code is:


//*****************************************************************************
//
// ADC READ TIMER0 DAQ FREQUENCY 3 Khz
//
// RENNE TAKAO
//
//*****************************************************************************
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "utils/ustdlib.h"
#include "utils/uartstdio.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/interrupt.h"
#include "driverlib/sysctl.h"
#include "driverlib/timer.h"
#include "driverlib/rom.h"
#include "grlib/grlib.h"
#include "driverlib/adc.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "drivers/cfal96x64x16.h"
#include "inc/lm4f232h5qd.h"
#include <math.h>
#include <complex.h>
#include <tgmath.h>
//*****************************************************************************
unsigned long g_ulFlags;
//---------------------------ADC--------------------------------------

#define SEQUENCER 0 //JR:

unsigned long ulADC0_Value[6]; //JR: ARRAY TO STORE ADC VALUES (d7,D6...)


unsigned long D5[500]; //JR: array to store 500 points from channel
unsigned long D4[500]; //JR: array to store 500 points from channel
unsigned long D3[500]; //JR: array to store 500 points from channel
unsigned long D2[500]; //JR: array to store 500 points from channel
unsigned long D1[500]; //JR: array to store 500 points from channel
unsigned long D0[500]; //JR: array to store 500 points from channel

//JR: Average 500 points / channel
float media_D5 = 0;
float media_D4 = 0;
float media_D3 = 0;
float media_D2 = 0;
float media_D1 = 0;
float media_D0 = 0;

char cText[8]; //JR: variavel que recebera a conversao de um "unsigned long" em "String"

unsigned long cont1 = 0; //JR: counter of number of retrieval data from ADC (0-499).

unsigned long ulFrequency=3000; 3Khz
unsigned long ulPeriod;
unsigned long ulSysPeriod;
//*****************************************************************************
//
// CSTN display
//
//*****************************************************************************
tContext g_sContext;

//*****************************************************************************
//
// The error routine that is called if the driver library encounters an error.
//
//*****************************************************************************
#ifdef DEBUG
void
__error__(char *pcFilename, unsigned long ulLine)
{
}
#endif

unsigned long i; //contador auxiliar utulizados nos laços de repetiçao(for)

void clr_vetor() // clear 500 position array
{
for (int j=0;j<500;j++)
{
D0[j]= 0;
D1[j]= 0;
D2[j]= 0;
D3[j]= 0;
D4[j]= 0;
D5[j]= 0;
}
}

void clr_buffer(unsigned long *ulValue)
{

for ( i = 0 ; i <6; i++)
{
ulValue[i] = 0; // clear ADC array for new data aquisition
}

}

//On led indicate start read
void ligaLed()
{
GPIO_PORTG_DATA_R |= 0x04;
}

//Off led indicate stop read

void desligaLed()
{
GPIO_PORTG_DATA_R &= ~(0x04);
}


void LerSinal()
{

ligaLed(); //On led to indicate start read from ad

// Trigger the ADC conversion.
ADCProcessorTrigger(ADC0_BASE, SEQUENCER);

// Wait for conversion to be completed.
while(!ADCIntStatus(ADC0_BASE, SEQUENCER, false))
{
}

// Clear the ADC interrupt flag.
ADCIntClear(ADC0_BASE, SEQUENCER);

// Read ADC Value.
ADCSequenceDataGet(ADC0_BASE, SEQUENCER, ulADC0_Value);

//store data from ADC in array of 500 positions

D0[cont1]= ulADC0_Value[0];
D1[cont1]= ulADC0_Value[1];
D2[cont1]= ulADC0_Value[2];
D3[cont1]= ulADC0_Value[3];
D4[cont1]= ulADC0_Value[4];
D5[cont1]= ulADC0_Value[5];

//clear ulADC0_Value;
clr_buffer(ulADC0_Value);



desligaLed(); //of led indicate stop aquisition
}

//*****************************************************************************
//
// The interrupt handler for the first timer interrupt.
//
//*****************************************************************************
void
Timer0IntHandler(void)
{

// Clear the timer interrupt.
//
TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);

// Update the interrupt status on the display.
//
// IntMasterDisable();


//print count1 in display
usprintf(cText, " %d ", cont1);//JR: D5
GrStringDraw(&g_sContext, cText,-1, 45,15, 1);

LerSinal();

//display value in UART
UARTprintf(">Count.: %d \n",cont1);


cont1++; //increment count



// IntMasterEnable();

}


int main(void)
{
tRectangle sRect;

FPULazyStackingEnable();


//clock

SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); //preescaler 40mhz

ulSysPeriod = SysCtlClockGet(); // Just used to print clock value



SYSCTL_RCGC2_R = SYSCTL_RCGC2_GPIOG;
GPIO_PORTG_DIR_R = 0x04;
GPIO_PORTG_DEN_R = 0x04;

//clear buffer
clr_buffer(ulADC0_Value);


//
// Initialize the display driver.
//
CFAL96x64x16Init();

//
// Initialize the graphics context and find the middle X coordinate.
//
GrContextInit(&g_sContext, &g_sCFAL96x64x16);

//
// Cria Banner.
//
sRect.sXMin = 0;
sRect.sYMin = 0;
sRect.sXMax = GrContextDpyWidthGet(&g_sContext) - 1;
sRect.sYMax = 9;
GrContextForegroundSet(&g_sContext, ClrDarkBlue);
GrRectFill(&g_sContext, &sRect);

//
// Change foreground for white text.
//
GrContextForegroundSet(&g_sContext, ClrWhite);

//
// Put the application name in the middle of the banner.
//
GrContextFontSet(&g_sContext, g_pFontFixed6x8);
GrStringDrawCentered(&g_sContext, "PROJECT", -1,
GrContextDpyWidthGet(&g_sContext) / 2, 4, 0);

//
// Initialize timer status display.
//
GrContextFontSet(&g_sContext, g_pFontFixed6x8);
GrStringDraw(&g_sContext, "Timer 0:", -1, 0, 15, 0);

//------------------------------- Enable and Set UART -----------------------------

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
UARTStdioInit(0);

//--------------------------------Enable A/D-------------------------------
//
// Enable ADC0.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

//
// Enable GPIO Port D.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); //JR: Muda para port D

GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_7 | GPIO_PIN_6 | GPIO_PIN_5
| GPIO_PIN_4| GPIO_PIN_3 | GPIO_PIN_2); //JR:configura as GPIOs como ADC input channel

//*****************************************************************************
//
// Configure sequencer for trigger by processor.
//
ADCSequenceConfigure(ADC0_BASE, SEQUENCER, ADC_TRIGGER_PROCESSOR, 0);//?

// >>>>>>>>>>>>> Seção: D >>>>>>>>>>>>>
//
// Configure o ADC para Hardware Over Sampling Ciruit.
//

ADCHardwareOversampleConfigure(ADC0_BASE, 64); //?


ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 0, ADC_CTL_CH4);//D7 //configura os "Sequencers" para capturar dados de 6
//canais diferentes e armazenar os dados na FIFO.
ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 1, ADC_CTL_CH5);//D6
ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 2, ADC_CTL_CH6);//D5
ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 3, ADC_CTL_CH7);//D4
ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 4, ADC_CTL_CH12);//D3
ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 5, ADC_CTL_CH13 | ADC_CTL_IE //JR:Habilita o pino AD PD7
|ADC_CTL_END);

//
// Enable sample sequence.
//
ADCSequenceEnable(ADC0_BASE, SEQUENCER);

//
// Clear interrupt status flag.
//
ADCIntClear(ADC0_BASE, SEQUENCER);
//------------------------------------------------------------------------------

//
// Enable the peripherals used by this example.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);

//
// Enable processor interrupts.
//
IntMasterEnable();

//
// Configure the two 32-bit periodic timers.
//
TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
TimerLoadSet(TIMER0_BASE, TIMER_A, SysCtlClockGet()/3000);// set for 3Khz timer

//
// Setup the interrupts for the timer timeouts.
//
IntEnable(INT_TIMER0A);
TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);

//
// Enable the timers.
//
TimerEnable(TIMER0_BASE, TIMER_A);


//setup initialize average variables;
media_D0= 0;
media_D1= 0;
media_D2= 0;
media_D3= 0;
media_D4= 0;
media_D5= 0;



//
// Loop forever while the timers run.
//
while(1)
{

//check if count1 is 499 .
if (cont1==499)
{


TimerDisable(TIMER0_BASE, TIMER_A);

for (i=0;i<500;i++)
{
media_D0= media_D0 + (D0[i]/500);
media_D1= media_D1 + (D1[i]/500);
media_D2= media_D2 + (D2[i]/500);

media_D3= media_D3 + (D3[i]/500);
media_D4= media_D4 + (D4[i]/500);
media_D5= media_D5 + (D5[i]/500);
}

UARTprintf(">Average D0: %f<\n",media_D0);
UARTprintf(">Average D1: %f<\n",media_D1);
UARTprintf(">Average D2: %f<\n",media_D2);
UARTprintf(">Average D3: %f<\n",media_D3);
UARTprintf(">Average D4: %f<\n",media_D4);
UARTprintf(">Average D5: %f<\n",media_D5);


clr_buffer(ulADC0_Value);
clr_vetor();
media_D0= 0;
media_D1= 0;
media_D2= 0;
media_D3= 0;
media_D4= 0;
media_D5= 0;



//restart counter
cont1=0;

TimerEnable(TIMER0_BASE, TIMER_A);
}



}
}

Thanks for Attention - Renne Takao Meguro Portal

  • What is happening with Timer0 that is causing you an issue?

    I think if you want a more accurate time you should most likely reset the load count before re-enabling the timer with another call to TimerLoadSet() where you reset the cont1 value to 0.