-2

uint16_t adc_value=0;
void ADC0_init(void)
{
    /* Disable digital input buffer */
    PORTA.PIN6CTRL &= ~PORT_ISC_gm;
    PORTA.PIN6CTRL |= PORT_ISC_INPUT_DISABLE_gc;
    
      /* Disable pull-up resistor */
    PORTA.PIN6CTRL &= ~PORT_PULLUPEN_bm;
    
    
    ADC0.CTRLB = VREF_ADC0REFEN_bm ;
    VREF.CTRLA = VREF_ADC0REFSEL_4V34_gc;  
  
    
    ADC0.CTRLC |= ADC_PRESC_DIV4_gc      /* CLK_PER divided by 4 */
               | ADC_REFSEL_INTREF_gc;  /* Internal reference */
  
  
    ADC0.CTRLA |= ADC_ENABLE_bm          /* ADC Enable: enabled */
               | ADC_RESSEL_10BIT_gc;   /* 10-bit mode */
    
    /* Select ADC channel */
    ADC0.MUXPOS  = ADC_MUXPOS_AIN6_gc;
}

uint16_t ADC0_read(void)
{
    /* Start ADC conversion */
    ADC0.COMMAND = ADC_STCONV_bm;
    
    /* Wait until ADC conversion done */
    while ( !(ADC0.INTFLAGS & ADC_RESRDY_bm) )
    {
        ;
    }
    /* Clear the interrupt flag by writing 1: */
    ADC0.INTFLAGS = ADC_RESRDY_bm;
    return (ADC0.RES >> 2);
}

i got a decimal value 4092 without this (ADC0.RES >> 2)...after i did this 2 bit right shift i got 1024...i dont understand what exactly going on...is right shift essential for getting 1024.....and why is that working in only after 2 bit shifting...please explain me....

  • 1
    Each right shift is essentially the same as a division by 2. That means two right shifts is a division by 2 * 2, i.e. 4. – Some programmer dude Feb 11 '23 at 05:13
  • okay..but in mode of 10 bit resolution actually the result of maximum value should be 1024 right ?.if dont do 2 bit right shift i got 4092 which is 12 bit value..? is there any mistakes of my understanding and my queries..? –  Feb 11 '23 at 05:24
  • PORTA.PIN6CTRL. Possibly not related but it is best to only do one store rather than multiple stores to setup the register you have changed the register 3 times, depending on the control register that could start the peripheral down one road then another then another. x = register. modify x. register = x is a better habit – old_timer Feb 11 '23 at 16:31

1 Answers1

1

Why are you are setting ADC0.CTRLB = VREF_ADC0REFEN_bm? VREF_ADC0REFEN_bm is intended for the VREF.CTRLB register, not the ADC0.CTRLB register.

VREF_ADC0REFEN_bm is defined as 0x02 and when you set ADC0.CTRLB to 0x02 you are setting the Sample Accumulation Number to 0x2, which means 4 samples are accumulated in the ADC Result register. That is why you have to divide by 4 to get your result back into the range of a single sample.

kkrambo
  • 6,643
  • 1
  • 17
  • 30
  • Hi Sir..im manikandan..from india....im new to embedded systems...i have some doubts and queries in embedded systems...will you please help me to get clarification...kindly share your email id please –  Feb 17 '23 at 13:22