Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Need P16F877 ADC Advice

Status
Not open for further replies.

Bizzare

Newbie level 4
Joined
Mar 15, 2011
Messages
6
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,335
Hi guys, first off im really new to PIC programming only just started learning the basics using MPLAB and following the tutorials on **broken link removed** very helpful!
The aim is to read in an analogue voltage to be converted to digital, which if is 3.2v or below will output a '1' and if above 3.6v will output a '0'.
I tried to read the PIC datasheet and am confused by a few things including the part around using interupts, acquisition time and resolution/conversion.
If anyone could give a sort of step by step process I need to go through to achieve my goal that would be very appreciated.
 

I haven't coded in ASM on PIC's before, but the general procedure is:
1. Set up A/D Converter control bits (ADCON0, per the tutorials you provided)
2. Set up clocking ratio for correct settling time
3. Initiate ADC sample
4. Wait for sample to become available
5. Read value from register
6. Make if statement to compare ADC value to the value that represents 3.6V and/or 3.2V. Start simple with a single if that compares the ADC value to the mid-point voltage value (if 0-5V range, and 10 bit resolution 0-1023, then 3.4V would be 696). Adding hysteresis in code requires you to store the previous state, so you can use a pair of logic statements to select your output state, depending on if you've passed your toggling threshold (3.2V or 3.6V)
7. Once you know the high-low condition, set the output pin accordingly.

In general with anything coding, start with some simple code, run it, see what it does and how it works. If incorrect, debug it, try again. Once you get that part working, add some more code, run again, debug.... repeat.
 
Thanks for the advice enjunear i'm following the steps, but I'm not sure what to do at step 6. Does anyone know a good website that explains how to do math functions in ASM?
So far the 10 bit value is stored in the ADRESH and ADRESL registers with right justified, I need to transfer this value to another register to then convert it into a voltage value.
Any advice or sample code would be appreciated. Thanks in advance o/
 

You shouldn't need to convert it to a numerical voltage value; keep the values in the 0-1023/0-65535, etc range. You can determine the value that corresponds to any voltage by knowing the min/max correlations of the ADC range.

If 0V = 0 (in the ADC register), and +5V = 1023 (assuming 10 bit resolution).
Now you can figure out any voltage in between by doing linear interpolation.

5V ...... 3.4V <--desired voltage
----- = -----
1023 .... X
(ignore dots.... posting removes the spaces, so the equation looks squished)

Solve for X.
(3.4*1023)/5 = X = 695.64 --> use an integer value, so 3.4V corresponds to 696 in the ADC register.

Now that you can convert from volts to a number in the register, you can simply use greater than/less than logic to compare the ADC value to your desired threshold (696). Once you compare the levels, fire off your output bit accordingly.
 
Last edited:
Thanks for reply enjunear, this got me thinking. I decided to left justify the 10 bit value and store it as a variable using only the 8 highest bits and subtract that from a fixed value, then btfss status,z.
Having some trouble doing the code for this, so anyone know the commands for pulling a variable result and subtracting it from a fixed value?
 

One way to test it would be to do a subtraction, then compare the result to the two original values.

A = 500, B = 440
A - B = R (result)
A - B = 60 = R
if (R < A) and (R < B), then A is greater than B (output something)
if (R > A) and (R > B), then B is greater than A (output something different)

This could work, assuming that the resulting negative number is stored properly (Two's Compliment).
If A = 500, B = 512, then A-B = -12
-12 stored in a 10-bit representation looks like 1111110100. This will be read by the PIC as 1012, since it doesn't "understand" negative numbers... it just manipulates the bits.

This works all the way up to A=1021, B = 1022.
A-B = -1, which is 1111111111 = "1024"... which is greater than A and B, so the logic still works.

Might be worth trying out to see how it plays. If you have a debug mode (or access to a serial port to dump data to a terminal), then you could watch the values on-the-fly.
 
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top