PDA

View Full Version : ADCIN and PIC18F4331 Arghhhhh !



GrandPa
- 24th July 2007, 21:48
Hi, I'm puzzled

I had no problem with the following code until I changed PIC from 18F4620 to 18F4331. Seem's like it always read ADC channel 0

Tried many variations of the defines but basically this is what I'm using:

DEFINE ADC_BITS 10
DEFINE ADC_SAMPLEUS 50
DEFINE ADC_CLOCK 3
ADCON2.7 = 1 'Right justified A/D
ANSEL0 = %11000011 'ADC pins: AN0,AN1,AN6,AN7
ADCON0 = %00000011
ADCHS = %01000100


then I have the four subroutines called by the program:

GetDure:
adcin 1, duration
duration = (duration*2) + 70
return

GetDpth: 'Return Depth
adcin 7, DPTH
dpth = 1024-dpth
DPTH = (dpth*5)/21
RETURN

GetStrk: 'Return Stroke length
adcin 6, STRK
STRK = (STRK*20)/51 '0 to 401
STRK = STRK + 80 '80 to 480 (1 to 6 inches)
RETURN

GetSPD: 'Return speed
adcin 0, PulseLen
PulseLen = ((1026-PulseLen)*4) + 35 '35 to 4100
return


The program compile fine and worked very well before with PIC18F4620, (using different define to match PIC). Now, It looks like it always read channel 0, for all 4 subroutines. It doesn't care about the value for the channel, after the ADCIN. What I'm missing ???

J-P

GrandPa
- 25th July 2007, 04:58
Well, here is what is working:




DEFINE OSC 16
TRISB = %00000000

'----- Set ADC ---------------------------------------------
DEFINE ADC_BITS 10
DEFINE ADC_SAMPLEUS 2
ADCON1 = %00000111 'ADC on channel AN0 to AN7
ADCON2.7 = 1 'Right justified A/D

'----- Set LCD ---------------------------------------------
DEFINE LCD_LINES 4
define LCD_DREG PORTD
DEFINE LCD_RSREG PORTC
DEFINE LCD_RSBIT 0
DEFINE LCD_EREG PORTC
DEFINE LCD_EBIT 2

line_1 con $80
line_2 con $C0
line_3 con $94
line_4 con $D4

PAUSE 1000
LCDOUT $FE, 1

A0 VAR WORD
A1 VAR WORD
A2 VAR WORD
A3 VAR WORD
A4 VAR WORD

main:
ADCIN 0, A0
ADCIN 1, A1
ADCIN 2, A2
ADCIN 3, A3

lcdOUT $FE,1, LINE_1, #A0
lcdOUT $FE, LINE_2, #A1
lcdOUT $FE, LINE_3, #A2
lcdOUT $FE, LINE_4, #A3
pause 100
goto main

end




BUT !!!!!!!!! this is NOT working





DEFINE OSC 16
TRISB = %00000000

'----- Set ADC ---------------------------------------------
DEFINE ADC_BITS 10
DEFINE ADC_SAMPLEUS 2
ADCON1 = %00000111 'ADC on channel AN0 to AN7
ADCON2.7 = 1 'Right justified A/D

'----- Set LCD ---------------------------------------------
DEFINE LCD_LINES 4
define LCD_DREG PORTD
DEFINE LCD_RSREG PORTC
DEFINE LCD_RSBIT 0
DEFINE LCD_EREG PORTC
DEFINE LCD_EBIT 2

line_1 con $80
line_2 con $C0
line_3 con $94
line_4 con $D4

PAUSE 1000
LCDOUT $FE, 1

A0 VAR WORD
A1 VAR WORD
A2 VAR WORD
A3 VAR WORD
A4 VAR WORD

main:
ADCIN 0, A0
ADCIN 1, A1
ADCIN 6, A2
ADCIN 7, A3

lcdOUT $FE,1, LINE_1, #A0
lcdOUT $FE, LINE_2, #A1
lcdOUT $FE, LINE_3, #A2
lcdOUT $FE, LINE_4, #A3
pause 100
goto main

end



The only difference is that I'm using channel 1,2,6 and 6 instead of 1,2,3,4

?????????????????????

GrandPa
- 25th July 2007, 05:39
Maybe it's a bug, maybe I'm really missing something but I found a real strange way to have it work on ADC channel 5 to 8




DEFINE OSC 16
TRISB = %00000000

'----- Set ADC ---------------------------------------------
DEFINE ADC_BITS 10
DEFINE ADC_SAMPLEUS 2
'ADCON1 = %00000111 'ADC on channel AN0 to AN7
ADCON2.7 = 1 'Right justified A/D
ANSEL0 = 255
ANSEL1.0 = 1
ADCHS = %01010110 'group select bit to channel 5-6-7-8

'----- Set LCD ---------------------------------------------
DEFINE LCD_LINES 4
define LCD_DREG PORTD
DEFINE LCD_RSREG PORTC
DEFINE LCD_RSBIT 0
DEFINE LCD_EREG PORTC
DEFINE LCD_EBIT 2

line_1 con $80
line_2 con $C0
line_3 con $94
line_4 con $D4

PAUSE 1000
LCDOUT $FE, 1

A0 VAR WORD
A1 VAR WORD
A2 VAR WORD
A3 VAR WORD
A4 VAR WORD

main:
ADCIN 0, A0
ADCIN 1, A1
ADCIN 2, A2
ADCIN 3, A3

lcdOUT $FE,1, LINE_1, #A0
lcdOUT $FE, LINE_2, #A1
lcdOUT $FE, LINE_3, #A2
lcdOUT $FE, LINE_4, #A3
pause 100
goto main

end




I Said Channel 5 to 8 !
Actually what is amazing is that this is wired to channel 5 to 8 (physical pin 7 to 10) And even if I wrote ADCIN 0, this will actually read channel 5 !!!!
This is certainly linked with the ADCHS register.

But there is a faint smell of bug around here, don't you think?

J-P

Bruce
- 25th July 2007, 12:06
It's not a bug. The newer 18F4331, 4431, etc, have more registers
associated with the advanced A/D, and ADCIN doesn't address this.

Microchip moved things around on this series, so you'll need to configure
A/D registers manually.

Bruce
- 30th July 2007, 21:54
Not sure if this will help (you probably already figured this out), but this PIC is
really nice. Here's an example of reading 4 x A/D channels simultaneously on a
18F2431.


DEFINE OSC 20
DEFINE DEBUG_REG PORTC
DEFINE DEBUG_BIT 6
DEFINE DEBUG_BAUD 9600
DEFINE DEBUG_MODE 0 ' 1 = inverted, 0 = true

CH1 VAR WORD
CH2 VAR WORD
CH3 VAR WORD
CH4 VAR WORD

' Analog setup
' Single shot, multi-channel, simultaneous Mode2, Groups A+B, then C+D
ADCON0 = %00011101

' Set +/- Vref to AVdd/AVss, FIFO buffer enabled
ADCON1 = %00010000

ADCON2 = %11001111 ' Right justified, 24 Tad, Frc
ADCON3 = 0 ' Disable all triggers
ADCHS = 0 ' Channel select for AN0,1,2,3
ANSEL0 = %00001111 ' AN0,1,2,3 analog input, rest digital

Main:
ADCON0.1 = 1 ' Start the conversion
WHILE ADCON0.1=1 ' Wait for it to complete (all 4 channels)
WEND

' FIFO buffer holds all 4 channels. Reading ADRESH & ADRESL automatically
' increments the buffer pointer (on read of ADRESL) to the next channels
' storage location.
CH1.HighByte = ADRESH ' get result from AN0
CH1.LowByte = ADRESL ' Increment buffer pointer

CH2.HighByte = ADRESH ' get result from AN1
CH2.LowByte = ADRESL ' Increment buffer pointer

CH3.HighByte = ADRESH ' get result fron AN2
CH3.LowByte = ADRESL ' Increment buffer pointer

CH4.HighByte = ADRESH ' get result from AN3
CH4.LowByte = ADRESL ' clears buffer pointer

' show 4 A/D channel results
DEBUG "A/D ch 1 = ",DEC CH1,13,10
DEBUG "A/D ch 2 = ",DEC CH2,13,10
DEBUG "A/D ch 3 = ",DEC CH3,13,10
DEBUG "A/D ch 4 = ",DEC CH4,13,10

PAUSE 5000
GOTO Main

END
Man, the more I play with this one, the more I like it.

GrandPa
- 31st July 2007, 03:32
Thanks for your help.

Actually I'm using the code from post #3. (with pbp adcin). But I will certainly investigate the ADC special features of this PIC.

I've actually switched from 18F4620 to 18F4331 mainly because of the REALLY NICE QEI module. But if I've read the datasheet correctly we can't use the 4x PLL with the internal clock?

J-P

Bruce
- 31st July 2007, 11:54
we can't use the 4x PLL with the internal clock?
Yep. The 4 x PLL doesn't work with the internal oscillator.

BigWumpus
- 6th December 2010, 20:27
ADCIN doesn't work on PIC18Fxx31.

Look here:
http://www.picbasic.co.uk/forum/showthread.php?t=13644&p=96903#post96903