Hello,
I'm a beginner using the board Tiva C series EK-TM4C129EXL.
I need to use the ADC so in order to check my configuration, I use the UART to send the results.
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
For the moment, I haven't got any input (0V) so the UART should send 0. The timer frequency is set to 5 HZ for the UART.
Here is my code (Sorry for the french commentary, I can translate if it's 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" // System clock rate in Hz. uint32_t g_ui32SysClock; // 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 5 //Hz //100000 //Hz uint8_t LED = 0; uint32_t ADCbuffer[3], thetaSinBuffer[3], thetaCosBuffer[3]; // Configuration des ADC void ConfigureADC(void) { UARTprintf("Configuration des ADC\n"); 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_5); while(!SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0) && !SysCtlPeripheralReady(SYSCTL_PERIPH_ADC1) && !SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOE)) {} UARTprintf("ADC et ports I/O autorisés\n"); ////// Désactivation des ADC (sécurité) ADCSequenceDisable(ADC0_BASE,2); ADCSequenceDisable(ADC0_BASE,0); ADCSequenceDisable(ADC1_BASE,0); UARTprintf("Séquenceurs ADC désactivés\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\n"); ////// Activations des ADC ADCSequenceEnable(ADC0_BASE,2); ADCSequenceEnable(ADC0_BASE,0); ADCSequenceEnable(ADC1_BASE,0); UARTprintf("Activation des ADC\n"); // 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); ////// 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,2,ADCbuffer); UARTprintf("Sequence: %d %d %d\n",ADCbuffer[0],ADCbuffer[1],ADCbuffer[2]); // 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); UARTprintf("Sync.: %d %d %d %d\n",thetaSinBuffer[0],thetaSinBuffer[1],thetaCosBuffer[0],thetaCosBuffer[1]); //test: la diode s'allume si le timer a le temps d'aller au bout HWREGBITW(&LED, 0) ^= 1; // (bit 0 du registre de LED) XOR 1 GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, LED); } // Initialise le port série. Doit être appellée avant UARTprintf(). void ConfigureUART(void) { // // Enable the GPIO Peripheral used by the UART. // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // // Enable UART0. // SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); // // Configure GPIO Pins for UART mode. // GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); 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 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION); while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPION)){} GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0); GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, LED); // LED = 0 // Active le périphérique Timer 0 SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); // Enable processor interrupts IntMasterEnable(); // 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); UARTprintf("Set up timers fini\n"); // Configure les ADC ConfigureADC(); UARTprintf("Configuration ADC finie\n"); // Enable the timers. TimerEnable(TIMER0_BASE, TIMER_A); UARTprintf("Set up fini\n"); // Loop forever while the timers run. while(1){} }
The UART send this:
GO!
Set up timers fini
Configuration des ADC
ADC et ports I/O autorisés
Séquenceurs ADC désactivés
Configuration 1 finie
Configuration des ADC finie
Configurations des séquences
Activation des ADC
Configuration ADC finie
Set up fini
Sequence: 1545 1811 1466
Sync.: 1173 1151 1637 1622
Sequence: 1350 1641 1436
Sync.: 989 986 1437 1410
Sequence: 1237 1525 1394
Sync.: 911 888 1320 1286
Sequence: 1141 1434 1340
Sync.: 843 849 1230 1221
Sequence: 1102 1367 1296
Sync.: 816 800 1192 1166
Sequence: 1073 1325 1265
Sync.: 781 773 1145 1141
Sequence: 1051 1294 1238
Sync.: 780 769 1143 1133
Sequence: 1049 1278 1239
Sync.: 785 763 1150 1131
Sequence: 1047 1277 1234
Sync.: 771 754 1131 1114
Sequence: 1041 1265 1226
Sync.: 771 759 1135 1127
Sequence: 1060 1272 1227
Sync.: 773 755 1140 1125
Sequence: 1037 1259 1224
Sync.: 766 760 1130 1109
Sequence: 1037 1265 1223
Sync.: 766 773 1126 1115
Sequence: 1038 1253 1219
Sync.: 765 768 1127 1112
etc...
But if there is no input, it should be:
...
Sequence: 0 0 0
Sync.: 0 0 0 0
Sequence: 0 0 0
Sync.: 0 0 0 0
etc...
So, what am I doing wrong?
Also, considering the frequency (100kHz) that I need to get the data andmake calculations, should I configure it as in the data sheet or the driverlib/adc is ok?
If you have any question, please ask me,
Thank you