Home Analog Wrong ADC Values while Debugging

Wrong ADC Values while Debugging

E-mail Print PDF
( 7 Votes )

Question: I have an ADC in my application.  While debugging, I place a break point after the ADC result is read.  Every time the break point is hit, I get different value from the ADC.  The input signal to the ADC is very stable.  What could be the reason for this behavior?  What is the workaround?

Answer:  ADCs in the PSoC (Incremental or Delta Sigma) are formed by a combination of analog and digital blocks with some processor intervention.  An Analog SC block is configured as a modulator and a digital block configured as a counter integrates the modulator's output for a fixed number of data cycles.  At the end of the integration time, the value in the counter (which is the ADC result) is read by the CPU.

When a break point is encountered in the project, only the CPU halts.  The analog and digital blocks of the ADC continue to run in the background.  Because of this, the counter will continue integrating the output of the Analog modulator for many conversion cycles and this corrupts the ADC result.

For example, let us consider the following code:

    int ADCResult

    void main()
    {
       // Start ADC and run in continuous sampling mode
       ADC_Start(ADC_HIGHPOWER);
       ADC_GetSamples(0);
 
       // Other code here
       .....
       .....
       while(1)
       {
          // Other code here
          .....
          while(ADC_fIsDataAvailable() == 0);
          ADCResult = ADC_iGetData();
          ADC_ClearFlag();
          asm("nop");  ---> Place breakpoint here
       }
    }

Everytime the program is executed and halts at the breakpoint, the value in ADCResult would be wrong.  There are a few workarounds for this.


Workaround-1

Clear the breakpoint on the code.  Run the program.  Place the breakpoint (by clicking on the left margin of the code) dynamically as the program is running.  When the program halts, the value in ADCResult would be the correct value.  Remove the breakpoint and run the program.  Place the breakpoint again in the same manner.  The value will be right again.


Workaround-2

Use the code below.

int ADCResult

void main()
{
   BYTE i;

   // Start ADC and run in continuous sampling mode
   ADC_Start(ADC_HIGHPOWER);
   ADC_GetSamples(0);

   // Other code here
   .....
   .....
   while(1)
   {
      // Other code here
      .....
      for(i=0; i<2; i++)
      {
         while(ADC_fIsDataAvailable() == 0);
         ADCResult = ADC_iGetData();
         ADC_ClearFlag();
      }
      asm("nop");  ---> Place breakpoint here
   }
}

In the above code, the breakpoint is hit after 3 ADC conversions.  The first two results are dropped and the third result is available in ADCResult, which will always be the correct value.  This technique is required only during the debugging phase.  In the final project, the for loop is not required. The ADC will produce correct results when the processor is running continuously.


Workaround-3

See code below.

int ADCResult;
void main()
{
 
   // Start ADC and run in continuous sampling mode
   ADC_Start(ADC_HIGHPOWER);

   // Other code here
   .....
   .....
   while(1)
   {
      // Other code here
      .....
      ADC_GetSamples(1);
      while(ADC_fIsDataAvailable() == 0);
      ADCResult = ADC_iGetDataClearFlag();
      asm("nop");  --------------------------> Break point here
   }
}

In the above code, the ADC is run in single sample mode.  The analog and digital blocks are started when the ADC_GetSamples(1) is called and the conversion is initiated.  At the end of conversion, the result is read and the analog and digital blocks are stopped.  So, the ADC result will not be corrupt during the next conversion.

Note: This workaround only works for incremental ADCs like ADCINC12, ADCINCVR, ADCINC and ADCINC14. It does not work with Deltasigma ADCs.


Comments (0)
Only registered users can write comments!