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

SAADC does not sample

I'm trying to sample analog input but there is no value after sampling.

I tested the input by configuring it as digital input and it worked correctly.

Below is code. Any help would be greatly appreciated.

// Configure ADC and enable it
void adc_init( void )
{
    NRF_SAADC->CH[0].PSELP = 1;
    NRF_SAADC->CH[0].PSELN = 0;
    NRF_SAADC->CH[0].CONFIG = 0x20010;
    NRF_SAADC->RESOLUTION = 0;
    NRF_SAADC->RESULT.PTR = (uint32_t)adcResult;
    NRF_SAADC->RESULT.MAXCNT = 1;
    nrf_saadc_enable();
    nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
}

int main(void)
{
    // Initialize clock
    clocks_start();
    
    nrf_delay_ms(1);

    // Initialize peripherals
    gpio_init();
    adc_init();

    nrf_gpio_pin_write(LED_1,0);

    nrf_delay_ms(100);

    while (true)
    {
        nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE);
        while (nrf_saadc_event_check(NRF_SAADC_EVENT_DONE) == 0);
        nrf_adc_result = ((uint16_t)*adcResult >> 8) & 0x7F;
        nrf_saadc_event_clear(NRF_SAADC_EVENT_DONE);

        if (nrf_adc_result > 25)
        {
            nrf_gpio_pin_write(LED_2,0);
        }
        else
        {
            nrf_gpio_pin_write(LED_2,1);
        }

        if (nrf_adc_result > 50)
        {
            nrf_gpio_pin_write(LED_3,0);
        }
        else
        {
            nrf_gpio_pin_write(LED_3,1);
        }

        if (nrf_adc_result > 100)
        {
            nrf_gpio_pin_write(LED_4,0);
        }
        else
        {
            nrf_gpio_pin_write(LED_4,1);
        }

        nrf_gpio_pin_toggle(LED_1);
        nrf_delay_ms(250);


    }
}

  • int16_t * adcResult = 0;

    That points to flash address zero, which is part of the MBR and countains the lower half of the inital stack pointer.

    You should point it to something in RAM like:

    static int16_t nrf_adc_result = 0;
    int16_t * adcResult = &nrf_adc_result;

    Also, get a book about the C programming language and read it. This is a very basic beginner question, and C cannot be learned properly just from forum posts.

  • Your explanation was useful. Your insult was not.

  • LOL: This is an example on how to not use a pointer variable.

    This is how it is supposed to look:

    static volatile int16_t nrf_adc_result;
    
    int16_t readResult(){
            NRF_SAADC->RESULT.PTR = (uint32_t)&nrf_adc_result;
    
            nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
            while (nrf_saadc_event_check(NRF_SAADC_EVENT_STARTED) == 0);
            nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE);
            while (nrf_saadc_event_check(NRF_SAADC_EVENT_END) == 0);
            nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
            if (nrf_adc_result <0)
            {
                nrf_adc_result = 0;
            }
    
          return nrf_adc_result;
    }

    Note that you can eliminate the pointer variable altogether here.

    I also notices that I was mistaken above: You need to read at least two books: One for basic C programming, one for programming C on a microcontroller like the ARM Cortex-M variants. The latter tells you about interrupts and the use of volatile among many other details.

Related