Analog/Digital Conversion Code Optimisation

About Analog/Digital Conversion Code Optimisation

The analog to digital converter (ADC or A/D) module support is implemented by Great Cow BASIC to provide 8-bit, 10-bit and 12-bit Single channel measurement mode and Differential Channel Measurement with support up to 34 channels. For compatibility all channels are supported.

There are two methods to optimise the code.

  1. To mimise the code, use the contstants to disable support for a specfic channels
  2. To adapt the ADC configuration by inserting specfic commands to set registers or register bits.

1. Minimise the code

The example below would disable support for ADC port 0 (AD0).

    #define USE_AD0 FALSE

The following tables show the #defines that can be used to reduce the code size - these are the defines for the standard microcontrollers. For 16f1688x and similar microcontrollers please see the second table.

Channel Optimisation Value Default Value

USE_AD0

FALSE

TRUE

USE_AD1

FALSE

TRUE

USE_AD2

FALSE

TRUE

USE_AD3

FALSE

TRUE

USE_AD4

FALSE

TRUE

USE_AD5

FALSE

TRUE

USE_AD6

FALSE

TRUE

USE_AD7

FALSE

TRUE

USE_AD8

FALSE

TRUE

USE_AD9

FALSE

TRUE

USE_AD10

FALSE

TRUE

USE_AD11

FALSE

TRUE

USE_AD12

FALSE

TRUE

USE_AD13

FALSE

TRUE

USE_AD14

FALSE

TRUE

USE_AD15

FALSE

TRUE

USE_AD16

FALSE

TRUE

USE_AD17

FALSE

TRUE

USE_AD18

FALSE

TRUE

USE_AD19

FALSE

TRUE

USE_AD20

FALSE

TRUE

USE_AD21

FALSE

TRUE

USE_AD22

FALSE

TRUE

USE_AD23

FALSE

TRUE

USE_AD24

FALSE

TRUE

USE_AD25

FALSE

TRUE

USE_AD26

FALSE

TRUE

USE_AD27

FALSE

TRUE

USE_AD28

FALSE

TRUE

USE_AD29

FALSE

TRUE

USE_AD30

FALSE

TRUE

USE_AD31

FALSE

TRUE

USE_AD32

FALSE

TRUE

USE_AD33

FALSE

TRUE

USE_AD34

FALSE

TRUE

For 16f1688x devices see the table below.

Channel Optimisation Value Default Value

USE_ADA0

FALSE

TRUE

USE_ADA1

FALSE

TRUE

USE_ADA2

FALSE

TRUE

USE_ADA3

FALSE

TRUE

USE_ADA4

FALSE

TRUE

USE_ADA5

FALSE

TRUE

USE_ADA6

FALSE

TRUE

USE_ADA7

FALSE

TRUE

USE_ADC0

FALSE

TRUE

USE_ADC1

FALSE

TRUE

USE_ADC2

FALSE

TRUE

USE_ADC3

FALSE

TRUE

USE_ADC4

FALSE

TRUE

USE_ADC5

FALSE

TRUE

USE_ADC6

FALSE

TRUE

USE_ADC7

FALSE

TRUE

USE_ADD0

FALSE

TRUE

USE_ADD1

FALSE

TRUE

USE_ADD2

FALSE

TRUE

USE_ADD3

FALSE

TRUE

USE_ADD4

FALSE

TRUE

USE_ADD5

FALSE

TRUE

USE_ADD6

FALSE

TRUE

USE_ADD7

FALSE

TRUE

USE_ADE0

FALSE

TRUE

USE_ADE1

FALSE

TRUE

USE_ADE2

FALSE

TRUE

This is a example - disables every channel except the specified channel by defining every channel except USE_AD0 as FALSE.

This will save 146 bytes of program memory.

; ----- Configuration
    #chip 16F1939

    'USART settings
    #define USART_BAUD_RATE 9600
    #define USART_TX_BLOCKING

    'Set the input pin direction
    Dir PORTA.0 In


    'Print 255 reading
    For CurrentAddress = 0 to 255

        'Take a reading and show it
        HSerPrint str(ReadAD10(AN0))

        'Wait 10 minutes before getting another reading
        Wait 10 min
    Next

    #define USE_AD0 TRUE
    #define USE_AD1 FALSE
    #define USE_AD2 FALSE
    #define USE_AD2 FALSE
    #define USE_AD3 FALSE
    #define USE_AD4 FALSE
    #define USE_AD5 FALSE
    #define USE_AD6 FALSE
    #define USE_AD7 FALSE
    #define USE_AD8 FALSE
    #define USE_AD9 FALSE
    #define USE_AD10 FALSE
    #define USE_AD11 FALSE
    #define USE_AD12 FALSE
    #define USE_AD13 FALSE
    #define USE_AD14 FALSE
    #define USE_AD15 FALSE
    #define USE_AD16 FALSE
    #define USE_AD17 FALSE
    #define USE_AD18 FALSE
    #define USE_AD19 FALSE
    #define USE_AD20 FALSE
    #define USE_AD21 FALSE
    #define USE_AD22 FALSE
    #define USE_AD23 FALSE
    #define USE_AD24 FALSE
    #define USE_AD25 FALSE
    #define USE_AD26 FALSE
    #define USE_AD27 FALSE
    #define USE_AD28 FALSE
    #define USE_AD29 FALSE
    #define USE_AD30 FALSE
    #define USE_AD31 FALSE
    #define USE_AD32 FALSE
    #define USE_AD33 FALSE
    #define USE_AD34 FALSE

For 16f18855 family of microcontrollers this is a example. This will save 149 bytes of program memory.

    '''  PIC: 16F18855
    '''  Compiler: GCB
    '''  IDE: GCB@SYN
    '''
    '''  Board: Xpress Evaluation Board
    '''  Date: 13.3.2016
    '''


        'Chip Settings.
        #chip 16f18855,32
        #Config FEXTOSC_OFF, RSTOSC_HFINT32
        #Config WRT_OFF, CPD_ON, MCLRE_ON

        '' -------------------LATA-----------------
        '' Bit#:  -7---6---5---4---3---2---1---0---
        '' LED:   ---------------|D5 |D4 |D3 |D1 |-
        ''-----------------------------------------
        ''

        #define USART_BAUD_RATE 19200
        #define USART_TX_BLOCKING

        #define LEDD2 PORTA.0
        #define LEDD3 PORTA.1
        #define LEDD4 PORTA.2
        #define LEDD5 PORTA.3
        Dir     LEDD2 OUT
        Dir     LEDD3 OUT
        Dir     LEDD4 OUT
        Dir     LEDD5 OUT

        #define SWITCH_DOWN         0
        #define SWITCH_UP           1

        #define SWITCH              PORTA.5


        'Setup an Interrupt event when porta.5 goes negative.
        IOCAN5 = 1
        On Interrupt PORTBChange  Call InterruptHandler

        do

         'Read the value from the EEPROM from register Zero in the EEPROM
          EPRead ( 0, OutValue )

          'Leave the Top Bytes alone and set the lower four bits
          PortA = ( PortA & 0XF0 ) OR ( OutValue / 16 )
          Sleep

        loop


    sub InterruptHandler

        if IOCAF5 = 1 then                         'S2 was just pressed
            IOCAN5 = 0                             'Prevent the event from reentering the InterruptHandler routine
            IOCAF5 = 0                             'We must clear the flag in software

            wait 5 ms                              'debounce by waiting and seeing if still held down
            if ( SWITCH = DOWN ) then
                'Read the ADC
                adc_value = readad ( AN4 )
                'Write the value to register Zero in the EEPROM
                EPWrite ( 0, adc_value )
            end if
            IOCAN5 = 1                              'ReEnable the InterruptHandler routine

        end if

    end sub

    #define USE_ADA0 FALSE
    #define USE_ADA1 FALSE
    #define USE_ADA2 FALSE
    #define USE_ADA3 FALSE
    #define USE_ADA4 TRUE
    #define USE_ADA5 FALSE
    #define USE_ADA6 FALSE
    #define USE_ADA7 FALSE
    #define USE_ADB0 FALSE
    #define USE_ADB1 FALSE
    #define USE_ADB2 FALSE
    #define USE_ADB3 FALSE
    #define USE_ADB4 FALSE
    #define USE_ADB5 FALSE
    #define USE_ADB6 FALSE
    #define USE_ADB7 FALSE
    #define USE_ADC0 FALSE
    #define USE_ADC1 FALSE
    #define USE_ADC2 FALSE
    #define USE_ADC3 FALSE
    #define USE_ADC4 FALSE
    #define USE_ADC5 FALSE
    #define USE_ADC6 FALSE
    #define USE_ADC7 FALSE
    #define USE_ADD0 FALSE
    #define USE_ADD1 FALSE
    #define USE_ADD2 FALSE
    #define USE_ADD3 FALSE
    #define USE_ADD4 FALSE
    #define USE_ADD5 FALSE
    #define USE_ADD6 FALSE
    #define USE_ADD7 FALSE
    #define USE_ADE0 FALSE
    #define USE_ADE1 FALSE
    #define USE_ADE2 FALSE

2. Adapt the ADC configuration

The following example will set the specific register bits. The instruction will be added to the compiled code.

    #define ADReadPreReadCommand  ADCON.2=0:ANSELA.0=1

The constant ADReadPreReadCommand can be used to adapt the ADC methods. The constant can enable registers or register bit(s) that are required to managed for a specfic solution.

In the example above the following ASM will be added to your code. This WILL be added just before the ADC is enabled and the setting of the acquisition delay.

  ;ADReadPreReadCommand
  banksel ADCON
  bcf ADCON,2
  banksel ANSELA
  bsf ANSELA,0