The adc (readad10) gives nonsense reading on a 16f1789.
Is it because it is a 12-bit converter?
The ASM subroutine for the ADC conversion is also amazingly long.
Should this be the case?
Should I try to set the ADCON registers manually or should the GCBasic defaults be good enough?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The PIC16F1788/89 ADC defaults to differential mode, meaning a pair of adc channels are used and the result is the difference between the two channels.
If one of the channels is left floating the result will be erroneous. For single-ended ADC reads you must either ground one of the channels where that channel becomes VREF-, or do some bit fiddling. The PIC datasheet explains this.
Have a look at the thread linked above. It should help.
Please let us know how you make out.
Last edit: William Roth 2015-04-09
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Just another small point the datasheet say the output is actually 13 bit as either signed integer or 2's compliment. I have not had any difficulties due to this as yet my values go from 0 to 4095. My code just has a readad10 in it yet the ASM looks like this.
ReadAD10 is a function. Much of ASM code is select cases so that all adc channels and configurations are supported.
I have a 16F1788 and when I make an ASM from a very simple program with ReadAD10 it has 18 select cases. But mine has comments in it, so I'm guessing you stripped those out of your posted ASM?
The "length" of the ASM, particularly the ADC Function will be significantly determined by the chip and its features.
Using READ1D10 with the 16F1788 takes up about 210 words of program memory. With your chip it is closer to 300. This could likely be reduced quite a bit by changing how A-D.h. works. That would be a major task, and backward compatibility is also a concern.
However GCB is flexible enough that you could write your own ADC routine for your specific chip/ application and probably reduce the memory usage by 75 percent. But with a chip that has 32K flash memory is 300 words a real issue ?
For more understanding on how ADC works with GCB, take a look at the A-D.h file in the \include\lowlevel folder.
You never did say what version of GCB you are using?
Last edit: William Roth 2015-04-11
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The adc (readad10) gives nonsense reading on a 16f1789.
Is it because it is a 12-bit converter?
The ASM subroutine for the ADC conversion is also amazingly long.
Should this be the case?
Should I try to set the ADCON registers manually or should the GCBasic defaults be good enough?
What version of GCB please?
See https://sourceforge.net/p/gcbasic/discussion/596084/thread/7169f5b8/#95e4
I think this is the same issue.
Hi David.
The PIC16F1788/89 ADC defaults to differential mode, meaning a pair of adc channels are used and the result is the difference between the two channels.
If one of the channels is left floating the result will be erroneous. For single-ended ADC reads you must either ground one of the channels where that channel becomes VREF-, or do some bit fiddling. The PIC datasheet explains this.
Have a look at the thread linked above. It should help.
Please let us know how you make out.
Last edit: William Roth 2015-04-09
Yes that worked. I also found that I had to set the voltage references as well so the following lines were needed
set chsn0 on
set chsn1 on
set chsn2 on
set chsn3 on
set adnref off 'neg ref set to Vss
adpref=0 'pos ref set to Vdd
Any idea why the assembled code for the ADC handling is so long
Post the source and your asm as a ZIP please. Then, I can have a looksy. :-)
Just another small point the datasheet say the output is actually 13 bit as either signed integer or 2's compliment. I have not had any difficulties due to this as yet my values go from 0 to 4095. My code just has a readad10 in it yet the ASM looks like this.
~~~~~~
FN_READAD10
banksel ADCON1
bsf ADCON1,ADFM
SysSelect1Case1
banksel ADREADPORT
movf ADREADPORT,F
btfss STATUS, Z
goto SysSelect1Case2
banksel ANSELA
bsf ANSELA,0
goto SysSelectEnd1
SysSelect1Case2
decf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case3
banksel ANSELA
bsf ANSELA,1
goto SysSelectEnd1
SysSelect1Case3
movlw 2
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case4
banksel ANSELA
bsf ANSELA,2
goto SysSelectEnd1
SysSelect1Case4
movlw 3
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case5
banksel ANSELA
bsf ANSELA,3
goto SysSelectEnd1
SysSelect1Case5
movlw 4
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case6
banksel ANSELA
bsf ANSELA,5
goto SysSelectEnd1
SysSelect1Case6
movlw 12
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case7
banksel ANSELB
bsf ANSELB,0
goto SysSelectEnd1
SysSelect1Case7
movlw 10
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case8
banksel ANSELB
bsf ANSELB,1
goto SysSelectEnd1
SysSelect1Case8
movlw 8
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case9
banksel ANSELB
bsf ANSELB,2
goto SysSelectEnd1
SysSelect1Case9
movlw 9
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case10
banksel ANSELB
bsf ANSELB,3
goto SysSelectEnd1
SysSelect1Case10
movlw 11
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case11
banksel ANSELB
bsf ANSELB,4
goto SysSelectEnd1
SysSelect1Case11
movlw 13
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case12
banksel ANSELB
bsf ANSELB,5
goto SysSelectEnd1
SysSelect1Case12
movlw 14
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case13
banksel ANSELC
bsf ANSELC,2
goto SysSelectEnd1
SysSelect1Case13
movlw 15
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case14
banksel ANSELC
bsf ANSELC,3
goto SysSelectEnd1
SysSelect1Case14
movlw 16
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case15
banksel ANSELC
bsf ANSELC,4
goto SysSelectEnd1
SysSelect1Case15
movlw 17
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case16
banksel ANSELC
bsf ANSELC,5
goto SysSelectEnd1
SysSelect1Case16
movlw 18
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case17
banksel ANSELC
bsf ANSELC,6
goto SysSelectEnd1
SysSelect1Case17
movlw 19
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case18
banksel ANSELC
bsf ANSELC,7
goto SysSelectEnd1
SysSelect1Case18
movlw 20
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case19
banksel ANSELD
bsf ANSELD,0
goto SysSelectEnd1
SysSelect1Case19
movlw 21
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case20
banksel ANSELD
bsf ANSELD,1
goto SysSelectEnd1
SysSelect1Case20
movlw 22
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case21
banksel ANSELD
bsf ANSELD,2
goto SysSelectEnd1
SysSelect1Case21
movlw 23
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case22
banksel ANSELD
bsf ANSELD,3
goto SysSelectEnd1
SysSelect1Case22
movlw 24
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case23
banksel ANSELD
bsf ANSELD,4
goto SysSelectEnd1
SysSelect1Case23
movlw 25
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case24
banksel ANSELD
bsf ANSELD,5
goto SysSelectEnd1
SysSelect1Case24
movlw 26
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case25
banksel ANSELD
bsf ANSELD,6
goto SysSelectEnd1
SysSelect1Case25
movlw 27
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case26
banksel ANSELD
bsf ANSELD,7
goto SysSelectEnd1
SysSelect1Case26
movlw 5
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case27
banksel ANSELE
bsf ANSELE,0
goto SysSelectEnd1
SysSelect1Case27
movlw 6
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case28
banksel ANSELE
bsf ANSELE,1
goto SysSelectEnd1
SysSelect1Case28
movlw 7
subwf ADREADPORT,W
btfss STATUS, Z
goto SysSelect1Case29
banksel ANSELE
bsf ANSELE,2
SysSelect1Case29
SysSelectEnd1
banksel ADCON1
bcf ADCON1,ADCS1
bsf ADCON1,ADCS0
bcf ADCON0,CHS0
bcf ADCON0,CHS1
bcf ADCON0,CHS2
bcf ADCON0,CHS3
bcf ADCON0,CHS4
banksel ADREADPORT
btfss ADREADPORT,0
goto ENDIF10
banksel ADCON0
bsf ADCON0,CHS0
ENDIF10
banksel ADREADPORT
btfss ADREADPORT,1
goto ENDIF11
banksel ADCON0
bsf ADCON0,CHS1
ENDIF11
banksel ADREADPORT
btfss ADREADPORT,2
goto ENDIF12
banksel ADCON0
bsf ADCON0,CHS2
ENDIF12
banksel ADREADPORT
btfss ADREADPORT,3
goto ENDIF13
banksel ADCON0
bsf ADCON0,CHS3
ENDIF13
banksel ADREADPORT
btfss ADREADPORT,4
goto ENDIF14
banksel ADCON0
bsf ADCON0,CHS4
ENDIF14
banksel ADCON0
bsf ADCON0,ADON
movlw 2
movwf SysWaitTemp10US
banksel STATUS
call Delay_10US
banksel ADCON0
bsf ADCON0,GO_NOT_DONE
SysWaitLoop1
btfsc ADCON0,GO_NOT_DONE
goto SysWaitLoop1
bcf ADCON0,ADON
banksel ANSELA
clrf ANSELA
clrf ANSELB
clrf ANSELC
clrf ANSELD
clrf ANSELE
banksel ADRESL
movf ADRESL,W
banksel READAD10
movwf READAD10
clrf READAD10_H
banksel ADRESH
movf ADRESH,W
banksel READAD10_H
movwf READAD10_H
banksel ADCON1
bcf ADCON1,ADFM
banksel STATUS
return
~~~~~~~
ReadAD10 is a function. Much of ASM code is select cases so that all adc channels and configurations are supported.
I have a 16F1788 and when I make an ASM from a very simple program with ReadAD10 it has 18 select cases. But mine has comments in it, so I'm guessing you stripped those out of your posted ASM?
The "length" of the ASM, particularly the ADC Function will be significantly determined by the chip and its features.
Using READ1D10 with the 16F1788 takes up about 210 words of program memory. With your chip it is closer to 300. This could likely be reduced quite a bit by changing how A-D.h. works. That would be a major task, and backward compatibility is also a concern.
However GCB is flexible enough that you could write your own ADC routine for your specific chip/ application and probably reduce the memory usage by 75 percent. But with a chip that has 32K flash memory is 300 words a real issue ?
For more understanding on how ADC works with GCB, take a look at the A-D.h file in the \include\lowlevel folder.
You never did say what version of GCB you are using?
Last edit: William Roth 2015-04-11