PDA

View Full Version : Reading multiple ADC channels FAST



lwindridge
- 21st April 2004, 15:13
I'm working on reading two ADC ports (RA0 and RA1) for two seperate sensor inputs.
I can read the value of one input without any problems, but when checking the second input it seems to nearly duplicate the first - even when the sensor isn't attached!

Can anyone shed any light on this? I need the sensor check to not slow down the code if possible as it is also reading rpm pulses and needs to be able to make rpm outputs matching the input but time shifting in 20uS steps (ignition retard on an engine basing retard values on air flow on RA0 and air temp on RA1).

I've attached my current code for reference.
I am using a 16F877 @ 4Mhz.

Cheers

Leigh Windridge

Calco
- 21st April 2004, 16:59
Hi,

Not quite sure about this but im guessing its something to do with your ADCON statement.
ADCON1 = %00000010 sets the a/d to LEFT justify the reult
whereas ADCON1 = %10000010 will right justify the result.
I always use right justify.
also you may need to turn the A/D on seperately with ADCON0 = %11000001.

just basic thoughts, Ive not used the ADCIN command before I usually access the registers directly.

Hope this helps


Darryl

lwindridge
- 21st April 2004, 17:08
I was wondering myself if it was the ACDIN command getting overlap between the registers hence them both coming out identical.

Do you have any code snippets I could browse through to see if I could get it working with direct access to the registers?

Leigh

Melanie
- 21st April 2004, 21:23
Here is an example reading the Registers directly... just six simple lines of code...

MyByte var Byte

ADCON1=%00000000
' Set LEFT Justification
' Enable ALL ADC's (using PIC16F87x as example)
ADCON0=%01000001
' Set Fosc/8
' Set ADC Channel 0 (RA0/AN0)
' Enable ADC Module
PauseUS 50
' 50uS Pause to allow sampling Capacitor to charge
ADCON0.1=1
' Start Conversion
While ADCON0.1=1:Wend
' Wait for conversion to complete
MyByte=ADRESH
' Read 8-bit Result

Justification is controlled by bit 7 of ADCON1. Use LEFT justification (ADCON1.7=0) for 8-bit ADC usage (byte result) and you read the result from the ADRESH register (as per the example above). Use RIGHT justification (ADCON1.7=1) for 10-bit ADC usage (word result), then ADRESH becomes the highbyte of the word, and ADRESL becomes the lowbyte... as per the example below (which also switches to RA1/AN1)...

MyWord var Word

ADCON1=%10000000
' Set LEFT Justification
' Enable ALL ADC's (using PIC16F87x as example)
ADCON0=%01001001
' Set Fosc/8
' Set ADC Channel 1 (RA1/AN1)
' Enable ADC Module
PauseUS 50
' 50uS Pause to allow sampling Capacitor to charge
ADCON0.1=1
' Start Conversion
While ADCON0.1=1:Wend
' Wait for conversion to complete
MyWord.Highbyte=ADRESH
MyWord.Lowbyte=ADRESL
' Read 16-bit Result

Braindamagingly simple (every PIC that has ADC's gives explicit step-by-step instructions in it's Datasheet - you gotta read those Datasheets!!).... now you know how simple it is, hands up anyone that can give me a valid reason to continue using ADCIN?

Melanie

lwindridge
- 21st April 2004, 22:37
You're right - once I sussed the how the code works it was very simple :)

Only problem is I couldn't figure it out from the data sheet - I guess I need more time working with PIC's to be able to think in a way that will allow me to understand it's register settings properly.

Now my next problem is going to be reading the two values, getting an RPM reading and working out the degrees per second of a crank shaft and duplicating the incoming pulse on an output pin but delayed by x uS according to a lookup table...

All good fun so expect some more odd questions to be coming out soon!!

Thanks again!

Leigh