Hello,
I'm trying to write some code with the ADC. I have 5 sensors and I need to sample their signal with a sampling frequency of 100kHz. In my code, I try to do it this way:
- Sample from pin PE0 with ADC0, sample sequencer SS2, first.
- Sample from pin PE0 with ADC0, sample sequencer SS2, second.
- Sample from pin PE0 with ADC0, sample sequencer SS2, last.
For the last 2 sensors, I need to synchronize twice of their samples (2 samples for each sensor) so:
- Sample from pin PE3 with ADC0, sample sequencer SS0, sync. with sample from pin PE5 with ADC1, sample sequencer SS0,
- Sample from pin PE3 with ADC0, sample sequencer SS0, a second time sync. with sample from pin PE5 with ADC1, sample sequencer SS0 a second time
Here is my code (Sorry for the french commentary, I can translate if necessary but I think the code is understandable like this)
#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <stdbool.h> #include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "inc/hw_types.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 "Custom files/constantes.h" #include "Custom files/maths.h" #include "Custom files/fichier.h" // // UART0 connecté au Port Série Virtuel et fonctionnant avec la configuration 115200, 8-N-1, // utilisé pour l'affichage de message via le logiciel X-CTU (ou tout autre logiciel) // // // System clock rate in Hz. // uint32_t g_ui32SysClock; // // Flags that contain the current value of the interrupt indicator as displayed // on the UART. // uint32_t g_ui32Flags; int volatile LED = 0; // // The error routine that is called if the driver library encounters an error. // #ifdef DEBUG void __error__(char *pcFilename, uint32_t ui32Line) { } #endif // // Définition des variables utiles // #define TMR0_FREQ 100000 //Hz uint32_t ADCbuffer[3], thetaSinBuffer[3], thetaCosBuffer[3]; float volatile courant; float volatile temp; float volatile pot; float volatile tang; float volatile theta[2]; float volatile position[2]; float volatile vitesse; // // Configuration des ADC // void ConfigureADC(void) { UARTprintf("Configuration des ADC\n"); ////// 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) UARTprintf("Configuration 1 finie\n"); //positionSin et positionCos sync ADCSequenceConfigure(ADC0_BASE,0,ADC_TRIGGER_PROCESSOR,0); ADCSequenceConfigure(ADC1_BASE,0,ADC_TRIGGER_PROCESSOR,0); UARTprintf("Configuration des ADC finie\n"); ////// 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_CH2); //Température ADCSequenceStepConfigure(ADC0_BASE,2,2,ADC_CTL_CH3|ADC_CTL_IE|ADC_CTL_END); //Potentiomètre // positionSin et positionCos sync // séquence de 2 échantillons pour la dérivée ADCSequenceStepConfigure(ADC0_BASE,0,0,ADC_CTL_CH0); ADCSequenceStepConfigure(ADC0_BASE,0,1,ADC_CTL_CH0|ADC_CTL_IE|ADC_CTL_END); ADCSequenceStepConfigure(ADC1_BASE,0,0,ADC_CTL_CH8); ADCSequenceStepConfigure(ADC1_BASE,0,1,ADC_CTL_CH8|ADC_CTL_IE|ADC_CTL_END); UARTprintf("Configurations des séquences"); ////// Activations des ADC ADCSequenceEnable(ADC0_BASE,2); ADCSequenceEnable(ADC0_BASE,0); ADCSequenceEnable(ADC0_BASE,1); UARTprintf("Activation des ADC"); // 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 ROM_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT); ////// 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 // Reste le flag de l'interuption de l'ADC ADCIntClear(ADC0_BASE,2); // Lecture des données ADCSequenceDataGet(ADC0_BASE,3,&ADCbuffer[0]); // Calculs et enregistrement courant = ADCbuffer[0]*GAIN_COURANT+OFFSET_COURANT; temp = ADCbuffer[1]*GAIN_TEMP+OFFSET_TEMP; pot = ADCbuffer[2]*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 // Reste le flag de l'interuption de l'ADC ADCIntClear(ADC0_BASE,0); ADCIntClear(ADC1_BASE,0); // Lecture des données ADCSequenceDataGet(ADC0_BASE,2,&thetaSinBuffer[0]); ADCSequenceDataGet(ADC1_BASE,2,&thetaCosBuffer[0]); // Calculs et enregitrement tang = (float)(thetaSinBuffer[0]-OFFSET_THETA)/((float)(thetaCosBuffer[0]-OFFSET_THETA))*GAIN_THETA; theta[0] = monAtan(tang,3)*180/PI; tang = (float)(thetaSinBuffer[1]-OFFSET_THETA)/((float)(thetaCosBuffer[1]-OFFSET_THETA))*GAIN_THETA; theta[1] = monAtan(tang,3)*180/PI; position[0] = GAIN_X*theta[0]-OFFSET_X; position[1] = GAIN_X*theta[1]-OFFSET_X; vitesse = (position[1]-position[0])*TMR0_FREQ; } // // Initialise le port série. Doit être appellée avant UARTprintf(). // void ConfigureUART(void) { // // Enable the GPIO Peripheral used by the UART. // ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // // Enable UART0. // ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); // // Configure GPIO Pins for UART mode. // ROM_GPIOPinConfigure(GPIO_PA0_U0RX); ROM_GPIOPinConfigure(GPIO_PA1_U0TX); ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, CLP_D2_PIN | CLP_D1_PIN); // // Initialize the UART for console I/O. // UARTStdioConfig(0, 115200, g_ui32SysClock); } // // Set up, loop forever // 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), 120000000); // // Initialisation du port série // ConfigureUART(); UARTprintf("GO\n"); // // Active le port des diodes // ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION); // // Active la pin de la diode D1 (PN1) // ROM_GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, CLP_D1_PIN); // // Active le périphérique Timer 0 // ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); // // Enable processor interrupts. // ROM_IntMasterEnable(); // // Configure the 32-bit periodic timers. // ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC); ROM_TimerLoadSet(TIMER0_BASE, TIMER_A, g_ui32SysClock/TMR0_FREQ); // // Setup the interrupts for the timer timeouts. // ROM_IntEnable(INT_TIMER0A); ROM_TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT); UARTprintf("Set up timers fini\n"); // // Configure les ADC // ConfigureADC(); UARTprintf("Configuration ADC finie\n"); // // Enable the timers. // ROM_TimerEnable(TIMER0_BASE, TIMER_A); // // Loop forever while the timers run. // UARTprintf("Set up fini"); while(1){} }
I can build and debug the code, I haven't got any error, but I've found out that the code get stuck in the ADC configuration, with
ADCSequenceConfigure(ADC0_BASE,2,ADC_TRIGGER_PROCESSOR,0); (UART is silent after this line, that's how I know).
I haven't got any error so I don't know what's going on.
I'm a new member of the TI community so that's my first try with CCS and Tiva C series.
This code is inspired by this post:
The project have been created from the exemple "timer". I thinks the paths are ok because the exemple code (copy/paste) works .
Maybe the startup file is not correct. It's the same as in the timer exemple.
If you have any questions, please let me know.
Thank you