Menu

10 bit ADC for 16F87X family.

Santiago
2009-01-24
2013-05-30
  • Santiago

    Santiago - 2009-01-24

    First i have to say i'm starting with gcbasic and don't know all the features.

    When working with ADC with 16f876a i see the 8 bits read and a 10 bit one, but i can't find the way to use Vref or select what channels will be analogic inputs or digital I/O.

    Then i adapted some asm routines i had to gcbasic, just to can select the configuration and fast operation in adc readings.

    Available functions and how to use are in the driver.

    This is the code if useful to someone ( an use example follow the driver):

    '________________________________________________________________________________
    '
    '           10 BIT ADC DRIVER FOR PIC16F87X FAMILY AND COMPATIBLES
    '
    '                            (optimized asm)

                          Original driver name: adc_87X.h
    '________________________________________________________________________________
    '
    '
    '    This library is free software; you can redistribute it and/or

    '    modify it under the terms of the GNU Lesser General Public

    '    License as published by the Free Software Foundation; either

    '    version 2.1 of the License, or (at your option) any later version.

    '    This library is distributed in the hope that it will be useful,

    '    but WITHOUT ANY WARRANTY; without even the implied warranty of

    '    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

    '    Lesser General Public License for more details.

    '    You should have received a copy of the GNU Lesser General Public

    '    License along with this library; if not, write to the Free Software

    '    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    '
    '________________________________________________________________________________
    '
    '                      AVAILABLE FUNCTIONS (examples):
    '________________________________________________________________________________
    '
    ' Configure ADC with fosc/32, 2 adc inputs and Vref+ at RA3:
    '
    '       adc_conf FOSC/32, A2_R1
    '
    '
    ' Configure ADC with fosc/16, 4 adc inputs, Vref+ at RA3 and Vref- at RA2:
    '
    '       adc_conf FOSC/16, A4_R2
    '
    '
    ' Configure ADC with fosc/8, 5 adc inputs, no Vref inputs:
    '
    '       adc_conf FOSC/8, A5_R0
    '
    '
    ' Open channel 1:
    '
    '       adc_open CH1
    '
    '
    ' Read channel previously opened:
    '
    '       adc_read
    '
    '
    ' Disable ADC module:
    '
    '       adc_close
    '
    '________________________________________________________________________________
    '
    '                     DEFINITIONS (available options)
    '________________________________________________________________________________
    '
    'Oscillator frecuency: used bit5=ADCON1.ADCS2, bit6=ADCON0.ADCS0, bit7=ADCON0.ADCS1
    #define FOSC/2    0x00
    #define FOSC/4    0x20
    #define FOSC/8    0x40
    #define FOSC/16   0x60
    #define FOSC/32   0x80
    #define FOSC/64   0xA0
    #define FOSC_RC   0xE0

    'ADC and Vref inputs(PCFG0-3 in ADCON1)
    #define A8_R0    0x00
    #define A7_R1    0x01
    #define A5_R0    0x02
    #define A4_R1    0x03
    #define A3_R0    0x04
    #define A2_R1    0x05
    #define A0_R0    0x06
    #define A6_R2    0x08
    #define A6_R0    0x09
    #define A5_R1    0x0a
    #define A4_R2    0x0b
    #define A3_R2    0x0c
    #define A2_R2    0x0d
    #define A1_R0    0x0e
    #define A1_R2    0x0f

    'select channel: used bits 3-5 = ADCON0.CHS0-CHS2
    #define CH0  0x00
    #define CH1  0x08
    #define CH2  0x10
    #define CH3  0x18
    #define CH4  0x20
    #define CH5  0x28
    #define CH6  0x30
    #define CH7  0x38

    '________________________________________________________________________________
    '
    '                               FUNCTIONS
    '________________________________________________________________________________

    sub adc_conf(setfosc, channels) #NR

        RLF     setfosc,W       ; We will take bit 5 from setfosc to put it in ADCON1.ADCS2
        ANDLW   0x40            ; 0x40 = 01000000 select bit 6 from setfosc (5º rotated)
        IORWF   channels,W      ; Join channel and bit 6 from setfosc (5º rotated)
        MOVWF   ADCON1          ; set config at ADCON1
        BSF     ADCON1,7        ; Right justified (10 bits)

                                ; GCBASIC will take care about BANKSELs..!!!
        MOVF    setfosc,W
        ANDLW   0xC0            ; 0xC0 = 11000000 select bits 6-7 from setfosc
        MOVWF   ADCON0          ; Set frecuency in ADCON0 (ADCS0, ADCS1)

    end sub

    sub adc_open(channel) #NR

        BCF     ADCON0,3        ; Delete previous config
        BCF     ADCON0,4
        BCF     ADCON0,5
        MOVF    channel,W
        IORWF   ADCON0,F        ; Set opened channel
        BSF     ADCON0,0        ; Enable ADC

    end Sub

    function adc_read As word

        BSF     ADCON0,2        ; Start conversion
        BTFSC   ADCON0,2        ; wait for not busy
        GOTO    $-1

        adc_read = ADRESL
        adc_read_H = ADRESH

    end function

    #define adc_close ADCON0.0 = 0

    '_____________________________________________________________________________________
    '
    ' **************************** END OF DRIVER **********************************
    '_____________________________________________________________________________________

    'USE EXAMPLE:

    '_____________________________________________________________________________________
    '_____________________________________________________________________________________

    '________________________________________________________________________________
    '
    '               Example to be used with adc-87X.h driver
    '
    '
    ' A led attached to PORTB.7 will light when Volt. level at PORTA.0 > Vdd/2
    '
    '________________________________________________________________________________
    '

    'General hardware configuration

    #chip 16F876A, 20

    #config HS_OSC, WDT_OFF, LVP_OFF, PWRTE_ON

    #include <adc-87X.h>   
    'driver must be in "iclude" dir or probide full path

    #define LED1   PORTB.7

    '________________________________________________________________________________

       
    DIR A0 IN
    DIR B7 OUT

    adc_conf FOSC/32, A1_R0

    adc_open CH0

    do while true

        if adc_read > 512 then
            set LED1 on
            goto outlabel
        end if
        set LED1 off

    outlabel:

    loop

    '________________________________________________________________________________

     
    • Santiago

      Santiago - 2009-01-24

      Sorry  there is a mistake in the driver here:
      '________________________________________________________________________________
      '
      ' 10 BIT ADC DRIVER FOR PIC16F87X FAMILY AND COMPATIBLES
      '
      ' (optimized asm)

      Original driver name: adc_87X.h ***************HERE**************
      '________________________________________________________________________________
      '

      The line must be comented:

      ' Original driver name: adc_87X.h

       
    • Santiago

      Santiago - 2009-01-24

      Very sorry again..... this is not the proper forum.... i posted the correct post is the proper forum... i hope .. :)

      Anyway i want to report something that give me errors:

      When compiling the example i had this line:

      #include <adc-87X.h>   'driver must be in "iclude" dir or probide full path

      This give me a sintax error... when it shouldn't (i think)
      This works ok:

      #include <adc-87X.h> 
      'driver must be in "iclude" dir or probide full path

      Sorry again for my confusion....

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.