Continue to Site

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.

  • 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.

Understanding ADC ADRESL and ADRESH values (PIC16f690)

Status
Not open for further replies.

Ozwurld

New Member
Hello all,

Firstly i am a complete newbie at all this and i'm doing my best to try to understand this awesome micros functionalities.

I am busy trying to learn how to work with ADC's. I am building a solar lantern and would to monitor the amount of voltage left in my battery when the lantern is in use so that i can turn on a green LED when the battery still has enough energy else turn on a Red LED when the battery energy is low....

My ADC code doesnt seem to be working right in the simulator someone please have a looksy at my code, i have attached the asm file...

->After a bit of exploring the MPLAB sim i managed to find [Debugger>>Stimulus>>new workbook>>Registerinjection(tab)]
The register injection tab allows me to create a .txt stimulus so what i did is:

i created a text file with one line that reads 255 in decimal, i am assuming this should count as a high i.e 5V. However when i look at the values in ADRESH and ADRESL they dont seem to make sense.

I found a formula that states:

Value of [ADRESH / ADRESL] = (Measured Value/Vref)*256 and based on this; the values in ADRESH and ADRESH dont seem valied as the formula doesnt give me a measured value of 5V which should correspond to the 255 in the text file.

>>>Please advice..., i have attached the picture of the ADESH and ADESL values that i got

ResultsFromWatch_zps4f4e6dda.png.html


Thanks.
 

Attachments

  • 16F690TEMP.ASM
    8 KB · Views: 214
Thanks nigel:

I considered this while designing the analogue input board, and made a decision to get over the problem in the hardware. The amplifiers on the inputs have attenuators feeding them, this gives the overall amplifier an adjustable gain of around minus 4, so 10V (or so) input will give 1000 output from the A2D. So by adjusting the gain of the input amplifiers, we can use an input voltage range from 0-10.23V, which (by no coincidence at all) allows us to get a 0-1023 reading from the A2D converter giving a resolution of 10mV, which is a theoretical accuracy of around 0.1% (obviously the system itself isn't this accurate, nor is the meter we'll use to calibrate it). Another advantage of this is that it calibrates the voltage reference chip as well, this probably isn't going to be exactly 2.5V, by calibrating the inputs against a known meter we take care of this as well.
[\quote]

Your wapsite was very helpful, but my problem with why my ADC value dont make sense hasnt been solved, i cant find where i am making the mistake. I just noticed that i should change to Fosc/32 for 20MHz pic.

And thus my code now looks like this:

Code:
;**********************************************************************
;   This file is a basic code template for assembly code generation   *
;   on the PIC16F690. This file contains the basic code               *
;   building blocks to build upon.                                    *  
;                                                                     *
;   Refer to the MPASM User's Guide for additional information on     *
;   features of the assembler (Document DS33014).                     *
;                                                                     *
;   Refer to the respective PIC data sheet for additional             *
;   information on the instruction set.                               *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Filename:       ADC - Battery Voltage Monitor.asm                                           *
;    Date:                                                            *
;    File Version:                                                    *
;                                                                     *
;    Author: Phindulo Owen Mulaudzi (603854)                                                          *
;    Company:                                                         *
;                                                                     * 
;                                                                     *
;**********************************************************************
;                                                                     *
;    Files Required: P16F690.INC                                      *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Notes:                                                           *
;                                                                     *
;**********************************************************************


    list        p=16f690        ; list directive to define processor
    #include    <P16F690.inc>        ; processor specific variable definitions
   
    errorlevel -203
    errorlevel -205
    errorlevel -302

    __CONFIG    _CP_OFF & _CPD_OFF & _BOR_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _FCMEN_OFF & _IESO_OFF


; '__CONFIG' directive is used to embed configuration data within .asm file.
; The labels following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.




;***** VARIABLE DEFINITIONS
w_temp        EQU    0x7D            ; variable used for context saving
status_temp    EQU    0x7E            ; variable used for context saving
pclath_temp    EQU    0x7F            ; variable used for context saving

;**********************************************************************
cblock 0x20
    d1
    d2
    RESULTHI
    RESULTLO
    CONVERSION
endc

;**********************************************************************
    ORG        0x000            ; processor reset vector
      goto        main            ; go to beginning of program


    ORG        0x004            ; interrupt vector location
    movwf        w_temp            ; save off current W register contents
    movf        STATUS,w        ; move status register into W register
    movwf        status_temp        ; save off contents of STATUS register
    movf        PCLATH,w        ; move pclath register into W register
    movwf        pclath_temp        ; save off contents of PCLATH register


; isr code can go here or be located as a call subroutine elsewhere

    movf        pclath_temp,w        ; retrieve copy of PCLATH register
    movwf        PCLATH            ; restore pre-isr PCLATH register contents   
    movf        status_temp,w        ; retrieve copy of STATUS register
    movwf        STATUS            ; restore pre-isr STATUS register contents
    swapf        w_temp,f
    swapf        w_temp,w        ; restore pre-isr W register contents
    retfie                    ; return from interrupt


main

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                        ;STARTING ADC CONVERSION PROCEDURE
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;1. Configure Port:
;• Disable pin output driver (See TRIS register)
;• Configure pin as analog
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
banksel    TRISA;
bsf        TRISC,0 ;disable output driver by making pin an input

banksel    ANSEL;
bcf        ANSEL,0 ;set RCO/AN4 as analogue input

banksel    ANSELH;
clrf    ANSELH

banksel    ADRESH
clrf    ADRESH ;init

banksel    ADRESL
clrf    ADRESL ;init

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;2. Configure the ADC module:
;• Select ADC conversion clock
;• Configure voltage reference
;• Select ADC input channel
;• Select result format
;• Turn on ADC module
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
banksel    ADCON1;
bcf        ADCON1,ADCS0;
bsf        ADCON1,ADCS1;
bcf        ADCON1,ADCS2 ;select Fosc/32 : 110

banksel    ADCON0;
bcf        ADCON0,VCFG ;use VDD pin as reference voltage

banksel    ADCON0;
bcf        ADCON0,CHS0;
bcf        ADCON0,CHS1;
bcf        ADCON0,CHS2;
bcf        ADCON0,CHS3; ;select pin AN0 : 0000

banksel    ADCON0;
bcf        ADCON0,ADFM;    Left justify A/D conversion

banksel    ADCON0
bsf        ADCON0,ADON;    Enable ADC
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;3. Configure ADC interrupt (optional):
;• Clear ADC interrupt flag 
;• Enable ADC interrupt
;• Enable peripheral interrupt
;• Enable global interrupt
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
banksel    PIR1;
bcf        PIR1,ADIF ;clear ADC interrupt flag

banksel    PIE1;
bsf        PIE1,ADIE ; enable ADC interrupt

banksel    INTCON
bsf        INTCON,PEIE; enable peripheral interrupt

banksel    INTCON;
bcf        INTCON,GIE; enable global interrupt

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;4. Wait the required acquisition time.
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
banksel    OSCCON;
bcf        OSCCON,IRCF0;
bsf        OSCCON,IRCF1;
bsf        OSCCON,IRCF2; ;set internal oscillator to 4MHz, uhmmm 1 instruction = 250us??

; Delay = 0.001 seconds = 1,000uS
movlw    0xC7;
movwf    d1;
movlw    0x01;
movwf    d2;

Delay_1us:
decfsz    d1, f;
goto    $+2;
decfsz    d2, f;
goto    Delay_1us;

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;5. Start conversion by setting the GO/DONEbit.
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
banksel    ADCON0;
bsf        ADCON0,1
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;6. Wait for ADC conversion to complete by one of the following:
;• Polling the GO/DONEbit
;• Waiting for the ADC interrupt (interrupts enabled)
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
banksel    PIR1;
btfss    PIR1, ADIF;
goto    $-1;    //wait for ADC to complete
banksel    PIR1;
bcf        PIR1, ADIF;
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;7. Read ADC Result
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
banksel ADRESL ;
movf ADRESL,W ;Read lower 8 bits
movwf RESULTLO ;Store in GPR space

banksel ADRESH ;
movf ADRESH,W ;Read upper 2 bits
movwf RESULTHI ;store in GPR space

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;8. Clear the ADC interrupt flag (required if interrupt is enabled).
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
banksel    PIR1;
bcf        PIR1, ADIF; clear ADC flag

banksel    ADCON0
bcf        ADCON0,ADON;    Disable ADC

goto $



    ORG    0x2100                ; data EEPROM location
    DE    1,2,3,4                ; define first four EEPROM locations as 1, 2, 3, and 4


    END                       ; directive 'end of program'

[\code]
 
Hey ozwurld, I'm interested to k ow more about your project, how's it going? Do you have a schematic?
Schematic not as yet, project has taken a nice form... but i decided to ditch the pic and use an arduino. I should have simulations by the time i submit my project report if your interested.
 
Schematic not as yet, project has taken a nice form... but i decided to ditch the pic and use an arduino. I should have simulations by the time i submit my project report if your interested.

Why didn't you code the PIC in C? I should have posted some code for you!! The Arduino is a good development station but you never learn the low level stuff for yourself!
 
Why didn't you code the PIC in C? I should have posted some code for you!! The Arduino is a good development station but you never learn the low level stuff for yourself!

Low level stuff is only about reading the datasheet.. why should someone learn something trivial that he does not even need to know? It is more important to learn how ADC works in general, than learn how to setup some registers in one particular uC.
 
:) i havent looked at uC as yet, the only reason i decided to go for the arduino is because im on a really tight schedule... i love asm but it can be disheartening at times.
 
:) i havent looked at uC as yet, the only reason i decided to go for the arduino is because im on a really tight schedule... i love asm but it can be disheartening at times.
The arduino environment is C++!!! That's what I don't understand...
 
There is always the option to use Atmel Studio instead of Arduino IDE.
 
Status
Not open for further replies.

Latest threads

Back
Top