This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

SAADC nrf52832

hello, I have two questions for SAADC of nrf52832 when we use nrf52832 SAADC for voltage measurement.

The AIN0 is connected to the pin to be measured(the voltage is about 1.5V, use SE mode, so the negative
input will be shorted to ground internally ), the output of SAADC is 850(the result beating frequently between 850 to 856).

my SAADC config is bellow:
NRF_SAADC->CH[channel].CONFIG = ((SAADC_CH_CONFIG_RESN_Bypass << SAADC_CH_CONFIG_RESN_Pos)|
(SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESP_Pos)|
(SAADC_CH_CONFIG_GAIN_Gain1_3<< SAADC_CH_CONFIG_GAIN_Pos)|
(SAADC_CH_CONFIG_REFSEL_Internal<<SAADC_CH_CONFIG_REFSEL_Pos)|
(SAADC_CH_CONFIG_TACQ_10us<< SAADC_CH_CONFIG_TACQ_Pos)|
(SAADC_CH_CONFIG_MODE_SE<<SAADC_CH_CONFIG_MODE_Pos) );
NRF_SAADC->CH[channel].PSELP = SAADC_CH_PSELP_PSELP_AnalogInput0;
NRF_SAADC->CH[channel].PSELN = SAADC_CH_PSELP_PSELP_NC;
NRF_SAADC->RESULT.MAXCNT = 1;
NRF_SAADC->RESOLUTION = SAADC_RESOLUTION_VAL_10bit;
NRF_SAADC->OVERSAMPLE = SAADC_OVERSAMPLE_OVERSAMPLE_Bypass;
NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Enabled << SAADC_ENABLE_ENABLE_Pos);
NRF_SAADC->INTENSET = SAADC_INTENSET_END_Msk;

then read the result:

NRF_SAADC->TASKS_START = 1;
NRF_SAADC->TASKS_SAMPLE = 1;

uint32_t saadc_timeout = 100000;
while ((NRF_SAADC->EVENTS_END == 0U)&& (saadc_timeout > 0))
{
saadc_timeout--;
}
NRF_SAADC->EVENTS_END = 0;

NRF_SAADC->RESULT.PTR = (uint32_t)saadc_value_data;


My question is :
1) RESULT = [V(P) – V(N) ] * GAIN/REFERENCE * 2(RESOLUTION - m)
RESULT = 850/1024 = 0.83
[V(P) – V(N) ] * GAIN/REFERENCE * 2(RESOLUTION - m) = 1.5V * Gain1_3 / (0.6V * 2) = 0.417, it's not equall to RESULT, why?


2) The SAADC output is beating frequently between 850 to 856(for example 851,853,855...), is it normal?

  • In a previous test, you reported 850 - 856, what has changed since then? ” It's because I add an data processing after the adc result,  the result now beating frequently from 642 to 695 is because of this data processing . To avoid the impact of that, I delete the data processing this time, and do the experiment again.

    This time I use Voltage source, not battery.

    I use SAADC_CH_CONFIG_TACQ_10us and SAADC_OVERSAMPLE_OVERSAMPLE_Bypass, the SAADC output is beating frequently between 850 to 856.

    then I config SAADC_CH_CONFIG_TACQ_10us and SAADC_OVERSAMPLE_OVERSAMPLE_Over2x, I found that sometimes, it timeout. then I config SAADC_CH_CONFIG_TACQ_40us , it also  timeout sometimes. (the SAADC output is beating  between 855 to 856,but timeout is problem). 

    My question is :
    1) how to avoid timeout when I use SAADC_OVERSAMPLE_OVERSAMPLE_Over2x.

    2) when I use SAADC_OVERSAMPLE_OVERSAMPLE_Over2x, is the SAADC acquisition time  longer than SAADC_OVERSAMPLE_OVERSAMPLE_Bypass? 

    how long it takes in acquisition when I config SAADC_OVERSAMPLE_OVERSAMPLE_Over2x and SAADC_OVERSAMPLE_OVERSAMPLE_Bypass?

    my SAADC config is bellow:

    NRF_SAADC->CH[channel].CONFIG = ((SAADC_CH_CONFIG_RESN_Bypass << SAADC_CH_CONFIG_RESN_Pos)|
    (SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESP_Pos)|
    (SAADC_CH_CONFIG_GAIN_Gain1_3<< SAADC_CH_CONFIG_GAIN_Pos)|
    (SAADC_CH_CONFIG_REFSEL_Internal<<SAADC_CH_CONFIG_REFSEL_Pos)|
    (SAADC_CH_CONFIG_TACQ_10us<< SAADC_CH_CONFIG_TACQ_Pos)|
    (SAADC_CH_CONFIG_MODE_SE<<SAADC_CH_CONFIG_MODE_Pos) );
    NRF_SAADC->CH[channel].PSELP = SAADC_CH_PSELP_PSELP_AnalogInput0;
    NRF_SAADC->CH[channel].PSELN = SAADC_CH_PSELP_PSELP_NC;
    NRF_SAADC->RESULT.MAXCNT = 1;
    NRF_SAADC->RESOLUTION = SAADC_RESOLUTION_VAL_10bit;
    NRF_SAADC->OVERSAMPLE = SAADC_OVERSAMPLE_OVERSAMPLE_Bypass;
    NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Enabled << SAADC_ENABLE_ENABLE_Pos);
    NRF_SAADC->INTENSET = SAADC_INTENSET_END_Msk;

    then read the result:

    NRF_SAADC->TASKS_START = 1;

    while (NRF_SAADC->EVENTS_STARTED == 0U);
    NRF_SAADC->TASKS_SAMPLE = 1;

    uint32_t saadc_timeout = 100000;
    while ((NRF_SAADC->EVENTS_END == 0U)&& (saadc_timeout > 0))
    {
    saadc_timeout--;
    }
    NRF_SAADC->EVENTS_END = 0;

    NRF_SAADC->RESULT.PTR = (uint32_t)saadc_value_data;

  • 1)
    What do you mean by timeout? That the EVENTS_END does not fire? 

    Why do you set RESULT.PTR after you've completed the sample conversion? The RESULT registers need to be set prior to enabling the START task. 

    2)
    Oversampling means that you take x times more samples and average them out. The time it takes to sample and convert one data point with oversampling is OVERSAMPLE x (Acquisition time + Conversion time), where the Conversion time is less than 2µs. 


  • NRF_SAADC->RESULT.PTR = (uint32_t)saadc_value_data; is to get the result in saadc_value_data,not to set the result.

    when I use (uint32_t)saadc_value_data[0] = NRF_SAADC->RESULT.PTR, I get 0, but when I use NRF_SAADC->RESULT.PTR = (uint32_t)saadc_value_data; I get the result. So there's a problem?

    timeout means EVENTS_END does not fire.

  • That's not how the SAADC works, the RESULT registers need to be set prior to enabling the START task.  see EasyDMA.

  • thank you, I seemed the example, the RESULT registers is set prior to enabling the START task.

    and the EVENTS_END does not fire when oversampling is OVERSAMPLE x is because the  BURST mode must be set.

    now the OVERSAMPLE mode works, but the result seems not better than bypass mode, both of them are  beating frequently between 850 to 856.

Related