[SOLVED] Pic18f45k20 adc, wrong output

Status
Not open for further replies.

P.Copper

Member level 5
Joined
Mar 18, 2013
Messages
82
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,807
Hi Y'all

I'm have coded a simple code for PIC18f45k20 10 bit ADC with reference voltage of 3.24V , now i'm inputing 1.97V to my analog channel AN6. because pic18f45k20 is an 8 bit micro i've put the 8 bits in portD and the LSB in portC. but i'm getting the wrong digital value for 1.97V input.
here's my code
Code:
  list p=pic18f45k20  #include  "p18f45k20.inc"


; CONFIG1H
  CONFIG  FOSC = INTIO67        ; Oscillator Selection bits (Internal oscillator block, port function on RA6 and RA7)
  CONFIG  FCMEN = OFF           ; Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
  CONFIG  IESO = OFF            ; Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)


; CONFIG2L
  CONFIG  PWRT = OFF            ; Power-up Timer Enable bit (PWRT disabled)
  CONFIG  BOREN = SBORDIS       ; Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
  CONFIG  BORV = 18             ; Brown Out Reset Voltage bits (VBOR set to 1.8 V nominal)


; CONFIG2H
  CONFIG  WDTEN = OFF           ; Watchdog Timer Enable bit (WDT is controlled by SWDTEN bit of the WDTCON register)
  CONFIG  WDTPS = 32768         ; Watchdog Timer Postscale Select bits (1:32768)


; CONFIG3H
  CONFIG  CCP2MX = PORTC        ; CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
  CONFIG  PBADEN = ON           ; PORTB A/D Enable bit (PORTB<4:0> pins are configured as analog input channels on Reset)
  CONFIG  LPT1OSC = OFF         ; Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)
  CONFIG  HFOFST = ON           ; HFINTOSC Fast Start-up (HFINTOSC starts clocking the CPU without waiting for the oscillator to stablize.)
  CONFIG  MCLRE = ON            ; MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)


; CONFIG4L
  CONFIG  STVREN = ON           ; Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
  CONFIG  LVP = OFF             ; Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
  CONFIG  XINST = OFF           ; Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))


; CONFIG5L
  CONFIG  CP0 = OFF             ; Code Protection Block 0 (Block 0 (000800-001FFFh) not code-protected)
  CONFIG  CP1 = OFF             ; Code Protection Block 1 (Block 1 (002000-003FFFh) not code-protected)
  CONFIG  CP2 = OFF             ; Code Protection Block 2 (Block 2 (004000-005FFFh) not code-protected)
  CONFIG  CP3 = OFF             ; Code Protection Block 3 (Block 3 (006000-007FFFh) not code-protected)


; CONFIG5H
  CONFIG  CPB = OFF             ; Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
  CONFIG  CPD = OFF             ; Data EEPROM Code Protection bit (Data EEPROM not code-protected)


; CONFIG6L
  CONFIG  WRT0 = OFF            ; Write Protection Block 0 (Block 0 (000800-001FFFh) not write-protected)
  CONFIG  WRT1 = OFF            ; Write Protection Block 1 (Block 1 (002000-003FFFh) not write-protected)
  CONFIG  WRT2 = OFF            ; Write Protection Block 2 (Block 2 (004000-005FFFh) not write-protected)
  CONFIG  WRT3 = OFF            ; Write Protection Block 3 (Block 3 (006000-007FFFh) not write-protected)


; CONFIG6H
  CONFIG  WRTC = OFF            ; Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
  CONFIG  WRTB = OFF            ; Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected)
  CONFIG  WRTD = OFF            ; Data EEPROM Write Protection bit (Data EEPROM not write-protected)


; CONFIG7L
  CONFIG  EBTR0 = OFF           ; Table Read Protection Block 0 (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
  CONFIG  EBTR1 = OFF           ; Table Read Protection Block 1 (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
  CONFIG  EBTR2 = OFF           ; Table Read Protection Block 2 (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
  CONFIG  EBTR3 = OFF           ; Table Read Protection Block 3 (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)


; CONFIG7H
  CONFIG  EBTRB = OFF           ; Boot Block Table Read Protection bit (Boot Block (000000-0007FFh) not protected from table reads executed in other blocks)


;----------------reset vector---------------------------------------------------
   org       0h
   goto      setup
;-----------------Variables-----------------------------------------------------
  cblock
      value
  endc


;--------------------Setup------------------------------------------------------
setup
       ;initialise portC
         clrf    PORTC         ;used for storing 2 LSB(RC7 and RC6) of the ADC
         clrf    TRISC
         clrf    LATC
         clrf    ANSEL          ;set PORTD as a digital  output
       ;initialise portE
         clrf    PORTE
         bsf     TRISE,1       ;Set RE1(AN6 pin) to input
         bsf     ANSEL,1       ;Set RE1 as analog input
       ;initialise portD
         clrf    PORTD
         clrf    TRISD
         clrf    LATD
         clrf    ANSEL          ;set PORTD as a digital  output
       ;initialise portA
         clrf    PORTA
         bsf     TRISA,0       ;Set RA0 to input
         bsf     ANSEL,0       ;set RA0 to analog


         bcf      TRISA,7        ;Set RA7 to output
         bcf      ANSEL,7        ;Set RA7 to digital
       ;initialise adc
         clrf    ADRESL         ;stores 2 LSB porte
         clrf    ADRESH         ;stores 8 MSB portd


         movlw   b'00011001'    ;chose adc chanel AN6(pin9), turn ADC on
         movwf   ADCON0


         movlw   b'10101100'    ;right justify, Frc,internal oscillator
         movwf   ADCON2         ; & 12 TAD ACQ time


         movlw   b'00000000'    ;ADC internal ref = Vdd,Vss
         movwf   ADCON1
         
;-------------------------main--------------------------------------------------
main
         call adc_on
         
         goto  main
;------------------------adc conversion-----------------------------------------
adc_on
        
        bcf     PORTA,0
        bsf     ADCON0,GO       ;start conversion
start
        btfsc   ADCON0,1        ;polling to test for conversion done
        bra     start
        bsf     PORTA,0         ;switch closed to sample


        movff ADRESH, PORTD  ;ADC results are transferred to portD (bit 9 to 2)
        movff ADRESL, PORTC  ;ADC results are transferred to portC (bit 1 to 0)


;-----------------------------end-----------------------------------------------
  end
 

Hi,

Couple of errors in your code as presented.

The first line, the #include should be on a new line.

Cblock must have a start location eg 0x00

Your ADC specifes Right Justification but your are trying to display it as if it were Left Just.

You have used Config to select internal osciilator, but the first lines of your 'main' code should be to use the OSCCON instruction to set the actual frequency you want; it defaults to 1mhz.

Look at your set up code, for PortC you clear ANSEL , ok, for PortE your bsf ANSEL ,1 , ok (but it should be bit 6 not 1), then for PortD you again Clear Ansel so turning off your PortE instruction !

Set all the bits for your ANSEL ANSEL1 instructions in one go , then set all the digital port directions.

its best to always terminate your code

loop goto loop
end

Though you are only doing 1 adc read with that code, if you do more, ensure you have a small delay between successive reads.

Have run the above points though a simulator at 4mhz and it seems to work though see what happens when you apply these changes.

Pic below shows your corrected code displaying the adc value as I think you intended.
See if you can get the same result, if not shout for help and post your revised code.
 

Attachments

  • 000071.jpg
    11.8 KB · Views: 85
  • 000072.jpg
    36.1 KB · Views: 83
Last edited:
thanks wp100, I will update the code and let you know of the outcomes
 

thanks wp100, I will update the code and let you know of the outcomes

Hi,

It looks like much of you code was from the set examples in the datasheet.

One easy way to setting up the files is to enter the data in binary form then load it into the appropriate system register, here for the ANSELs but you can use it for all other registers, like OSCCON etc


; set Analogue Ports

movlw b'01000000' ;ANS 7 - 0, bit 6 = RE1 to Analogue , rest Digital
movwf ANSEL
movlw b'00000000' ;ANS 12 - 8, all Digital
movwf ANSELH
 

Everything worked out perfectly thanks again...
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…