#### khatus

Joined Jul 2, 2018
95
I am trying to understand how adc works and also trying to make an ADC function

If the result is Right justified can anyone describe how the adc value stored??
And IS ADRES is a valid MCU register??

If the adc value taken is 563. In binary it is 1101010101.
Then the lower 8 bit stored in ADRESL register (8 bit register).

That is 01010101 goes to ADRESL register (8 bit register).

and the upper 2 bit i.e 11 goes to bit0 and bit1 of ADRESL respectively
but is some example of other compiler (like mikro c , mplab ) they always use a step:
Code:

and stored this value in a variable (16 bit or 2 byte variable required).

My question is why (ADRESH << 8) is step is required
if the contain of ADRESH is 00000011; then after shifting 8 times to the left it becomes 00000000 and if we bit wise ORED with ADRESL it becomes
ADRESL -> 00110011 ( BITWISE OR operation)
-------------------------
00110011 ???( a 8 bit number but it should be a 10 bit )

Here is the example of MPLAB XC8

Can someone show me the bitwise operation?
for example

And is ADRES is a valid register??

#### MrChips

Joined Oct 2, 2009
30,802
ADRES is not a valid resister.

adval has been declared as an unsigned integer, i.e. 16 bits.

ADRESH is an 8-bit register, containing the upper bits of the ADC result.

Setting

first guarantees that the 8-bit result gets stored into a 16-bit variable.
Then
will shift the result to the left by 8 (the same as multiplying by 256).

#### Xavier Pacheco Paulino

Joined Oct 21, 2015
728
ADRESH = 00000011 is expanded into 16 bit: 00000000 00000011

ADRESH << 8 = 00000000 00000011 << 8 = 0000011 00000000

ADRESL = 00110011 is expanded into 16 bits: 0000000 00110011

0000011 00000000
0000000 00110011
---------------------------
0000011 00110011

#### AlbertHall

Joined Jun 4, 2014
12,346
ADRES is not a valid resister.
Not on the 16F877 it isn't because the two halves are in different banks.
On some PICs you can get away with 'unsigned int adval = ADRES;' but it isn't really recommended.

#### MrChips

Joined Oct 2, 2009
30,802
Not on the 16F877 it isn't because the two halves are in different banks.
On some PICs you can get away with 'unsigned int adval = ADRES;' but it isn't really recommended.
That's one of the reasons I don't do PICs.
I thought bank addressing went with the dodo bird, like segment addressing.

#### shteii01

Joined Feb 19, 2010
4,644
That's one of the reasons I don't do PICs.
I thought bank addressing went with the dodo bird, like segment addressing.
Remember, this is Indian dude and they are using ANCIENT 16F877.

#### khatus

Joined Jul 2, 2018
95
ADRESH = 00000011 is expanded into 16 bit: 00000000 00000011

ADRESH << 8 = 00000000 00000011 << 8 = 0000011 00000000

ADRESL = 00110011 is expanded into 16 bits: 0000000 00110011

0000011 00000000
0000000 00110011
---------------------------
0000011 00110011
but how can you expand an 8 bit sfr register to 16 bit ???

#### khatus

Joined Jul 2, 2018
95
I have understand your logic but
or
this also works!!! i don't know why?? can you explain it ??

#### MrChips

Joined Oct 2, 2009
30,802
You have declared adval as 16 bits.
Hence the compiler uses 16 bit registers.

#### khatus

Joined Jul 2, 2018
95
ADRESH = 00000011 is expanded into 16 bit: 00000000 00000011

I have the following confusion
1. ADRESH is a 8 bit register and i can't understand how a 8 bit SFR register is defined/expanded into a 16 bit variable?? Since they can handle only 8bit?
and also i thought the bit shifting operation is done inside those 8 bit ADRESL and ADRESH register after then they added and assigned to the 16 bit variable.

I guess the correct process would be
2. Assign contain of ADRESH (8 bit) and ADRESL to the declared 16 bit variable.
3.Bit shifting those two 16-bit variables.
4.Added or ORED them and stores inside another 16 bit variable

Last edited:

#### Xavier Pacheco Paulino

Joined Oct 21, 2015
728
I have the following confusion
1. ADRESH is a 8 bit register and i can't understand how a 8 bit SFR register is defined/expanded into a 16 bit variable?? Since they can handle only 8bit?
adval has been declared as an unsigned integer, i.e. 16 bits.
You have declared adval as 16 bits.
Hence the compiler uses 16 bit registers.

#### khatus

Joined Jul 2, 2018
95

#### AlbertHall

Joined Jun 4, 2014
12,346

From the device datasheet:

#### khatus

Joined Jul 2, 2018
95
The microcontroller i am using for testing is PIC 18f452

This one works perfectly for PIC 18f452

//***PIC 18f452 micro controller with 4Mhz crystal oscillator***//
unsigned int value; //variable to store 10 bit adc value
{
switch (channel)
{
case (0): // for channel 0
{
break;
}
case (1): // for channel 1
{
break;
}
case (2): // for channel 2
{
break;
}
}
ADCON0.GO_DONE = 1; // start conversion
while (ADCON0.GO_DONE); // wait for conversion
}
void main()
{
//INTCON = 0; // disable all interrupts

///*** A/D Port configuration cointrol bits****////
ADCON1.PCFG2 = 0; //All analog channels are declared as analog
ADCON1.PCFG3 = 0; //refernce voltage is VDD and VSS

///***Input and Output declaration bits***///
TRISA = 0b11111111; // PORTA (Pin RA0-RA7) are input
TRISB = 0b00000000; // PORTB (Pin RB0-RB7) are output
TRISC = 0b00111111; // Pins RC6, RC7 are output
//Delay_ms(2000);

///****Conversion clock select bits****///

while (1)
{
//***let's use our open source function***//
PORTB = value; // Send lower 8 bits to PORTB here RB0(LSB)
PORTC = value >> 2; // Send 2 most significant bits to RC7(MSB), RC6 pin
}
}

The ADC read function which will convert analog input given to channel 1 to 10 bit digital number with low voltage reference (Vref-) 0v and high voltage reference (Vref+) 5V. The output will be displayed using 10 LEDs.

The analog value in decimal is 563 -> binary 1000110011;

Last edited:

#### John P

Joined Oct 14, 2008
2,026

What you're seeing there is your compiler being helpful. The processor has 2 bytes that hold the A/D result, ADRESL and ADRESH. The compiler lets you use a "virtual" 16-bit variable ADRES, which has a location in memory that's the same as ADRESL, but being 2 actual bytes it also uses the next one up, ADRESH. You go and check the list file, and you'll find that every time the variable is used, the processor is looking at first a low byte, then a high byte. It makes your C code easier to follow, but the resulting hex codes are the same as if you accessed ADRESL and ADRESH separately.

#### shteii01

Joined Feb 19, 2010
4,644
Did anyone notice the jump from 16F877 to 18F452?

#### AlbertHall

Joined Jun 4, 2014
12,346
Did anyone notice the jump from 16F877 to 18F452?
It was a closely guarded secret.