Search code examples
cembeddedmicrocontrolleravrattiny

i have solved my issues....yet still there some doubts..clarify me



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....


Solution

  • 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.