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