0
\$\begingroup\$

I am using a simple code to read from ADC pin A0. When I read from ADCH and ADCL. The result is correct only once in the startup. When I change the analog value in A0, output from the ADC don't change at all. Unless I have reset the mcu.

In the datasheet it is not state clearly that there is a register called ADC. They highlight ADCH and ADCL.

reading from register ADC work fine.

This is my simple code that don't work.

/* * Section: Function Defintion */ void ADC_Setup(){ // Enable the ADC ADCSRA |= 1<<ADEN; // Select the refence voltage to be AVcc, which is connected to Vcc in the Arduino Nano board ADMUX |= 1<<REFS0; // Set Prescaler to 128, so that the ADC clock is 16M/128= 125Khz ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); ADCSRA |= (1<<ADSC) | (1<<ADATE) | (1<<ADIF) | (1<<ADIF); sei(); } void ADC_StartConvert(){ ADCSRA |= (1<<ADSC); } uint16_t ADC_read(){ uint16_t i = ADCH*256 + ADCL; // if changed to i = ADC; it work fine!! return i; } 

What is could be the cause to make the ADC hold conversion because of reading from ADCL?

\$\endgroup\$
3
  • \$\begingroup\$ use "(((uint16_t)(ADCH))<<8 +ADCL)" \$\endgroup\$ Commented Oct 5, 2020 at 14:50
  • 2
    \$\begingroup\$ I whoud try this uint16_t i = (uint16_t) (ADCL + (ADCH*256)); becouse ADCL must be read first, then ADCH \$\endgroup\$ Commented Oct 5, 2020 at 15:09
  • \$\begingroup\$ @G36, thanks it worked. However, no any logical explanation for this. \$\endgroup\$ Commented Oct 5, 2020 at 21:20

1 Answer 1

2
\$\begingroup\$

ADCL must be read first before ADCH, as stated in the datasheet.

Use this code

/* * Section: Function Defintion */ void ADC_Setup(){ // Enable the ADC ADCSRA |= 1<<ADEN; // Select the refence voltage to be AVcc, which is connected to Vcc in the Arduino Nano board ADMUX |= 1<<REFS0; // Set Prescaler to 128, so that the ADC clock is 16M/128= 125Khz ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); ADCSRA |= (1<<ADSC) | (1<<ADATE) | (1<<ADIF); sei(); } void ADC_StartConvert(){ ADCSRA |= (1<<ADSC); } uint16_t ADC_read(){ uint16_t i = ADCL + (((uint16_t)(ADCH))<<8); return i; } 
\$\endgroup\$
2
  • \$\begingroup\$ I looked again in the datasheet and it is said that ADCL must be read first. As G36 suggested \$\endgroup\$ Commented Oct 5, 2020 at 21:22
  • 1
    \$\begingroup\$ @AshrafAlmubarak thanks for correcting me, So I am editing the code. \$\endgroup\$ Commented Oct 6, 2020 at 4:40

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.