Reputation: 91
I'm trying to write a program that for a PIC18F252 microcontroller to use the ADC to convert 3 analogue signals (on 3 separate pins) into digital signals for use at the output of the program. The guide I've been using to help me understand the ADC has been helpful, but I'm struggling with the part where they put it all together. Here's the code:
unsigned int ADC_Read(unsigned char channel)
{
ADCON0 &= 0x11000101; //Clearing the Channel Selection Bits
ADCON0 |= channel<<3; //Setting the required Bits
__delay_ms(2); //Acquisition time to charge hold capacitor
GO_nDONE = 1; //Initializes A/D Conversion
while(GO_nDONE); //Wait for A/D Conversion to complete
return ((ADRESH<<8)+ADRESL); //Returns Result
}
Then you can call the function and assign it to a variable using this:
i = (ADC_Read(4)); //store the result of adc in “i”
My problem is that I'm struggling to understand the bitshifting part of the code. I get why and how it clears the channel selection bits, but my struggle is understanding how 'channel<<3', when channel=4 in this example, can create a binary value that can be OR'd with the ADCON0 value. Is anyone able to explain what the value of channel is after the code has run, if it starts as 4, and also what the new configuration of ADCON0 would be after the OR line?
I understand each line individually I'm just struggling to get how they piece together because this has to be done 3 times, selecting a different channel each time, and at the moment I can't tell what channel this is setting.
Upvotes: 1
Views: 1895
Reputation: 386541
The other answers provide the layout of the registers. This answer illustrates the process of changing the desired bits.
First, we clear the channel bits (and the unimplemented bit 1).
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
| a | b | c | d | e | f | g | h | Initial state
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+ (The OP incorrectly
& | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | used 0x11000101
+---+---+---+---+---+---+---+---+ instead of 0b11000101.)
+---+---+---+---+---+---+---+---+
= | a | b | 0 | 0 | 0 | f | 0 | h |
+---+---+---+---+---+---+---+---+
Next, we need to slide the channel into bits 5-3.
+---+---+---+---+---+---+---+---+
|(0)|(0)|(0)|(0)|(0)| 1 | 0 | 0 | 4 (Channel in bits 2-0)
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
<< 3 |(0)|(0)| 1 | 0 | 0 |(0)|(0)|(0)| (Channel in bits 5-3)
+---+---+---+---+---+---+---+---+
Now, we can OR it in.
+---+---+---+---+---+---+---+---+
| a | b | 0 | 0 | 0 | f | 0 | h |
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
| |(0)|(0)| 1 | 0 | 0 |(0)|(0)|(0)|
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
= | a | b | 1 | 0 | 0 | f | 0 | h |
+---+---+---+---+---+---+---+---+
I used (0)
to denote a zero bit that doesn't carry data.
Upvotes: 3
Reputation: 1457
The ADCON0 register looks like this
bit 7-6 A/D Conversion Clock Select bits (ADCON0 bits in bold)
bit 5-3 Analog Channel Select bits
bit 2 GO/DONE
bit 1 Unimplemented
bit 0 ADON
So as you can see bit 5-3 serves as the channel select. bit 5-3 are treated as a 3-bit value, so if you wanna select channel 4 which is 100 in binary you would shift the number 4(100), 3 steps to left to place it in channel select bits.
Upvotes: 1
Reputation: 8614
If you refer to the DataSheet for PIC18F252 Section 17.0
The definition of the ADCON0
is given. Here bits 3,4,5 are the channel selection bits.
The code
ADCON0 &= 0x11000101; //Clearing the Channel Selection Bits
ADCON0 |= channel<<3; //Setting the required Bits
will set the channels from 0 to 7 as per the function parameter.
Upvotes: 2