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.

Tiva C series TM4C129EXL - ADC sequence - Maximum sampling frequency

Hello,

I am currently working on a project with TM4C129EXL. I need to use a specifc ADC sequence (See the code below). I wanted to change the timer frequency (400000 Hz) , but it seems to run up to about 100000Hz (compared a counter in the timer with a stopwatch).

When I add some code, it runs up to about 15000Hz.

The datasheet gives the maximum number of sample, wich is 2MSPS.

I suppose there is some kind of limitations here. Can you explain? Maybe my code is wrong?

Thank you.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>

#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/timer.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"
#include "driverlib/adc.h"
#include "drivers/pinout.h"
#include "drivers/buttons.h"
#include "driverlib/fpu.h"
#include "driverlib/pwm.h"

#include "Custom files/constantes.h"
#include "Custom files/maths.h"
#include "Custom files/correcteurs.h"

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

// Réglages des paramètres du programme
// fréquence d'échantillonnage
#define TMR0_FREQ 100000 //Hz

// Horloge
uint32_t g_ui32SysClock;

// Etat de la diode
uint8_t LED = 0;

// variables analogiques
float tension;
float temp;
float pot;
float sinus;
float cosinus;
float courant[NBECH_COURANT];
float v[NBECH_V]; //vitesse
float x[NBECH_X]; //position

float *adrTest;
float test;
int *adrCompteurTemps;

uint32_t ADCbuffer[4], thetaSinBuffer[1], thetaCosBuffer[1];

// Initialise le timer 0
void
ConfigureTIMER0(void)
{
	// Active le périphérique Timer 0
	SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);

	// Configure the 32-bit periodic timers.
	TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
	TimerLoadSet(TIMER0_BASE, TIMER_A, g_ui32SysClock/TMR0_FREQ);

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

// Initialise les ADC et les GPIO associées
void
ConfigureADC(void)
{
	SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);

	ADCReferenceSet(ADC0_BASE, ADC_REF_INT);
	ADCReferenceSet(ADC1_BASE, ADC_REF_INT);

	GPIOPinTypeADC(GPIO_PORTE_BASE,GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5);

	while(!SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0) && !SysCtlPeripheralReady(SYSCTL_PERIPH_ADC1) && !SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOE))
	{}

	////// Désactivation des ADC (sécurité)
	ADCSequenceDisable(ADC0_BASE,2);
	ADCSequenceDisable(ADC0_BASE,0);
	ADCSequenceDisable(ADC1_BASE,0);

	////// Configuration des ADC
	// Séquence courant -> température -> potentiomètre
	ADCSequenceConfigure(ADC0_BASE,2,ADC_TRIGGER_PROCESSOR,0); //ADC0 Sequence 2 déclenchement processeur priorité 0 (Haute)

	//positionSin et positionCos sync
	ADCSequenceConfigure(ADC0_BASE,0,ADC_TRIGGER_PROCESSOR,0);
	ADCSequenceConfigure(ADC1_BASE,0,ADC_TRIGGER_PROCESSOR,0);

	////// Configuration des séquences
	// Séquence courant -> température -> potentiomètre
	ADCSequenceStepConfigure(ADC0_BASE,2,0,ADC_CTL_CH1); //Courant
	ADCSequenceStepConfigure(ADC0_BASE,2,1,ADC_CTL_CH9); //vitesse
	ADCSequenceStepConfigure(ADC0_BASE,2,2,ADC_CTL_CH2); //Température
	ADCSequenceStepConfigure(ADC0_BASE,2,3,ADC_CTL_CH3|ADC_CTL_IE|ADC_CTL_END); //Potentiomètre

	// positionSin et positionCos sync
	ADCSequenceStepConfigure(ADC0_BASE,0,0,ADC_CTL_CH0|ADC_CTL_IE|ADC_CTL_END);
	ADCSequenceStepConfigure(ADC1_BASE,0,0,ADC_CTL_CH8|ADC_CTL_IE|ADC_CTL_END);

	////// Activations des ADC
	ADCSequenceEnable(ADC0_BASE,2);
	ADCSequenceEnable(ADC0_BASE,0);
	ADCSequenceEnable(ADC1_BASE,0);

	// Reset des flags d'interuption des ADC
	ADCIntClear(ADC0_BASE,2);
	ADCIntClear(ADC0_BASE,0);
	ADCIntClear(ADC1_BASE,0);
}

// Fonction d'interuption du timer 0
void
Timer0IntHandler(void)
{
	// Reset le flag de l'interuption du timer
	TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);

	static int compteurTemps = 0;
	adrCompteurTemps = &compteurTemps;

	//////////////////////////////////////////////////////////////////////////
	////// ADC

	// initialise le flag de l'interuption de l'ADC
	ADCIntClear(ADC0_BASE,2);

	// Déclenche la conversion
	ADCProcessorTrigger(ADC0_BASE,2);
	while(!ADCIntStatus(ADC0_BASE,2,false)){} // attend la fin de la conversion

	// Reset le flag de l'interuption de l'ADC
	ADCIntClear(ADC0_BASE,2);

	// Lecture des données
	ADCSequenceDataGet(ADC0_BASE,2,ADCbuffer);

	// Calculs et enregistrement
	actualiseEchantillons(courant,NBECH_COURANT);
	courant[0] = ADCbuffer[0]*GAIN_COURANT-OFFSET_COURANT;

	actualiseEchantillons(v,NBECH_V);
	//v[0] = ADCbuffer[1]*GAIN_VITESSE-OFFSET_VITESSE;
	v[0] = -1.825101272*((ADCbuffer[1]-1848.246159)*1.510773788/1848.246159);
	temp = ADCbuffer[2]*GAIN_TEMP+OFFSET_TEMP;
	pot = ADCbuffer[3]*GAIN_POT+OFFSET_POT;

	// position, sync
	ADCIntClear(ADC0_BASE,0);
	ADCIntClear(ADC1_BASE,0);

	// déclenche les conversions synchronisées
	ADCProcessorTrigger(ADC1_BASE,(0|ADC_TRIGGER_WAIT)); // ADC-1 en attente de déclenchement
	ADCProcessorTrigger(ADC0_BASE,(0|ADC_TRIGGER_SIGNAL)); // ADC-0 en déclenchement global
	while(!ADCIntStatus(ADC0_BASE,0,false)){} // attend la fin de la conversion

	// Reset le flag de l'interuption de l'ADC
	ADCIntClear(ADC0_BASE,0);
	ADCIntClear(ADC1_BASE,0);

	// Lecture des données
	ADCSequenceDataGet(ADC0_BASE,0,thetaSinBuffer);
	ADCSequenceDataGet(ADC1_BASE,0,thetaCosBuffer);

	// Calculs et enregitrement //max (erreur capteur + erreur monAtan) = 0.152 mm
	sinus = (thetaSinBuffer[0]*GAIN_SINCOS-OFFSET_SIN)*GAIN_NL_SIN;
	cosinus = (thetaCosBuffer[0]*GAIN_SINCOS-OFFSET_COS)*GAIN_NL_COS;

	actualiseEchantillons(x,NBECH_X);
	x[0] = GAIN_X*monAtan2(cosinus,sinus,3)+OFFSET_X;

	compteurTemps++;
	test = (float)compteurTemps/TMR0_FREQ;
	adrTest = &test;

	//////////////////////////////////////////////////////////////////////////
	////// Test de fin de timer
	HWREGBITW(&LED, 0) ^= 1; // (bit 0 du registre de LED) XOR 1
	GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, LED);
}

//	Main: Initialisation et boucle infinie
int
main(void)
{
	////// Set up

	// Règle l'horloge sur le cristal à 120MHz

	g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
			SYSCTL_OSC_MAIN |
			SYSCTL_USE_PLL |
			SYSCTL_CFG_VCO_480), CLK_FREQ);

	// Permet d'utiliser les virgules flottantes (nombres réels)
	FPULazyStackingEnable();
	FPUEnable();

	// Active le port des diodes
	PinoutSet(false, false);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
	while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPION)){}
	GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0 | GPIO_PIN_1);
	GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0 | GPIO_PIN_1, 0);

	// Autorise les interuptions
	IntMasterEnable();

	// Configure le timer pour l'échantillonnage
	ConfigureTIMER0();

	// Configure les ADC
	ConfigureADC();

	// initialisation des tableaux de stockage des données
	initialiseTableau(courant, NBECH_COURANT);
	initialiseTableau(v, NBECH_V);
	initialiseTableau(x, NBECH_X);

	// Lance le timer
	TimerEnable(TIMER0_BASE, TIMER_A);

	// Boucle infinie en parallèle du timer
	while(1)
	{
	}
}





/*********************************************
* These functions are defined in another file
*********************************************/
void actualiseEchantillons(float tab[], int dim){
	float temp;
	int i;
	for(i = dim-1; i > 0; i = i--)
	{
		temp = tab[i];
		tab[i] = tab[i-1];
		tab[i-1] = temp;
	}
}

void initialiseTableau (float tableau[], int dim){
	int i;
	for(i = 0; i<dim; i++)
	{
		tableau[i] = 0.0;
	}
}

**Attention** This is a public forum