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

Use AREF1(pin0.06) as analog reference voltage for ADC instead of internal VBG

Dear Sir: Could I use the external reference AREF1(pin0.06) instead of internal VBG 1.2V for ADC operation ? I do the following settings to config using external reference

   nrf_adc_config.resolution = NRF_ADC_CONFIG_RES_10BIT;
   nrf_adc_config.scaling = NRF_ADC_CONFIG_SCALING_INPUT_FULL_SCALE;
   nrf_adc_config.reference = NRF_ADC_CONFIG_REF_EXT_REF1;

But it doesn't work, is there any other settings before using external reference for ADC.

Thanks a lot

Parents
  • Hi,

    I will assume you are using nRF51. Essentially you will need to configure EXTREFSEL with AREF1 and REFSEL with External. Something like this should work (I use hardware registers by preference).

    static void adc_init(void)
    {	
    	/* Enable interrupt on ADC sample ready event*/		
    	NRF_ADC->INTENSET = ADC_INTENSET_END_Msk;   
    	sd_nvic_SetPriority(ADC_IRQn, NRF_APP_PRIORITY_LOW);  
    	sd_nvic_EnableIRQ(ADC_IRQn);
    	
    	NRF_ADC->CONFIG	= (ADC_CONFIG_EXTREFSEL_AnalogReference1 << ADC_CONFIG_EXTREFSEL_Pos) /* Bits 17..16 : ADC external reference pin selection. */
    					| (ADC_CONFIG_PSEL_AnalogInput2 << ADC_CONFIG_PSEL_Pos)					     /*!< Use analog input 2 as analog input. */
    					| (ADC_CONFIG_REFSEL_External << ADC_CONFIG_REFSEL_Pos)					     /*!< Use external voltage as reference for conversion. */
    					| (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) /*!< Analog input specified by PSEL with no prescaling used as input for the conversion. */
    					| (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos);							     /*!< 8bit ADC resolution. */ 
    	
    	/* Enable ADC*/
    	NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
    }
    

    This answer also contains some useful information.

    Best regards,

    Øyvind

Reply
  • Hi,

    I will assume you are using nRF51. Essentially you will need to configure EXTREFSEL with AREF1 and REFSEL with External. Something like this should work (I use hardware registers by preference).

    static void adc_init(void)
    {	
    	/* Enable interrupt on ADC sample ready event*/		
    	NRF_ADC->INTENSET = ADC_INTENSET_END_Msk;   
    	sd_nvic_SetPriority(ADC_IRQn, NRF_APP_PRIORITY_LOW);  
    	sd_nvic_EnableIRQ(ADC_IRQn);
    	
    	NRF_ADC->CONFIG	= (ADC_CONFIG_EXTREFSEL_AnalogReference1 << ADC_CONFIG_EXTREFSEL_Pos) /* Bits 17..16 : ADC external reference pin selection. */
    					| (ADC_CONFIG_PSEL_AnalogInput2 << ADC_CONFIG_PSEL_Pos)					     /*!< Use analog input 2 as analog input. */
    					| (ADC_CONFIG_REFSEL_External << ADC_CONFIG_REFSEL_Pos)					     /*!< Use external voltage as reference for conversion. */
    					| (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) /*!< Analog input specified by PSEL with no prescaling used as input for the conversion. */
    					| (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos);							     /*!< 8bit ADC resolution. */ 
    	
    	/* Enable ADC*/
    	NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
    }
    

    This answer also contains some useful information.

    Best regards,

    Øyvind

Children
  • Hi Yvind: It seems no work, the following is the register setting of ADC on the product, Is there something wrong ? 1. ADC->CONFIG = 0x00020822 2. ADC->INTENSET = 0x01 3. ADC->INTENCLR = 0x01 4. ADC->POWER = 0x01 If we want to use external reference voltage, should I pay attention to the hardware desgin ? Do I need to connect a capacitor from the AIN7( gpio0.06) pin to ground ?

    Thanks a lot

  • What voltage are you applying to VREF? It should be between 0.83V - 1.3V. A capacitor on the pin helps keep constant voltage, however I still think you should see something, this leads me to think that there is something wrong with your code.

  • Hi Yvind: The VREF is 1.24V, and the following is ADC related Code

    void mp_adc_config(void)
    {    
    
        //1.10 BIT ADC    2.SCALING_INPUT_FULL_SCALE     3.Vref = 1.24V  
        nrf_adc_config_t nrf_adc_config = NRF_ADC_CONFIG_DEFAULT;
    
    		nrf_adc_config.resolution = NRF_ADC_CONFIG_RES_10BIT;
    		nrf_adc_config.scaling = NRF_ADC_CONFIG_SCALING_INPUT_FULL_SCALE;
    		nrf_adc_config.reference = NRF_ADC_CONFIG_REF_EXT_REF1;
    
        // Initialize and configure ADC
        nrf_adc_configure( (nrf_adc_config_t *)&nrf_adc_config);
    
        nrf_adc_int_enable(ADC_INTENSET_END_Enabled << ADC_INTENSET_END_Pos);  /*!< Interrupt enabled. */
        NVIC_SetPriority(ADC_IRQn, NRF_APP_PRIORITY_HIGH);   //Configure the priority
        NVIC_EnableIRQ(ADC_IRQn);
    	
    		mp_adc_init();
    
    		nrf_adc_input_select(g_mpADC[MP_ADC_INDEX_TEMP].channel);
    
    		g_currAdcChannelIndex = 0;
    }
    
  • Instead of nrf_adc_configure() try calling

    NRF_ADC->CONFIG = (ADC_CONFIG_EXTREFSEL_AnalogReference1 << ADC_CONFIG_EXTREFSEL_Pos) /* Bits 17..16 : ADC external reference pin selection. */
                        | (ADC_CONFIG_PSEL_AnalogInput2 << ADC_CONFIG_PSEL_Pos)                      /*!< Use analog input 2 as analog input. */
                        | (ADC_CONFIG_REFSEL_External << ADC_CONFIG_REFSEL_Pos)                      /*!< Use external voltage as reference for conversion. */
                        | (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) /*!< Analog input specified by PSEL with no prescaling used as input for the conversion. */
                        | (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos);                              /*!< 8bit ADC resolution. */
    
  • Hi: I use the following setting as you recommanded, the voltage value I read is 1.013V, But the real value is 0.9V. And when I use internal 1.2V as reference voltage ,the value I get is close to 0.9V.

    NRF_ADC->CONFIG = (ADC_CONFIG_EXTREFSEL_AnalogReference1 << ADC_CONFIG_EXTREFSEL_Pos) /* Bits 17..16 : ADC external reference pin selection. */
                        | (ADC_CONFIG_PSEL_AnalogInput2 << ADC_CONFIG_PSEL_Pos)                      /*!< Use analog input 2 as analog input. */
                        | (ADC_CONFIG_REFSEL_External << ADC_CONFIG_REFSEL_Pos)                      /*!< Use external voltage as reference for conversion. */
                        | (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) /*!< Analog input specified by PSEL with no prescaling used as input for the conversion. */
                        | (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos);
    
Related