A/D conversion with PIC18F67J50


+ Reply to Thread
Results 1 to 10 of 10
  1. #1
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530

    Default A/D conversion with PIC18F67J50

    I am having a heck of a time getting A/D conversion to work with the pic18f67j50. I know I am probably missing something basic from rtfm.

    In desperation, I have tried to copy some C demo code (that is working on my hardware), and translate the basic setup to picbasic pro. My hardware is the Olimex PIC_LCD3310 located here http://www.olimex.com/dev/pic-lcd3310.html

    I have the display working. Right now I just have an analog operator issue.

    Here is my setup from the include file:
    Code:
        else
            LIST
            LIST p = 18F67J50, r = dec, w = -311, w = -230, f = inhx32
            INCLUDE "P18F67J50.INC"	; MPASM  Header
            CONFIG XINST = OFF
    	CONFIG STVREN = OFF    ;added
    	CONFIG WDTEN = OFF    ;added
    	CONFIG CP0 = OFF    ;added
    	CONFIG IESO = OFF    ;added
    	CONFIG FCMEN = OFF    ;added
    	CONFIG CCP2MX = DEFAULT    ;added
    	CONFIG PLLDIV = 5
    	CONFIG WDTPS = 32768 ;was 512
            CONFIG CPUDIV = OSC1
            CONFIG FOSC = HSPLL
    	CONFIG MSSPMSK = MSK5   ;added
            NOLIST
        endif
    And here is one of my attempts at getting A/D out of it:
    Code:
    DEFINE OSC 48
    
    include "modedefs.bas"
    include "LCD_3310.pbp"
    
    TRISD = 0
    PORTD.0 = 1   'turn on g sensor
    PORTD.1 = 0   'select scale for g sensor
    PORTD.2 = 0   'select scale for g sensor
    
    
    TRISA = %00000111   'set porta.0, 1, and 2 as inputs
    TRISB = 0
    CM1CON = 7
    CM2CON = 7
    TRISC = 0
    TRISE = 0
    ADCON0 = %00000001      'turn on adc
    ADCON1 = %00000010      'fosc/32 ?? 
    'am I translating c language ADCON1=0x10 above correctly?
    
    resx var word
    x var word
    y var word
    z var word
    adval var word
    
    x=0
    y=0
    z=0
    adval = 0
    
    PORTD.0 = 1   'turn on g sensor (again)
    '*************************************************
    @bsf WDTCON,ADSHR   ;set shared address SFR with WTCON<4> - is this right?
    ADCON0 = %11111110  ' channel with a 0 is analog input, all others digital
    @bcf WDTCON,ADSHR
    ADCON1 = %10111110  'right justified, AD=20AD, A/D clock=fosc/64
    ADCON0.0 = 1        'turn on adc
    
    ADCON0.2 = 0        'channel select bit CHS0(should already be a 0)
    ADCON0.3 = 0        'Channel select bit CHS1(should already be a 0)
    
    
    start:
        Pause 500       	' Wait .5 second
    loop: 		ADCON0.1 = 1					'Start Conversion
    adval = 0                                   'clear result word
    notdone:	pause 5
    			if ADCON0.1 = 1 Then notdone	'wait for low on bit-2 of ADCON0, conversion finished
    
    			adval.highbyte = ADRESH			'move HIGH byte of result to adval
    			adval.lowbyte = ADRESL			'move LOW byte of result to adval
                
                ADCON0 = %00000000              'turn off adc
    	    	
                'Lcdout $fe, 1   				'Clear screen
            	'Lcdout "Value: ", DEC adval	'Display the decimal value  
    @ PrintStr 0,0, "Z= "                       ;display on Nokia 3310
    @ PrintVar 24,0, _adval                     ;display result on 3310
            	Pause 100       				'Wait .1 second
    
           		'Goto loop       				'Do it forever
            	End
    This is an (apparently BAD) attempt at making it look almost just like:
    Code:
    #pragma config XINST    = OFF      // Extended instruction set
            #pragma config STVREN   = OFF      // Stack overflow reset
            #pragma config PLLDIV   = 5         // (20 MHz crystal used on this board)
            #pragma config WDTEN    = OFF      // Watch Dog Timer (WDT)
            #pragma config CP0      = OFF      // Code protect
            #pragma config CPUDIV   = OSC1      // OSC1 = divide by 1 mode
            #pragma config IESO     = OFF      // Internal External (clock) Switchover
            #pragma config FCMEN    = OFF      // Fail Safe Clock Monitor
            #pragma config FOSC     = HSPLL      // Firmware must also set OSCTUNE<PLLEN> to start PLL!
            #pragma config WDTPS    = 32768
    //      #pragma config WAIT     = OFF      // Commented choices are
    //      #pragma config BW       = 16      // only available on the
    //      #pragma config MODE     = MM      // 80 pin devices in the 
    //      #pragma config EASHFT   = OFF      // family.
            #pragma config MSSPMSK  = MSK5
    //      #pragma config PMPMX    = DEFAULT
    //      #pragma config ECCPMX   = DEFAULT
            #pragma config CCP2MX   = DEFAULT
    
    ;---------------snip
    
          ////////////MMA pins configuration - Sleep mode disabled///////////////////////////////
             TRISDbits.TRISD0=0;
             PORTDbits.RD0=1;
             //GS1 =0
             TRISDbits.TRISD1=0;
             PORTDbits.RD1=0;
             //GS2=0
             TRISDbits.TRISD2=0;
             PORTDbits.RD2=0;
             
             TRISAbits.TRISA0=1;
             TRISAbits.TRISA1=1;
             TRISAbits.TRISA2=1;
             //ADC module enable
             //ADCON1=0x10111110;         //right-justified; AD=20AD;A/D clock=fOSC/64    
              ADCON0=0x01;         //Enable ADC module
             ADCON1=0x10;      
          ////////////////////////MMA measure/////////////////////
             resx=0;
             x=0;
             y=0;
             z=0;
             sym=0;
             PORTDbits.RD0=1;  //MMA SLEEP MODE disable
    //****************************************************************************
             ANCON0bits.PCFG0=0;  //AN0 - analog input
             ADCON1=0b10111110;         //right-justified; AD=20AD;A/D clock=fOSC/64    
          //   ADCON1=0x10;
             ADCON0bits.ADON=1;    //Enable ADC module, AVdref, AVss
             //set Z-axis measure
             ADCON0bits.CHS0=0;
             ADCON0bits.GO=1;            //BSF ADCON0,GO ;Start conversion
             while(ADCON0bits.GO);         //   BSC ADCON0,GO ;Is conversion done? ;   GOTO $-1 ;No, test again
             resz=ADRESL;
             z=ADRESH;
             z=(z<<8)|resz;   
             resz=z;      
             ADCON0=0x00;      //stop ADC
    //****************************************************************************
    If someone could point out what an idiot I am, that would be great!

    Thanks!

    Walter
    http://www.scalerobotics.com

  2. #2
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    I believe it's the ADCON0 = %00000000 'turn off adc

    You probably get a reading the first loop through.
    But for all loops after that, the A/D module is turned off.
    <br>
    DT

  3. #3
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530

    Default

    Thanks Darrel,

    I commented out my ADCON0 = %00000000 and put the loop back in, and confirmed my loop is looping. My result seems to be stuck at 24543, 40910 or 8142 each time I reset. Basically giving me random numbers as best I can tell. But despite the loop looping, the numbers do not change, until I remove power from the unit, then apply power again.

    Code:
    DEFINE OSC 48
    
    include "modedefs.bas"
    include "LCD_3310.pbp"
    
    TRISD = 0
    PORTD.0 = 1   'turn on g sensor
    PORTD.1 = 0   'select scale for g sensor
    PORTD.2 = 0   'select scale for g sensor
    
    
    TRISA = %00000111   'set porta.0, 1, and 2 as inputs
    TRISB = 0
    CM1CON = 7
    CM2CON = 7
    TRISC = 0
    TRISE = 0
    ADCON0 = %00000001      'turn on adc
    ADCON1 = %00000010      'fosc/32 ?? 
    'am I translating c language ADCON1=0x10 above correctly?
    
    resx var word
    x var word
    y var word
    z var word
    adval var word
    
    x=0
    y=0
    z=0
    adval = 0
    
    PORTD.0 = 1   'turn on g sensor (again)
    '*************************************************
    @ bsf WDTCON,ADSHR   ;set shared address SFR with WTCON<4> - is this right?
    ADCON0 = %11111110  ' channel with a 0 is analog input, all others digital
    @ bcf WDTCON,ADSHR
    ADCON1 = %10111110  'right justified, AD=20AD, A/D clock=fosc/64
    ADCON0.0 = 1        'turn on adc
    
    ADCON0.2 = 0        'channel select bit CHS0(should already be a 0)
    ADCON0.3 = 0        'Channel select bit CHS1(should already be a 0)
    
    
    start:
        Pause 500       ' Wait .5 second
    loop: 		ADCON0.1 = 1					'Start Conversion
    adval = 0                                   'clear result word
    notdone:	pause 5
    	if ADCON0.1 = 1 Then notdone	'wait for low on bit-2 of ADCON0, conversion finished
    
    	adval.highbyte = ADRESH			'move HIGH byte of result to adval
    	adval.lowbyte = ADRESL			'move LOW byte of result to adval
                
            'ADCON0 = %00000000              'turn off adc
    	    	
            'Lcdout $fe, 1   				'Clear screen
            'Lcdout "Value: ", DEC adval	'Display the decimal value  
                x = x +1                        'test to see if loop is working
    @ PrintStr 0,0, "Z= "                       ;display on Nokia 3310
    @ PrintVar 24,0, _adval                     ;display result on 3310
    @ PrintVar 0,1, _x                          ;show if loop is looping
            Pause 100       				'Wait .1 second
    
           	Goto loop       				'Do it forever
    End
    http://www.scalerobotics.com

  4. #4
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530

    Default

    Whoops,

    I noticed that it was going to my include file, then popping up at start: which missed all my settings to the ADCON0 etc.

    Sometimes I have to say it out loud (to everyone) to figure it out, with the help of some experts. I won't tell anyone how many days I was trying..........

    Thanks,

    Walter
    Last edited by ScaleRobotics; - 6th May 2009 at 21:04.
    http://www.scalerobotics.com

  5. #5
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898

    Default

    You conversion clock seems a bit high @48MHz operation, and your first example in C used ANCON0, not yours.... yet...

    While it's not a problem for now, one day you may need to disable some analog feature on this PIC... however, seems ANCON0 and ANCON1 are not included in PBP 2.50c, so I guess the following would be handy one day or another.
    Code:
            '
            '       Configure ADC
            '       =============
            ANCON0  VAR BYTE EXT    ' not included in PBP2.50c
            ANCON1  VAR BYTE EXT    ' not included in PBP2.50c
            
            ANCON0 = %10011110
                   '  -xx------ Not Implemented
                   '  1--1111-- AN7, & AN<4:1> = Digital
                   '  -------0- AN0 = Analog
                   
            ANCON1 = %11111111
                   '  11111111- AN<15:10> = Digital
                                         
            ADCON0 = %00000001
                   '  0-------- VCFG1, Vref- 0 = AVss (1=AN2)
                   '  -0------- VCFG2, Vref+ 0 = AVdd (1=AN3) 
                   '  --0000--- CHS<3:0>, Channel select -- 0
                   '  ------0-- Go/Done, don't care for now
                   '  -------1- ADON, Enable ADC
                      
            ADCON1 = %10000111
                   '  1-------- ADFM, Right justified result
                   '  -0------- ADCAL, Normal A/D converter operation
                   '  --000---- ACQT<2:0>, A/D Aquisition time = 0 Tad
                   '  -----111- ADCS<2:0>, A/D conversion clock = FRC
                    
            '
            '       Hardware Aliases
            '       ================
            GoDone      var ADCON0.1 ' StartConversion = 1, Conversion done = 0
            
            '
            '       Software Variables
            '       ==================
    @ADVal = ADRESL
            ADVal       VAR WORD EXT
            
    Start:
            pauseus 10  ' Acquisition time        
            GoDone = 1
            While GoDone : Wend
            LCDOUT $FE, 1, "Value: ", DEC ADVal
            PAUSE 250
            GOTO START
    EDIT: for some odd reason, ANCON0 & ANCON1 are commented in PIC18EXT.BAS, i'd sent an e-mail to Melabs, obviously they must have a reason for that.
    Last edited by mister_e; - 6th May 2009 at 22:04.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  6. #6
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530

    Default

    Thanks mister_e ! I have flipped to page 299 to 302 so many times but never noticed the "D" to "N" change. Doh!

    Do you think it is edited out because it is a shared address, only distinguished by the address share bit ADSHR in the WDTCON register?

    Currently I have to:
    @ bsf WDTCON,ADSHR 'flag address share bit
    ADCON0 = %11111000 ' channels with a 0 is analog input, all others digital
    @ bcf WDTCON,ADSHR
    (or should I say I think? I have to....)

    to set the aNcon0 register

    (Despite all my mistakes, I am now getting valid conversion results, as of post 4)
    Last edited by ScaleRobotics; - 6th May 2009 at 22:34.
    http://www.scalerobotics.com

  7. #7
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898

    Default

    Holly crap, yeah, that make sense indeed. Yet another stupidity from Microchip

    So my example will need some changes...
    Code:
            '
            '       Configure ADC
            '       =============
            ANCON0  VAR BYTE EXT    ' not included in PBP2.50c
            ANCON1  VAR BYTE EXT    ' not included in PBP2.50c
            
            WDTCON.4 = 1    ' Switch to Alternate SFR
            ANCON0 = %10011110
                   '  -xx------ Not Implemented
                   '  1--1111-- AN7, & AN<4:1> = Digital
                   '  -------0- AN0 = Analog
                   
            ANCON1 = %11111111
                   '  11111111- AN<15:10> = Digital
                                         
            WDTCON.4 = 0    ' Back to Default SFR
    or
    Code:
            '
            '       Configure ADC
            '       =============
            WDTCON.4 = 1    ' Switch to Alternate SFR
            
            ADCON1 = %10011110  ' alternate ANCON0
                   '  -xx------ Not Implemented
                   '  1--1111-- AN7, & AN<4:1> = Digital
                   '  -------0- AN0 = Analog
                   
            ADCON0 = %11111111  ' alternate ANCON1 
                   '  11111111- AN<15:10> = Digital
                                         
            WDTCON.4 = 0    ' Back to Default SFR
    By far, i prefer the first, easier to read

    However, yours work.. keep it like that. If it's not broken, don't fix it!
    Last edited by mister_e; - 6th May 2009 at 23:00.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  8. #8
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898

    Default

    Side note... there's no real need to redefine ANCON1, ANCON0 as i did if you use ANCON1_ALT, ANCON0_ALT within your code. Those two are defined in PIC18EXT.BAS.

    Having _ALT written at the right of the register name, may remember you to set/clear WDTCON.4 bit? Maybe
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  9. #9
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530

    Default

    Quote Originally Posted by mister_e View Post
    Side note... there's no real need to redefine ANCON1, ANCON0 as i did if you use ANCON1_ALT, ANCON0_ALT within your code. Those two are defined in PIC18EXT.BAS.

    Having _ALT written at the right of the register name, may remember you to set/clear WDTCON.4 bit? Maybe
    Sweet! I did not see that either. May be time for glasses. And a lot cleaner than the way I was doing it, and I like the way you wrote the registry bits in the code. That would have kept me from having to divert my attention to and from tfm a lot!

    Thanks for all the help.

    Walter
    http://www.scalerobotics.com

  10. #10
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898

    Default

    To me, comments are really important. So, on the long run... coding like that
    Code:
            ADCON0 = %00000001
                   '  0-------- VCFG1, Vref- 0 = AVss (1=AN2)
                   '  -0------- VCFG2, Vref+ 0 = AVdd (1=AN3) 
                   '  --0000--- CHS<3:0>, Channel select -- 0
                   '  ------0-- Go/Done, don't care for now
                   '  -------1- ADON, Enable ADC
    May indeed avoid to open the datasheet all the time, one thing is sure, it's easier to modify/understand later.
    Last edited by mister_e; - 8th May 2009 at 02:03.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

Similar Threads

  1. Fast / low resolution A/D conversion
    By AndrewC in forum General
    Replies: 7
    Last Post: - 7th April 2009, 12:18
  2. A/D conversion problem in 18F2520, 2523, 2550 etc.
    By selimkara in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 10th March 2008, 16:26
  3. A/D conversion problem on 18F4431
    By ttease in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 10th April 2007, 23:03
  4. A/D converter fails?
    By egberttheone in forum mel PIC BASIC Pro
    Replies: 14
    Last Post: - 13th February 2006, 18:57
  5. Strange A/D conversion...
    By Christos_K in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 5th June 2005, 01:35

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts