1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

yet another PIC12F683 ADC problem

Discussion in 'Microcontrollers' started by madderscience, Jan 10, 2008.

  1. madderscience

    madderscience New Member

    Joined:
    Jan 10, 2008
    Messages:
    2
    Likes:
    0
    Hi all-

    I'm relatively new to PIC processors, and like some previous posters I am building what is essentially a voltmeter (eventually to become part of a data acquisition system for my electric car).

    However the problem I seem to be having doesn't match what is described anywhere else I can find on this forum, so I'll post this and let you guys tell me what presumably dumb thing I am doing.

    My problem is that after finishing an ADC sample cycle, I cannot get ADRESL to read back anything other than Zero. However I am getting sane values from ADRESH. If I left justify the adc results, I get 8 bits of good data from ADRESH, but always zero from ADRESL. If I right justify the results, I get two bits of good data from ADRESH, but ADRESL still reads zero. Yes, I am using bank bits. I am transmitting my results off of the PIC via rs232 on an unused pin, so I can see what I am getting on a remote computer terminal.

    Here are the (relevant) portions of my code: (comments may be truncated)

    one-time-setup:

    InitIO BANKSEL GPIO ; select bank containing GPIO (bank 0)
    clrf GPIO ; clear contents of GPIO
    clrf CMCON0 ; CMCON0 set GP0, GP1 to analog input, GP2 to I/O and
    BANKSEL ANSEL ; select bank containing ANSEL register (bank 1)
    movlw 0x33 ; set up ADC for dedicated clock and input on AN0
    movwf ANSEL ; and write to ANSEL register.
    movlw 0x03 ; set up tristate control buffer for input on GP0 and GP1
    movwf TRISIO ; GP5,4,2 all outputs. GP3 is always a
    BANKSEL GPIO ; go back to bank 0
    return

    sample routine, called periodically:

    (ADCON0 is set to 0x0 before calling (Vdd reference, left justify, channel zero), the "Delay" routine sets up a variable duration watchdog timer wake-from-sleep based on the contents of W, and is known working)

    Sample bsf ADCON0, 0 ; turn on adc.
    movlw 0x0
    call Delay ; wait 1/8s (way longer) than acquisition tim

    bsf ADCON0, 1 ; GO!

    btfsc ADCON0, 1 ; are we really done???
    goto $-1

    ; store the result in program memory.
    movfw ADRESH
    movwf sampleH ; <<<< WORKS FINE, GETTING SANE DATA
    BANKSEL ADRESL
    movfw ADRESL
    movwf sampleL ; <<<< ALWAYS ZERO!! GRRR!!!!!!

    BANKSEL PIR1

    bcf ADCON0, 0 ; turn off adc. isr should have done this, but
    return ; and done,

    I can do without the two least significant bits, but I'd like to have them if possible.

    Thanks to all.

    Brian
     
  2. Nigel Goodwin

    Nigel Goodwin Super Moderator Most Helpful Member

    Joined:
    Nov 17, 2003
    Messages:
    39,234
    Likes:
    641
    Location:
    Derbyshire, UK
    If you read the 'sticky' at the top of this forum, it refers you to my tutorials, one of which explains simply and clearly how to use the analogue inputs.
     
  3. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,023
    Likes:
    317
    Location:
    Brisbane Australia
    ONLINE
    What bank is sampleL in?

    Mike.
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,637
    Likes:
    109
    Location:
    Michigan, USA

    I suspect Pommie has found the problem unless sampleL and sampleH are in the 'shared' 70..7Fh area.
     
    Last edited: Jan 10, 2008
  6. madderscience

    madderscience New Member

    Joined:
    Jan 10, 2008
    Messages:
    2
    Likes:
    0
    problem identified

    Thats it!

    I knew I was doing /something/ stupid. SampleL is in the low bank random acess area, so I am writing what comes out of ADRESL into a wrong and/or unimplemented register.

    Thanks to all!

    Brian
     
  7. fejesg

    fejesg New Member

    Joined:
    Nov 2, 2008
    Messages:
    19
    Likes:
    0
    Hi, Everybody!

    I read this forum and rejoiced at it - I would like to make a circuit, wich can control ny modell engine's direction and speed. Before I made a same circuit, with 16F716, but it has no internal oscillator, and DIP18, 12F683 has INTOSC? and DIP8 -> smaller.

    I can not start ADC. With Brian's routines neither.... Please help me. After message I fitted int he asm, which I wrote - PWM works, but ADC not. When I program PIC and switch on power, the GP2 output works for 1 minute, and off...

    fejesg HU

    ;************************************************************
    ; Processor: PIC12F683 at 4 MHz using intosc
    ;************************************************************
    LIST P=12F683, R=DEC
    #include "P12F683.INC"
    ;
    __config _FCMEN_OFF & _IESO_OFF & _PWRTE_OFF & _BOD_OFF & _MCLRE_OFF & _WDT_OFF & _CP_OFF & _CPD_OFF & _INTOSCIO
    ;
    CBLOCK 0x20
    Loop1, Loop2, adfelso, adalso
    ENDC
    ;
    ORG 0x00
    goto main

    InitIO
    BANKSEL GPIO ; select bank containing GPIO (bank 0)
    clrf GPIO ; clear contents of GPIO
    clrf CMCON0 ; CMCON0 set GP0, GP1 to analog input, GP2 to I/O and
    CLRF TMR2 ;
    CLRF T2CON ;
    CLRF CCPR1L ;
    movlw b'00001100' ; PWM on
    movwf CCP1CON
    BANKSEL ANSEL ; select bank containing ANSEL register (bank 1)
    movlw 0x33 ; set up ADC for dedicated clock and input on AN0
    movwf ANSEL ; and write to ANSEL register.
    movlw 0x03 ; set up tristate control buffer for input on GP0 and GP1
    movwf TRISIO ; GP5,4,2 all outputs. GP3 is always a
    BANKSEL GPIO ; go back to bank 0
    return

    delay ; ez 250-250-nél kb 0,5 sec idő, 1/8 sec-hez negyede kell, kb. 60-250
    MOVLW 60
    MOVWF Loop1
    Outer MOVLW 250
    MOVWF Loop2
    Inner NOP
    NOP
    DECFSZ Loop2,F
    GOTO Inner ; Inner loop = 5 usec.
    DECFSZ Loop1,F
    GOTO Outer
    RETURN

    ;sample routine, called periodically:
    ;(ADCON0 is set to 0x0 before calling (Vdd reference, left justify, channel zero), the "Delay" routine
    ;sets up a variable duration watchdog timer wake*from*sleep based on the contents of W, and is
    ;known working)

    Sample
    bsf ADCON0, 0 ; turn on adc.
    movlw 0x0
    call delay ; wait 1/8s (way longer) than acquisition tim
    bsf ADCON0, 1 ; GO!
    btfsc ADCON0, 1 ; are we really done???
    goto $-1
    ; store the result in program memory.
    movfw ADRESH
    movwf adfelso ; <<<< WORKS FINE, GETTING SANE DATA
    BANKSEL ADRESL
    movfw ADRESL
    BCF STATUS,RP0 ; Bank0
    movwf adalso ; <<<< ALWAYS ZERO!! GRRR!!!!!!
    BANKSEL PIR1
    bcf ADCON0, 0 ; turn off adc. isr should have done this, but
    return

    pwm_init
    ;
    bsf STATUS, RP0 ; bank1
    movlw b'11111111'
    movwf PR2 ; berakja a periódusidő értékét
    clrf INTCON ; minden megszakítást tilt
    clrf PIE1 ; minden megszakítást tilt
    bcf STATUS, RP0 ; bank0
    movlw b'00000101' ; 1:4 előosztó, T2ON=1.
    movwf T2CON
    clrf CCPR1L
    movlw b'10001100' ; PWM bekapcsolva, aktív L kitöltési felső 2 bitje 00
    movwf CCP1CON ; beírni
    movlw b'00001111' ; alapértékek: 11000111, 10000001, 00001111, 11111111
    movwf CCPR1L ; berak egy alapértéket
    ;
    return

    main

    call InitIO

    call pwm_init

    here

    nop
    nop
    nop
    call Sample

    BCF STATUS,RP0 ; Bank0

    movfw adalso
    movwf CCP1CON
    nop
    nop

    goto here

    end
     
  8. eblc1388

    eblc1388 Active Member

    Joined:
    Jan 25, 2005
    Messages:
    2,228
    Likes:
    18
    Location:
    UK
    Are you using macro?

    What is "movfw" in your code? You should use "movf XXX,w" instead.
     
  9. fejesg

    fejesg New Member

    Joined:
    Nov 2, 2008
    Messages:
    19
    Likes:
    0
    Hi, Chung (Lao?).

    In the starting of experimentation I used movf REGISTER and movwf THERE. I don't know, why not works routine???

    Inside the PDF documentation I read, that necessary delay time (TAD) 3..5 mikrosec (with 4 MHz internal clock 3..5 pcs nop-s...). If I use longer delay, it is not works too..

    Please help me; my question:
    - are my register settings good? I read in PDF that CMCON0 & TRISIO & ANSEL & ADCON0 work together...

    If You can, please send me a short WORKABLE asm program, with wich I can start my ADC; after it, I can modify program, to handle PWM.

    fejesg
     
  10. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,023
    Likes:
    317
    Location:
    Brisbane Australia
    ONLINE
    You don't appear to be setting ADCON0 (except bits 0 and 1) and so it may be reading the wrong pin and GP2 should be set to input for the PWM module to work correctly. You may also have to turn off the comparators (CMCON0=7).

    Mike.
     
  11. ericgibbs

    ericgibbs Well-Known Member Most Helpful Member

    Joined:
    Jan 4, 2007
    Messages:
    21,189
    Likes:
    644
    Location:
    Ex Yorks' Hants UK
    hi,
    I have used a Code tidy to reformat your code. [Pommie's]
    When you post code, select all the code and then click the '#' sign in the menu bar, it keeps the formatting.:) also others can read it more easily.
    I'll look thru your program.

    Code (text):
    ;************************************************* ***********  
    ; Processor: PIC12F683 at 4 MHz using intosc  
    ;************************************************* ***********  
        list    P=12F683, R=DEC
    #include "P12F683.INC"
    ;
        __config _FCMEN_OFF & _IESO_OFF & _PWRTE_OFF & _BOD_OFF & _MCLRE_OFF & _WDT_OFF & _CP_OFF & _CPD_OFF & _INTOSCIO
    ;
        cblock  0x20
    Loop1,  Loop2,  adfelso, adalso
        endc
    ;
        org 0x00
        goto    main

    InitIO
        banksel GPIO        ; select bank containing GPIO (bank 0)
        clrf    GPIO        ; clear contents of GPIO
        clrf    CMCON0      ; CMCON0 set GP0, GP1 to analog input, GP2 to I/O and
        clrf    TMR2        ;
        clrf    T2CON       ;
        clrf    CCPR1L      ;
        movlw   b'00001100' ; PWM on
        movwf   CCP1CON
        banksel ANSEL       ; select bank containing ANSEL register (bank 1)
        movlw   0x33        ; set up ADC for dedicated clock and input on AN0
        movwf   ANSEL       ; and write to ANSEL register.
        movlw   0x03        ; set up tristate control buffer for input on GP0 and GP1
        movwf   TRISIO      ; GP5,4,2 all outputs. GP3 is always a
        banksel GPIO        ; go back to bank 0
        return

    delay               ; ez 250-250-nél kb 0,5 sec ido", 1/8 sec-hez negyede kell, kb. 60-250
        movlw   60
        movwf   Loop1
    Outer   movlw   250
        movwf   Loop2
    Inner   nop
        nop
        decfsz  Loop2,F
        goto    Inner       ; Inner loop = 5 usec.
        decfsz  Loop1,F
        goto    Outer
        return

    ;sample routine, called periodically:  
    ;(ADCON0 is set to 0x0 before calling (Vdd reference, left justify, channel zero), the "Delay" routine  
    ;sets up a variable duration watchdog timer wake*from*sleep based on the contents of W, and is  
    ;known working)  

    Sample
        bsf ADCON0,0    ; turn on adc.
        movlw   0x0
        call    delay       ; wait 1/8s (way longer) than acquisition tim
        bsf ADCON0,1    ; GO!
        btfsc   ADCON0,1    ; are we really done???
        goto    $-1
    ; store the result in program memory.  
        movfw   ADRESH
        movwf   adfelso     ; <<<< WORKS FINE, GETTING SANE DATA
        banksel ADRESL
        movfw   ADRESL
        bcf STATUS,RP0  ; Bank0
        movwf   adalso      ; <<<< ALWAYS ZERO!! GRRR!!!!!!
        banksel PIR1
        bcf ADCON0,0    ; turn off adc. isr should have done this, but
        return

    pwm_init
    ;
        bsf STATUS,RP0  ; bank1
        movlw   b'11111111'
        movwf   PR2     ; berakja a periódusido" értékét
        clrf    INTCON      ; minden megszakítást tilt
        clrf    PIE1        ; minden megszakítást tilt
        bcf STATUS,RP0  ; bank0
        movlw   b'00000101' ; 1:4 elo"osztó, T2ON=1.
        movwf   T2CON
        clrf    CCPR1L
        movlw   b'10001100' ; PWM bekapcsolva, aktív L kitöltési felso" 2 bitje 00
        movwf   CCP1CON     ; beírni
        movlw   b'00001111' ; alapértékek: 11000111, 10000001, 00001111, 11111111
        movwf   CCPR1L      ; berak egy alapértéket
    ;
        return

    main

        call    InitIO

        call    pwm_init

    here

        nop
        nop
        nop
        call    Sample

        bcf STATUS,RP0  ; Bank0

        movfw   adalso
        movwf   CCP1CON
        nop
        nop

        goto    here

        end
     
     
  12. fejesg

    fejesg New Member

    Joined:
    Nov 2, 2008
    Messages:
    19
    Likes:
    0
    Hi, Mike.

    At first, I setted up CMCON0 b'00000111', how You wrote; but the program not worked... I changed settings, after I read message of Chung.

    fejesg
     
  13. fejesg

    fejesg New Member

    Joined:
    Nov 2, 2008
    Messages:
    19
    Likes:
    0
    Hi, Eric.

    Thank You the repair of my message; at the next time I shall do in this way. I wait the result of Your checking of my program.

    fejesg
     
  14. ericgibbs

    ericgibbs Well-Known Member Most Helpful Member

    Joined:
    Jan 4, 2007
    Messages:
    21,189
    Likes:
    644
    Location:
    Ex Yorks' Hants UK
    hi,
    Your original code reads the ADC OK and loads the two registers OK [adfelso, adalso], this is using my Oshonsoft simulator.
    Why do think its not loading these two registers.?
    Your program comments call the locations 'program memory' its not.

    BTW: the movfw is recognised by the assembler OK.

    I'll look at the program later today.
     
  15. fejesg

    fejesg New Member

    Joined:
    Nov 2, 2008
    Messages:
    19
    Likes:
    0
    Hi, Eric.

    I use Mplab 8.15; it is errorous, because the base setting inside are 20 MHz IntOsc (but values of osccon are right...); I can not try program with the assembler correctly.

    I made (on the last weekend) a test circuit;
    at first:I connected a LED (& a speaker, with BC301) to GP2, switched on PWM, setted up a "basement" CCPR1L value (speaker beeped!), and I wrote in program that the end of conversion value of ADRESL shall write in CCPR1L. IT NOT WORKED.

    at second:I connected 4 LED-s to GP1-GP2-GP4-GP5, conncted a potmeter (+5v-out-gnd) to GP0 (as analog input), and wrote in program, that the result of conversion (ADRESL) shall copy to GPIO, and let appear result in I/O-s, light LED-s. IT NOT WORKED.

    Huuu. I dont't know why not works AD of 12F683; when I made a test circuit with 16F716, that's ADC has worked well.

    fejesg
     
  16. eblc1388

    eblc1388 Active Member

    Joined:
    Jan 25, 2005
    Messages:
    2,228
    Likes:
    18
    Location:
    UK
    Eric thanks for pointing that out. I have never used it before and it is not one from the standard 14-bit instruction set.

    I then looked it up in Assembler Help file and yes it is defined as an "Pseudo-Instruction" which is accepted by the assembler.

    However, Microchip also stated "Use of these pseudo-instructions is not recommended for new designs. These are documented mainly for historical purposes.".
     
  17. fejesg

    fejesg New Member

    Joined:
    Nov 2, 2008
    Messages:
    19
    Likes:
    0
    So. Dear Everybody.

    Does know anybody well MPLAB 8.15? Can I use some procedures, to simulate analog input of PIC? I have no Oshorn Simulator (because it is not free software).

    fejesg
     
  18. ericgibbs

    ericgibbs Well-Known Member Most Helpful Member

    Joined:
    Jan 4, 2007
    Messages:
    21,189
    Likes:
    644
    Location:
    Ex Yorks' Hants UK
    hi,
    You can get Oshonsoft on a 30 day free trial.
     
  19. ericgibbs

    ericgibbs Well-Known Member Most Helpful Member

    Joined:
    Jan 4, 2007
    Messages:
    21,189
    Likes:
    644
    Location:
    Ex Yorks' Hants UK
    To set the MPLAB sim clock do this: Click 'debugger' on the menu bar, click 'settings' on the drop down menu, set the sim clock to 4MHz.

    Your ADC reading code works OK on the Oshonsoft sim at 4MHZ.
     
  20. fejesg

    fejesg New Member

    Joined:
    Nov 2, 2008
    Messages:
    19
    Likes:
    0
  21. fejesg

    fejesg New Member

    Joined:
    Nov 2, 2008
    Messages:
    19
    Likes:
    0
    ThanX Eric!

    I modified clock frequency! But the Output (Mplab SIM writes "ADC-W0008: No stimulus file attached to ADRESL for A/D.". How can I simulate analogue input?

    fejesg
     

Share This Page