PIC24F: Is there any risk of dirty reads when reading the ADC results buffer?

Discussion in 'Embedded Systems and Microcontrollers' started by Robin66, May 4, 2017.

  1. Robin66

    Thread Starter Member

    Jan 5, 2016
    235
    6
    Hi, to save precious cycles I'd like to avoid interrupting after each ADC acquisition. Sometimes I'm round-robining, other times I'm just repeatedly sampling the same ANx to ensure I have the most up-to-date measurement for some other async function. Is there any risk of dirty reads if I just reference the appropriate ADC1BUFx when the result is consumed rather than using intermediary variables? I don't see any mention of such a risk in the family reference below. However when I have attempted this in the past I have noticed 0's coming thru occasionally, but I can't be sure this wasn't some other bug in my code. At the time I just backed away assuming it was a dirty read but now reading the docs I think it was more likely my bug.

    http://ww1.microchip.com/downloads/en/DeviceDoc/39739a.pdf
     
  2. Picbuster

    Well-Known Member

    Dec 2, 2013
    895
    117
    The external impedance connected to the adc is added to the internal one.
    When input capacitor is to high and signal fluctuation exist you need a longer sample time or reduce the input cap.
    At the other hand, if no extra input cap is used and a random signal fluctuation is applied problems may arise.
    I do use the pic's a lot and ADC problems never occur.

    create a timer and generate start adc ( ADCON0bits.GO = On;)
    Read the adc in an interrupt.
    if (PIR1bits.ADIF)
    {
    PIR1bits.ADIF = 0;// Clear A/D conversion complete interrupt flag
    Delay1KTCYx(5);// Delay for 5000 instruction cycles see manual
    Voltage.Vbatt[ADCON0bits.CHS0] = (float)(ADRESH*256 + ADRESL) ;
    }

    Each time you want a value read Voltage.Vbatt[ 0] for that channel.
    Delay = sum of timer + adc conversion
    Picbuster




    Picbuster.
     
  3. Robin66

    Thread Starter Member

    Jan 5, 2016
    235
    6
    Thanks for the reply @Picbuster. Your interrupt per acquisition is exactly what I was trying to avoid. It looks like you're using a PIC18 device though which only has 1 ADC results buffer so you don't have a choice if you want to sample other channels. The PIC24 family have a device per channel. I've ensured that my sampling times are adequate for the RC of the channel. Besides, if this was an issue I'd expect erroneous but non-zero results. Why the 5000 instruction delay?
     
  4. Picbuster

    Well-Known Member

    Dec 2, 2013
    895
    117
    in manual
    After this acquisition time has elapsed, the A/D conversion can be
    started. An acquisition time can be programmed to
    occur between setting the GO/DONE
    bit and the actual
    start of the conversion.


    in my case I calculated 5000 but you should verify with your own configuration.
    Why would you like avoid interrupt as you can control this by software?

    Picbuster
     
  5. Robin66

    Thread Starter Member

    Jan 5, 2016
    235
    6
    I think you've misunderstood elements of your code. The delay is meant to allow adequate sampling, but your delay is after the sampling AND conversion have already completed. You're just delaying to read a register that we know has already been written to because an interrupt has occurred based on that fact.
     
    Last edited: May 5, 2017
  6. Picbuster

    Well-Known Member

    Dec 2, 2013
    895
    117
    You are absolutely correct however I used the delay between samples taken.
    But yes it is not really needed.
    Picbuster
     
  7. Robin66

    Thread Starter Member

    Jan 5, 2016
    235
    6
    Ok, I've managed to isolate this and found that you can get an erroneous 0 read if the read clashes with the end of sampling/start of conversion. The buffer value will then remain at 0 until the conversion is complete and the bufffer is updated with the new value. I don't see this documented anyway so I suspect this is a bug
     
Loading...