Code:
buffer = (ADCH<<8) | ADCL;
Das ist ein Kunstfehler. Die Reihenfolge, in der das ausgewertet wird, ist
AFAIK nicht spezifiziert in C, so daß ADCL vor ADCH gelesen werden kann. Der Zugriff muss aber in einer bestimmten Reihenfolge getan werden. Das erreicht man, indem man auf ADC als 16-Bit-Register zugreift, und nicht, indem man es von Hand in zwei 8-Bit-Register zerbröselt.

Klarere, einfacher zu lesen und auf jeden Fall korrekt ist also
Code:
buffer = ADC;
. Schneller und codesparender ist's auch noch...