View previous topic :: View next topic |
Author |
Message |
gtx15
Joined: 19 May 2018 Posts: 27
|
Differential A/D |
Posted: Sat Jul 13, 2019 6:21 pm |
|
|
Using the command set_adc_channel(chan, [differential])
gives me a compile error 66 Previous identifier must be a pointer.
Target is 18f87k22.
Any Ideas? Version 5.076 |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Jul 13, 2019 6:44 pm |
|
|
The 18F87K22.h file gives the syntax:
Code: | void set_adc_channel(int8 pos_channel, int8 neg_channel); |
What does "[differential]" mean ? It's supposed to be an int8.
I made the test program below and it compiled OK with vs. 5.085.
Test program:
Code: | #include <18F87K22.h>
#fuses NOWDT,PUT,BROWNOUT
#use delay(internal=4M)
#use rs232(baud=9600, UART1, ERRORS)
//=================================
void main()
{
int8 chan_pos, chan_neg;
set_adc_channel(chan_pos, chan_neg);
while(TRUE);
} |
|
|
![](templates/subSilver/images/spacer.gif) |
gtx15
Joined: 19 May 2018 Posts: 27
|
|
Posted: Sun Jul 14, 2019 5:03 am |
|
|
Your right, Differential is the 8 bit number for the analog input to the negative input of the differential opamp leading to the a/d. The manual shows brackets around this number, I will try your code. Thank you! |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19375
|
|
Posted: Sun Jul 14, 2019 7:06 am |
|
|
This would normally be used with fixed (constant) values, rather than
using variables.
So (for example):
void set_adc_channel(1,2);
Would give the ADC reading the voltage difference between AN1 and
AN2.
Remember both channels need to be enabled.
The second value sets the CHSN bits, the first the CHS bits.
I've not used this on this chip, but on PIC24's supporting this, the compiler
does correctly load the sign bit into the result, so you have to use a
signed variable to hold this. |
|
![](templates/subSilver/images/spacer.gif) |
gtx15
Joined: 19 May 2018 Posts: 27
|
|
Posted: Sun Jul 14, 2019 8:05 am |
|
|
Using this code: set_adc_channel (1, 6) ;
Does not correctly set the chs bits.
Also this is from the Manual. set_adc_channel (chan [,neg])) |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9176 Location: Greensville,Ontario
|
|
Posted: Sun Jul 14, 2019 8:59 am |
|
|
You need to post your code, at least a small, compilable version...it'll really help figure out what's going on.
Also, you are aware that the 'negative' input of the ADC inputs really cannot be a NEGATIVE voltage.
Jay |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19375
|
|
Posted: Sun Jul 14, 2019 10:58 am |
|
|
When the differential ADC is used an extra bit is set in the peripheral
indicating the sign of the result.
However though the result can be negative (when the negative input is
above the positive input), the two voltages have both to be positive of
ground as Jay says.
As Jay says you need to post an example program. We need to test this
with your compiler version. The latter is vital, since features like this are
often largely untested and so may well not work correctly on all compiler
versions. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19375
|
|
Posted: Mon Jul 15, 2019 2:48 am |
|
|
I just tested with your compiler version, and (remarked inline):
Code: |
.................... set_adc_channel(1,6);
00080: MOVLW 04
00082: MOVWF 01
00084: MOVF ADCON0,W
//correct CHS=bits 2 to 5. AN1 needs 00001xx into
//this register.
00086: ANDLW 83
00088: IORWF 01,W
0008A: MOVWF ADCON0
0008C: MOVLW 07
0008E: MOVWF 01
00090: MOVF ADCON1,W
00092: ANDLW F8
00094: IORWF 01,W
00096: MOVWF ADCON1
//Again correct. AN6 needs 111 into bits 0 to 2 of
//ADCON1. The number needed is one greater than expected, since
//these bits have 000 selecting Vss
|
So your compiler _is_ correctly setting up for differential operation.
The chip returns the sign bit in the top four bits of the result. So this
is automatically read, so long as you right justify. If you left justify it is
in the low four bits which then means you would have to fiddle.
So you need:
Code: |
#include <18F87K22.h>
#device ADC=12
#fuses NOWDT,PUT,BROWNOUT
#use delay(internal=4M)
#use rs232(baud=9600, UART1, ERRORS)
//=================================
void main()
{
signed int16 val;
setup_adc(ADC_TAD_MUL_4 | ADC_CLOCK_DIV_4);
//setup to give 4uSec Tad - min=1.4, max 25
//Tacq=4uSec (2.45uSec required min).
setup_adc_ports(sAN1 | sAN6, VSS_2V048);
//Run with Vss to internal 2.048v, AN1 and AN6
set_adc_channel(1,6);
//AN1 as +ve, AN6 as -ve
while(TRUE)
{
val=read_adc();
printf("%ld\n\r", val);
delay_ms(100);
}
}
|
To print the result as a signed value.
Be aware that the -ve channel can only be AN0 to AN6. |
|
![](templates/subSilver/images/spacer.gif) |
|