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

SAADC,NRF52832,How to calculata accurate sampling interval

void saadc_init(void)
{
NVIC_EnableIRQ(SAADC_IRQn);
NVIC_ClearPendingIRQ(SAADC_IRQn);
NRF_SAADC->RESOLUTION = SAADC_RESOLUTION_VAL_10bit;

// Configure the SAADC channel with AIN0 (P0.02) as positive input, no negative input(single ended).
NRF_SAADC->CH[0].PSELP = SAADC_CH_PSELP_PSELP_AnalogInput0 << SAADC_CH_PSELP_PSELP_Pos;
NRF_SAADC->CH[0].PSELN = SAADC_CH_PSELN_PSELN_NC << SAADC_CH_PSELN_PSELN_Pos;

NRF_SAADC->CH[0].CONFIG = (( SAADC_CH_CONFIG_BURST_Disabled << SAADC_CH_CONFIG_BURST_Pos ) | // Burst mode is disabled (normal operation)
                          ( SAADC_CH_CONFIG_MODE_SE         << SAADC_CH_CONFIG_MODE_Pos  ) | // Single ended, PSELN will be ignored, negative input to ADC shorted to GND
                          ( SAADC_CH_CONFIG_TACQ_20us       << SAADC_CH_CONFIG_TACQ_Pos  ) | // Acquisition time, the time the ADC uses to sample the input voltage
                          ( SAADC_CH_CONFIG_REFSEL_VDD1_4  << SAADC_CH_CONFIG_REFSEL_Pos ) | // VDD/4 as reference
                          ( SAADC_CH_CONFIG_GAIN_Gain1_4   << SAADC_CH_CONFIG_GAIN_Pos   ) | // Gain control
                          ( SAADC_CH_CONFIG_RESN_Bypass    << SAADC_CH_CONFIG_RESN_Pos   ) | // Bypass resistor ladder
                          ( SAADC_CH_CONFIG_RESP_Bypass    << SAADC_CH_CONFIG_RESP_Pos   )); // Bypass resistor ladder

// Configure sample rate. Minimum sample rate is 16,000,000/2047 = 7816.3 Samples pr second => 0.128ms interval
  // Configure sample rate. Minimum sample rate is 16,000,000/8000 = 2000 Samples pr second

NRF_SAADC->SAMPLERATE = ( SAADC_SAMPLERATE_MODE_Timers << SAADC_SAMPLERATE_MODE_Pos) |
                         ( 8000 << SAADC_SAMPLERATE_CC_Pos );

/* RAM Bufffer pointer for ADC Result*/
NRF_SAADC->RESULT.PTR  =(uint32_t)&m_buffer_pool;

/* Number of Sample Count*/
NRF_SAADC->RESULT.MAXCNT = SAMPLES_IN_BUFFER;

// Enable SAADC END interrupt to do maintainance and printing of values. 
NRF_SAADC->INTENSET = SAADC_INTENSET_END_Enabled << SAADC_INTENSET_END_Pos;
NVIC_EnableIRQ(SAADC_IRQn);
}

I have do a test accurate sampling interval used rtc0. I used ( 8000 << SAADC_SAMPLERATE_CC_Pos ), It must be 16,000,000/8000 = 2000 Samples pr second, INRF_SAADC->RESULT.MAXCNT = SAMPLES_IN_BUFFER is 100, add time count at SAADC_IRQHandler,
DEBUG output is APP:DEBUG: Time taken: 1.162201 sec

APP:DEBUG: Time taken: 2.322083 sec

APP:DEBUG: Time taken: 3.481964 sec

APP:DEBUG: Time taken: 4.641876 sec

APP:DEBUG: Time taken: 5.801758 sec

100*100 = 10000,must used 10000/samplerate(2000), is about 5sec.but in the log, it only used 1sec. why???

void SAADC_IRQHandler(void)
{
// Clear events
	//NRF_LOG_INFO("SAADC_IRQHandler\r\n");
  if(adc_count == 100)
	{
		  adc_count = 0;
			nrf_gpio_pin_clear(17);
			counter=NRF_RTC0->COUNTER;
			sprintf(tx_message, "\r\n Time taken: %6f sec \r\n", (float)counter/32768);
			NRF_LOG_DEBUG("%s\r\n",(uint32_t)tx_message);
	}
	else
	{
		  adc_count ++;
            }
}
Related