Other Parts Discussed in Thread: C2000WARE
Hello,
The below code is given in the C2000Ware example for continuous ADC sampling:
// // Setup the ADC for continuous conversions on channel 0 // setupADCContinuous(ADCA_BASE, 0U); // // Initialize results buffer // for(resultsIndex = 0; resultsIndex < RESULTS_BUFFER_SIZE; resultsIndex++) { adcAResults[resultsIndex] = 0; } resultsIndex = 0; // // Enable global Interrupts and higher priority real-time debug events: // EINT; // Enable Global interrupt INTM ERTM; // Enable Global realtime interrupt DBGM // // Take conversions indefinitely in loop // do { // // Enable ADC interrupts // ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER1); ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER2); ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER3); ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER4); // // Clear all interrupts flags(INT1-4) // HWREGH(ADCA_BASE + ADC_O_INTFLGCLR) = 0x000F; // // Initialize results index // resultsIndex = 0; // // Software force start SOC0 to SOC7 // HWREGH(ADCA_BASE + ADC_O_SOCFRC1) = 0x00FF; // // Keep taking samples until the results buffer is full // while(resultsIndex < RESULTS_BUFFER_SIZE) { // // Wait for first set of 8 conversions to complete // while(false == ADC_getInterruptStatus(ADCA_BASE, ADC_INT_NUMBER3)); // // Clear the interrupt flag // ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER3); // // Save results for first 8 conversions // // Note that during this time, the second 8 conversions have // already been triggered by EOC6->ADCIN1 and will be actively // converting while first 8 results are being saved // adcAResults[resultsIndex++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0); adcAResults[resultsIndex++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER1); adcAResults[resultsIndex++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER2); adcAResults[resultsIndex++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER3); adcAResults[resultsIndex++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER4); adcAResults[resultsIndex++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER5); adcAResults[resultsIndex++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER6); adcAResults[resultsIndex++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER7); // // Wait for the second set of 8 conversions to complete // while(false == ADC_getInterruptStatus(ADCA_BASE, ADC_INT_NUMBER4)); // // Clear the interrupt flag // ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER4); // // Save results for second 8 conversions // // Note that during this time, the first 8 conversions have // already been triggered by EOC14->ADCIN2 and will be actively // converting while second 8 results are being saved // adcAResults[resultsIndex++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER8); adcAResults[resultsIndex++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER9); adcAResults[resultsIndex++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER10); adcAResults[resultsIndex++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER11); adcAResults[resultsIndex++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER12); adcAResults[resultsIndex++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER13); adcAResults[resultsIndex++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER14); adcAResults[resultsIndex++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER15); } // // Disable all ADCINT flags to stop sampling // ADC_disableInterrupt(ADCA_BASE, ADC_INT_NUMBER1); ADC_disableInterrupt(ADCA_BASE, ADC_INT_NUMBER2); ADC_disableInterrupt(ADCA_BASE, ADC_INT_NUMBER3); ADC_disableInterrupt(ADCA_BASE, ADC_INT_NUMBER4); // // At this point, adcAResults[] contains a sequence of conversions // from the selected channel // // // Software breakpoint, hit run again to get updated conversions // asm(" ESTOP0"); }
I have a couple of questions regarding the code. First of all, is this code just required upon start-up, and then the continuous sampling begins after the last EOC is generated to trigger the first set of 8 conversions to be made again? It seems that the benefit of continuous sampling is that it can be performed in the background of the CPU, but this code shows that the CPU has to do a lot of waiting until the arrays are filled with samples, which seems to defeat the purpose.
What happens if an interrupt is received by the CPU while these measurements are being taken? Does it jump to that interrupt and return to the continuous sampling once the ISR has been serviced? What if the ISR requires the array to be filled with results, for example if the array is used within the control law accelerator to implement a PID controller?
Since the array is so large, with 256 elements of 12- or 16-bit values, how would one average them to get say an average current or voltage that can be used within the CLA to implement a control law using the DCL? Adding and averaging the results would probably take some time, and would there be a data type large enough to store the intermediate result before casting to a 12- or 16-bit integer for the controller?
Best regards,
Joel