8_Bit_ADC bit shifting

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
Can someone please explain what ledValue = (adcValue >> 7); /* Light up all LEDs up to ledValue */ LED_PORT = 0; for (i = 0; i <= ledValue; i++) { LED_PORT |= (1 << i); } 
is doing in the code mentioned below?



int main(void) {

  // -------- Inits --------- //
  uint8_t ledValue;
  uint16_t adcValue;
  uint8_t i;

  initADC0();
  LED_DDR = 0xff;

  // ------ Event loop ------ //
  while (1) {

    ADCSRA |= (1 << ADSC);                     /* start ADC conversion */
    loop_until_bit_is_clear(ADCSRA, ADSC);          /* wait until done */
    adcValue = ADC;                                     /* read ADC in */
                        /* Have 10 bits, want 3 (eight LEDs after all) */
    ledValue = (adcValue >> 7);
                                   /* Light up all LEDs up to ledValue */
    LED_PORT = 0;
    for (i = 0; i <= ledValue; i++) {
      LED_PORT |= (1 << i);
    }
    _delay_ms(50);
  }                                                  /* End event loop */
  return (0);                            /* This line is never reached */
}

Mav

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The comments tell all! Effectively you have a 8 led bargraph.
If the adc reference is 5V, each led will represent the input voltage in 5/8 volts.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
adcValue  is 16 bits, but only the lower 10 mean anything (10 bit adc)....the >>7 shoves those 10 meaningful bit over 7 places to the right, meaning only the top 3 reamain (the other 7 fall off the edge of the Earth). 

So now we are left with a 3 bit value (representing 0-7).   The next part of the code simply counts up to that value in an i loop.  Each i pass, the port is or'd with a  1-bit shifted i positions left, thus turning on one additional led position (the next position).  If the 3 bit value was 5, we'd end up turning on 5 leds (one by one).  It happens so fast that it appears they light up simultaneously.  You could add a small delay in the loop for a  "bargraph"  effect.

 

Note your code does not explicitly set up the adc for use (such as channel selection, reference level, clocking rate, enable ADC power, etc), other than: 

 initADC0();

Whatever that does (in case you have trouble).  It could just be a return statement, for all we know---that wouldn't work!

 

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!