News:

Let's find out together what makes a PIC Tick!

Main Menu

Compilation failure in 12F675

Started by shantanu@india, Mar 09, 2024, 08:38 AM

Previous topic - Next topic

shantanu@india

Hi,
The following program used to compile in 867 words in the year 2010 by the erstwhile Proton compiler. Now the size is exceeding 1023 bytes:

'variables   
Dim    sum            As Word
Dim    an_buff_ptr    As Byte 
Dim    analog_in      As Word 
Dim    bar_buff_0    As Byte
Dim    bar_buff_1    As Byte
Dim    bar_buff_2    As Byte
Dim    bar_buff_3    As Byte
Dim    bar_buff_4    As Byte
Dim    bar_buff_5    As Byte
Dim    bar_buff_6    As Byte
Dim    bar_buff_7    As Byte 
Dim    bit_count      As Byte 
'******************************************************************
'hardware details
Symbol  disp_clk  GPIO.2
Symbol  disp_strobe  GPIO.5
Symbol  disp_data  GPIO.4
Symbol  an_buff_size 10
'*******************************************************************
Device 12F675
Reminders =0
Warnings=0 
Xtal=4.0

Config  BODEN_ON, CPD_ON, CP_ON, MCLRE_OFF, PWRTE_ON, WDT_ON, INTRC_OSC_NOCLKOUT


'*******************************************************************
'initialization

    ANSEL=%00110011      'analog input through pin6 only
    ADCON0=%10000000    '5V reference
    CMCON=7            'comparators off
    GPIO=0              'PORTs low
    TRISIO=%001011      'before configuring direction
   
'**********************************************************************


run_mode:

   
   
    While 1 = 1
        Clrwdt       
                                'load the first 4 bytes of the bar_buff
        Clear sum
        For an_buff_ptr=1 To an_buff_size
            Clrwdt
            DelayMS 25          'loop delay between analog reads
            sum=sum+ ADIn 1      'take sample & store in proper location                                       
        Next
                             
        sum=sum/an_buff_size
       
        For bit_count=0 To 7
            If sum<(32 + 32*bit_count) Then
              SetBit bar_buff_0,bit_count
            Else
              ClearBit bar_buff_0,bit_count
            EndIf
        Next
       
        For bit_count=0 To 7
            If sum<(256 + 32*(bit_count+1)) Then
              SetBit bar_buff_1,bit_count
            Else
              ClearBit bar_buff_1,bit_count
            EndIf
        Next
       
        For bit_count=0 To 7
            If  sum<(512 + 32*(bit_count+1)) Then
              SetBit bar_buff_2,bit_count
            Else
              ClearBit bar_buff_2,bit_count
            EndIf
        Next
       
        For bit_count=0 To 7
            If  sum<(767 + 32*(bit_count+1)) Then
              SetBit bar_buff_3,bit_count
            Else
              ClearBit bar_buff_3,bit_count
            EndIf
        Next 
                                    'load the next 4 bytes of the bar buffer
        Clear sum
        For an_buff_ptr=1 To an_buff_size
            Clrwdt
            DelayMS 25          'loop delay between analog reads
            sum=sum+ ADIn 0      'take sample & store in proper location                                       
        Next
                             
        sum=sum/an_buff_size
       
        For bit_count=0 To 7
            If sum<(32 + 32*bit_count) Then
              SetBit bar_buff_4,bit_count
            Else
              ClearBit bar_buff_4,bit_count
            EndIf
        Next
       
        For bit_count=0 To 7
            If sum<(256 + 32*(bit_count+1)) Then
              SetBit bar_buff_5,bit_count
            Else
              ClearBit bar_buff_5,bit_count
            EndIf
        Next
       
        For bit_count=0 To 7
            If  sum<(512 + 32*(bit_count+1)) Then
              SetBit bar_buff_6,bit_count
            Else
              ClearBit bar_buff_6,bit_count
            EndIf
        Next
       
        For bit_count=0 To 7
            If  sum<(767 + 32*(bit_count+1)) Then
              SetBit bar_buff_7,bit_count
            Else
              ClearBit bar_buff_7,bit_count
            EndIf
        Next                 

        GoSub send_bar_data          'display the result
        Clrwdt
        DelayMS 500               
    Wend

'***********************************************************************
'bargraph driving routines
'This program refreshes the  32-segment bargraph     
       
send_bar_data:
   
        SHOut disp_data,disp_clk, LsbFirst,[bar_buff_3,bar_buff_2,bar_buff_1,bar_buff_0]       
        SHOut disp_data,disp_clk, MsbFirst,[bar_buff_4,bar_buff_5,bar_buff_6,bar_buff_7]
        High disp_strobe
        Nop
        Low disp_strobe

        Return
       
'***************************************************************************************
Regards
Shantanu

John Lawton

The clearly successful compilation belies your post title. Have you tried using the optimiser, it might help?

John

shantanu@india

Regards
Shantanu

shantanu@india

Set optimiser level 3.
Same problem.
Regards
Shantanu

AlbertoFS

#4
Hi Shanta,
If you decompose the formulas into several parts, this reduces the code.
As I have moved the formulas, please check them.
Regards
Alberto
    Device 12F675
    Declare Watchdog = On
    Declare Reminders = On
    Declare Warnings = On
    Declare Xtal = 4

'variables   
Dim    LocalWord0 As Word
Dim    sum         As Word
Dim    an_buff_ptr As Byte
Dim    analog_in   As Word
Dim    bar_buff_0 As Byte
Dim    bar_buff_1 As Byte
Dim    bar_buff_2 As Byte
Dim    bar_buff_3 As Byte
Dim    bar_buff_4 As Byte
Dim    bar_buff_5 As Byte
Dim    bar_buff_6 As Byte
Dim    bar_buff_7 As Byte
Dim    bit_count  As Byte
'******************************************************************
'hardware details
Symbol  disp_clk = GPIO.2
Symbol  disp_strobe = GPIO.5
Symbol  disp_data = GPIO.4
Symbol  an_buff_size = 10
'*******************************************************************

Config  BODEN_ON, CPD_ON, CP_ON, MCLRE_OFF, PWRTE_ON, WDT_ON, INTRC_OSC_NOCLKOUT

'*******************************************************************
'initialization

    ANSEL=%00110011      'analog input through pin6 only
    ADCON0=%10000000    '5V reference
    CMCON=7            'comparators off
    GPIO=0              'PORTs low
    TRISIO=%001011      'before configuring direction
   
'**********************************************************************
run_mode:
   
    While 1 = 1
        Clrwdt       
                                'load the first 4 bytes of the bar_buff
        Clear sum
        For an_buff_ptr=1 To an_buff_size
            Clrwdt
            DelayMS 25          'loop delay between analog reads
            sum = sum + ADIn 1      'take sample & store in proper location                                       
        Next
                             
        sum=sum/an_buff_size
       
        For bit_count=0 To 7
            LocalWord0 = 32 + (32 * bit_count)
            If sum < LocalWord0 Then
              SetBit bar_buff_0,bit_count
            Else
              ClearBit bar_buff_0,bit_count
            EndIf
        Next
       
        For bit_count=0 To 7
            LocalWord0 = 256 + (32 * (bit_count+1))
            If sum < LocalWord0 Then
              SetBit bar_buff_1,bit_count
            Else
              ClearBit bar_buff_1,bit_count
            EndIf
        Next
       
        For bit_count=0 To 7
            LocalWord0 = 512 + (32*(bit_count+1))
            If  sum < LocalWord0 Then
              SetBit bar_buff_2,bit_count
            Else
              ClearBit bar_buff_2,bit_count
            EndIf
        Next
       
        For bit_count=0 To 7
            LocalWord0 = 767 + (32*(bit_count+1))
            If  sum < LocalWord0 Then
              SetBit bar_buff_3,bit_count
            Else
              ClearBit bar_buff_3,bit_count
            EndIf
        Next
                                    'load the next 4 bytes of the bar buffer
        Clear sum
        For an_buff_ptr=1 To an_buff_size
            Clrwdt
            DelayMS 25              'loop delay between analog reads
            LocalWord0 = ADIn 0
            sum = sum + LocalWord0      'take sample & store in proper location                                       
        Next
                             
        sum=sum/an_buff_size
       
        For bit_count=0 To 7
            LocalWord0 = 32 + (32*bit_count)
            If sum < LocalWord0 Then
              SetBit bar_buff_4,bit_count
            Else
              ClearBit bar_buff_4,bit_count
            EndIf
        Next
       
        For bit_count=0 To 7
            LocalWord0 = 256 + (32*(bit_count+1))
            If sum < LocalWord0 Then
              SetBit bar_buff_5,bit_count
            Else
              ClearBit bar_buff_5,bit_count
            EndIf
        Next
       
        For bit_count=0 To 7
            LocalWord0 = 512 + (32*(bit_count+1))
            If  sum < LocalWord0 Then
              SetBit bar_buff_6,bit_count
            Else
              ClearBit bar_buff_6,bit_count
            EndIf
        Next
       
        For bit_count=0 To 7
            LocalWord0 = 767 + (32 * (bit_count+1))
            If  sum < LocalWord0 Then
              SetBit bar_buff_7,bit_count
            Else
              ClearBit bar_buff_7,bit_count
            EndIf
        Next                 

        GoSub send_bar_data          'display the result
        Clrwdt
        DelayMS 500               
    Wend

'***********************************************************************
'bargraph driving routines
'This program refreshes the  32-segment bargraph     
       
send_bar_data:
        SHOut disp_data,disp_clk, LsbFirst,[bar_buff_3,bar_buff_2,bar_buff_1,bar_buff_0]       
        SHOut disp_data,disp_clk, MsbFirst,[bar_buff_4,bar_buff_5,bar_buff_6,bar_buff_7]
        High disp_strobe
        Nop
        Low disp_strobe
        Return
'***************************************************************************************
Now the compiled code is 903 bytes with Positron 4038
73's de EA3AGV

top204

#5
Crickey 2010 ! That's 14 years ago, and the compiler has gone through a lot of changes since then. Where has the time gone?

One of the major changes I did, quite a few years ago, was to make some commands not dependent on the compiler's library subroutines, because standard 14-bit core devices are now very old, and only have a call stack size of 8, and 'so called' enhanced 14-bit core devices do not have many more, so too many compiler command library calls within subroutines or procedures that also call other subroutines or procedures will cause the device to have a hardware stack overflow if too many calls are made.

Two of the commands I changed to inline were SetBit and ClearBit, so they increase the code size when they are now used, but do not use the library subroutines, so they are safer within programs, along with other commands that must use a library subroutine call.

I am actually surprised that program fitted in the device originally, because the repetative calculations are default 16-bit, and when used within a comparison, create extra code for the temporary variables, so they take up more code space as well. Along with Else directives that adds an extra jump to the code, to jump over the block of code that is compared as false.

Also, For-Next loops always use less code memory when counting backwards to 0 with a Byte variable, because of the optimisations I made within the compiler's assembler creation, so whenever possible, always count down with the DownTo directive in a For-Next when loop using a Byte variable as its index.

As Alberto has done, and beaten me too it. :-) I have re-written the code a bit so it fits within the device, but uses some code managing tweaks to the listing, and it takes up 930 words of code space, so Alberto has beaten me on that aswell. :-)

I think it could be tweaked even further by using the repetative calculation procedures and a temporary variable, and not actually within the comparisons themselves. A bit of a mix between Alberto's code and mine.

    Device = 12F675
    Declare Xtal = 4
    Declare WatchDog = On                                           ' Tell the compiler that the watchdog is enabled, so it adds ClrWdt mnemonics to its library routines
'
' Hardware details
'
    Symbol Disp_Clk_Pin    = GPIO.2
    Symbol Disp_Strobe_Pin = GPIO.5
    Symbol Disp_Data_Pin   = GPIO.4
    Symbol cAn_Buff_Size   = 10
'
' Create variables
'
    Dim wSum         As Word
    Dim bAn_Buff_Ptr As Byte
    Dim wAnalog_In   As Word
    Dim bBit_Count   As Byte
    Dim bBar_Buff_0  As Byte
    Dim bBar_Buff_1  As Byte
    Dim bBar_Buff_2  As Byte
    Dim bBar_Buff_3  As Byte
    Dim bBar_Buff_4  As Byte
    Dim bBar_Buff_5  As Byte
    Dim bBar_Buff_6  As Byte
    Dim bBar_Buff_7  As Byte

    Config BODEN_ON, CPD_ON, CP_ON, MCLRE_OFF, PWRTE_ON, WDT_ON, INTRC_OSC_NOCLKOUT

'---------------------------------------------------------------------------------------------
' The main program starts here
'
    ANSEL = %00110011                                               ' Analog input through pin6 only
    ADCON0 = %10000000                                              ' 5V reference
    GPIO = 0                                                        ' PORTs low
    TRISIO = %00001011                                              ' Before configuring direction

Run_Mode:
    Do
        '
        ' Load the first 4 bytes of the bar_buff
        '
        wSum = 0
        For bAn_Buff_Ptr = (cAn_Buff_Size - 1) DownTo 0
            DelayMS 25                                              ' Loop delay between analog reads (also clears the watchdog timer)
            wSum = wSum + ADIn 1                                    ' Take sample & store in proper location
        Next
        wSum = wSum / cAn_Buff_Size

        For bBit_Count = 0 To 7
            ClearBit bBar_Buff_0, bBit_Count                        ' Default to a cleared bit
            If wSum < (32 + Calc()) Then                            ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_0, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next

        For bBit_Count = 0 To 7
            ClearBit bBar_Buff_1, bBit_Count                        ' Default to a cleared bit
            If wSum < (256 + CalcPlusOne()) Then                    ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_1, bBit_Count
            EndIf
        Next

        For bBit_Count = 0 To 7
            ClearBit bBar_Buff_2, bBit_Count                        ' Default to a cleared bit
            If  wSum < (512 + CalcPlusOne()) Then                   ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_2, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next

        For bBit_Count = 0 To 7
            ClearBit bBar_Buff_3, bBit_Count                        ' Default to a cleared bit
            If  wSum < (767 + CalcPlusOne()) Then                   ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_3, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next
        '
        ' Load the next 4 bytes of the bar buffer
        '
        wSum = 0
        For bAn_Buff_Ptr = (cAn_Buff_Size - 1) DownTo 0
            DelayMS 25                                              ' Loop delay between analog reads (also clears the watchdog timer)
            wSum = wSum + ADIn 0                                    ' Take sample & store in proper location
        Next
        wSum = wSum / cAn_Buff_Size

        For bBit_Count = 0 To 7
            ClearBit bBar_Buff_4, bBit_Count                        ' Default to a cleared bit
            If wSum < (32 + Calc()) Then                            ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_4, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next

        For bBit_Count = 0 To 7
            ClearBit bBar_Buff_5, bBit_Count                        ' Default to a cleared bit
            If wSum < (256 + CalcPlusOne()) Then                    ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_5, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next

        For bBit_Count = 0 To 7
            ClearBit bBar_Buff_6, bBit_Count                        ' Default to a cleared bit
            If wSum < (512 + CalcPlusOne()) Then                    ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_6, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next

        For bBit_Count = 0 To 7
            ClearBit bBar_Buff_7, bBit_Count                        ' Default to a cleared bit
            If wSum < (767 + CalcPlusOne()) Then                    ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_7, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next
        Send_Bar_Data()                                             ' Display the result
        DelayMS 500                                                 ' Delay for 500ms (also clears the watchdog timer)
    Loop

'---------------------------------------------------------------------------------------------
' Perform a repetative calculation as a procedure call
' Input     : Global variable bBit_Count
' Output    : Returns the calculation's result
' Notes     : Performs the calculation "32 * (bBit_Count + 1)" as a procedure call, to save code space
'
Proc CalcPlusOne(), Word
    Result = 32 * (bBit_Count + 1)
EndProc

'---------------------------------------------------------------------------------------------
' Perform a repetative calculation as a procedure call
' Input     : Global variable bBit_Count
' Output    : Returns the calculation's result
' Notes     : Performs the calculation "32 * bBit_Count" as a procedure call, to save code space
'
Proc Calc(), Word
    Result = 32 * bBit_Count
EndProc

'---------------------------------------------------------------------------------------------
' Bargraph driving
' Input     : bBar_Buff_0 to bBar_Buff_7
' Output    : None
' Notes     : This procedure refreshes the  32-segment bargraph
'
Proc Send_Bar_Data()
    SHOut Disp_Data_Pin, Disp_Clk_Pin, LsbFirst,[bBar_Buff_3, bBar_Buff_2, bBar_Buff_1, bBar_Buff_0]
    SHOut Disp_Data_Pin, Disp_Clk_Pin, MsbFirst,[bBar_Buff_4, bBar_Buff_5, bBar_Buff_6, bBar_Buff_7]
    PinHigh Disp_Strobe_Pin
    Nop
    PinClear Disp_Strobe_Pin
EndProc

AlbertoFS

As Les said, you can mix the 2 solutions. Also, since the procedures are very repetitive and passing value consumes bytes; then the procedures can be modified as with you can see it.
Consumption: 690 Bytes
Alberto
    Device = 12F675
    Declare Xtal = 4
    Declare Watchdog = On                                           ' Tell the compiler that the watchdog is enabled, so it adds ClrWdt mnemonics to its library routines
'
' Hardware details
'
    Symbol Disp_Clk_Pin    = GPIO.2
    Symbol Disp_Strobe_Pin = GPIO.5
    Symbol Disp_Data_Pin   = GPIO.4
    Symbol cAn_Buff_Size   = 10
'
' Create variables
'
    Dim TempWord As Word
    Dim wSum         As Word
    Dim bAn_Buff_Ptr As Byte
    Dim wAnalog_In   As Word
    Dim bBit_Count   As Byte
    Dim bBar_Buff_0  As Byte
    Dim bBar_Buff_1  As Byte
    Dim bBar_Buff_2  As Byte
    Dim bBar_Buff_3  As Byte
    Dim bBar_Buff_4  As Byte
    Dim bBar_Buff_5  As Byte
    Dim bBar_Buff_6  As Byte
    Dim bBar_Buff_7  As Byte

    Config BODEN_ON, CPD_ON, CP_ON, MCLRE_OFF, PWRTE_ON, WDT_ON, INTRC_OSC_NOCLKOUT

'---------------------------------------------------------------------------------------------
' The main program starts here
'
    ANSEL = %00110011                                               ' Analog input through pin6 only
    ADCON0 = %10000000                                              ' 5V reference
    GPIO = 0                                                        ' PORTs low
    TRISIO = %00001011                                              ' Before configuring direction
   
'**********************************************************************
Run_Mode:
    Do
        '
        ' Load the first 4 bytes of the bar_buff
        '
        wSum = 0
        For bAn_Buff_Ptr = (cAn_Buff_Size - 1) DownTo 0
            DelayMS 25                                              ' Loop delay between analog reads (also clears the watchdog timer)
            wSum = wSum + ADIn 1                                    ' Take sample & store in proper location
        Next
        wSum = wSum / cAn_Buff_Size

        For bBit_Count = 0 To 7
            ClearBit bBar_Buff_0, bBit_Count                        ' Default to a cleared bit
            Calc()
            TempWord = TempWord + 32
            If wSum < TempWord Then                                 ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_0, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next

        For bBit_Count = 0 To 7
            ClearBit bBar_Buff_1, bBit_Count                        ' Default to a cleared bit
            CalcPlusOne()
            TempWord = TempWord + 256
            If wSum < TempWord Then                                 ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_1, bBit_Count
            EndIf
        Next

        For bBit_Count = 0 To 7
            ClearBit bBar_Buff_2, bBit_Count                        ' Default to a cleared bit
            CalcPlusOne()
            TempWord = TempWord + 512
            If  wSum < TempWord Then                                ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_2, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next

        For bBit_Count = 0 To 7
            ClearBit bBar_Buff_3, bBit_Count                        ' Default to a cleared bit
            CalcPlusOne()
            TempWord = TempWord + 767
            If  wSum < TempWord Then                                ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_3, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next
        '
        ' Load the next 4 bytes of the bar buffer
        '
        wSum = 0
        For bAn_Buff_Ptr = (cAn_Buff_Size - 1) DownTo 0
            DelayMS 25                                              ' Loop delay between analog reads (also clears the watchdog timer)
            wSum = wSum + ADIn 0                                    ' Take sample & store in proper location
        Next
        wSum = wSum / cAn_Buff_Size

        For bBit_Count = 0 To 7
            ClearBit bBar_Buff_4, bBit_Count                        ' Default to a cleared bit
            Calc()
            TempWord = TempWord + 32
            If wSum < TempWord Then                                 ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_4, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next

        For bBit_Count = 0 To 7
            ClearBit bBar_Buff_5, bBit_Count                        ' Default to a cleared bit
            CalcPlusOne()
            TempWord = TempWord + 256
            If wSum < TempWord Then                                 ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_5, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next

        For bBit_Count = 0 To 7
            ClearBit bBar_Buff_6, bBit_Count                        ' Default to a cleared bit
            CalcPlusOne()
            TempWord = TempWord + 512
            If wSum < TempWord Then                                 ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_6, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next

        For bBit_Count = 0 To 7
            ClearBit bBar_Buff_7, bBit_Count                        ' Default to a cleared bit
            CalcPlusOne()
            TempWord = TempWord + 767           
            If wSum < TempWord Then                                 ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_7, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next
        Send_Bar_Data()                                             ' Display the result
        DelayMS 500                                                 ' Delay for 500ms (also clears the watchdog timer)
    Loop

'---------------------------------------------------------------------------------------------
' Perform a repetative calculation as a procedure call
' Input     : Global variable bBit_Count
' Output    : Returns the calculation's result
' Notes     : Performs the calculation "32 * (bBit_Count + 1)" as a procedure call, to save code space
'
'Proc CalcPlusOne(), Word
'    Result = 32 * (bBit_Count + 1)
'EndProc

Proc CalcPlusOne()
    TempWord = 32 * (bBit_Count + 1)
EndProc
'---------------------------------------------------------------------------------------------
' Perform a repetative calculation as a procedure call
' Input     : Global variable bBit_Count
' Output    : Returns the calculation's result
' Notes     : Performs the calculation "32 * bBit_Count" as a procedure call, to save code space
'
'Proc Calc(), Word
'    Result = 32 * bBit_Count
'EndProc

Proc Calc()
    TempWord = 32 * bBit_Count
EndProc
'---------------------------------------------------------------------------------------------
' Bargraph driving
' Input     : bBar_Buff_0 to bBar_Buff_7
' Output    : None
' Notes     : This procedure refreshes the  32-segment bargraph
'
Proc Send_Bar_Data()
    SHOut Disp_Data_Pin, Disp_Clk_Pin, LsbFirst,[bBar_Buff_3, bBar_Buff_2, bBar_Buff_1, bBar_Buff_0]
    SHOut Disp_Data_Pin, Disp_Clk_Pin, MsbFirst,[bBar_Buff_4, bBar_Buff_5, bBar_Buff_6, bBar_Buff_7]
    PinHigh Disp_Strobe_Pin
    Nop
    PinClear Disp_Strobe_Pin
EndProc
'***************************************************************************************
73's de EA3AGV

top204

#7
You beat me to it again Alberto, as I was typing, and beat my code size (nicely done). :-) Procedures come in very handy. :-)

Below is a mixture of Alberto's code mechanism with mine, and the result is down to 746 words. The compiler's syntax is so flexible (sometimes too flexible), and its assembler code created so optimised and clear to understand, it is amazing what a little bit of high-level code manipulation can do to make a program smaller, or faster, or sometimes both. But smaller code is not always the fastest code to operate.

    Device = 12F675
    Declare Xtal = 4
    Declare WatchDog = On                                           ' Tell the compiler that the watchdog is enabled, so it adds ClrWdt mnemonics to its library routines
'
' Hardware details
'
    Symbol Disp_Clk_Pin    = GPIO.2
    Symbol Disp_Strobe_Pin = GPIO.5
    Symbol Disp_Data_Pin   = GPIO.4
    Symbol cAn_Buff_Size   = 10
'
' Create variables
'
    Dim wTemp        As Word
    Dim wSum         As Word
    Dim bAn_Buff_Ptr As Byte
    Dim wAnalog_In   As Word
    Dim bBit_Count   As Byte
    Dim bBar_Buff_0  As Byte
    Dim bBar_Buff_1  As Byte
    Dim bBar_Buff_2  As Byte
    Dim bBar_Buff_3  As Byte
    Dim bBar_Buff_4  As Byte
    Dim bBar_Buff_5  As Byte
    Dim bBar_Buff_6  As Byte
    Dim bBar_Buff_7  As Byte

    Config BODEN_ON, CPD_ON, CP_ON, MCLRE_OFF, PWRTE_ON, WDT_ON, INTRC_OSC_NOCLKOUT

'---------------------------------------------------------------------------------------------
' The main program starts here
'
    ANSEL = %00110011                                               ' Analog input through pin6 only
    ADCON0 = %10000000                                              ' 5V reference
    GPIO = %00000000                                                ' Pull the bits of GPIO low
    TRISIO = %00001011                                              ' Before configuring direction

Run_Mode:
    Do
        '
        ' Load the first 4 bytes of the bar_buff
        '
        wSum = 0
        For bAn_Buff_Ptr = (cAn_Buff_Size - 1) DownTo 0
            DelayMS 25                                              ' Loop delay between analog reads (also clears the watchdog timer)
            wSum = wSum + ADIn 1                                    ' Take sample & store in proper location
        Next
        wSum = wSum / cAn_Buff_Size                                 ' Get the average into wSum

        For bBit_Count = 0 To 7
            wTemp = (32 + Calc())                                   ' Pre-Calculate for the comparison
            ClearBit bBar_Buff_0, bBit_Count                        ' Default to a cleared bit
            If wSum < wTemp Then                                    ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_0, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next

        For bBit_Count = 0 To 7
            wTemp = (256 + CalcPlusOne())                           ' Pre-Calculate for the comparison
            ClearBit bBar_Buff_1, bBit_Count                        ' Default to a cleared bit
            If wSum < wTemp Then                                    ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_1, bBit_Count
            EndIf
        Next

        For bBit_Count = 0 To 7
            wTemp = (512 + CalcPlusOne())                           ' Pre-Calculate for the comparison
            ClearBit bBar_Buff_2, bBit_Count                        ' Default to a cleared bit
            If wSum < wTemp Then                                    ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_2, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next

        For bBit_Count = 0 To 7
            wTemp = (767 + CalcPlusOne())                           ' Pre-Calculate for the comparison
            ClearBit bBar_Buff_3, bBit_Count                        ' Default to a cleared bit
            If wSum < wTemp Then                                    ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_3, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next
        '
        ' Load the next 4 bytes of the bar buffer
        '
        wSum = 0
        For bAn_Buff_Ptr = (cAn_Buff_Size - 1) DownTo 0
            DelayMS 25                                              ' Loop delay between analog reads (also clears the watchdog timer)
            wSum = wSum + ADIn 0                                    ' Take sample & store in proper location
        Next
        wSum = wSum / cAn_Buff_Size                                 ' Get the average into wSum

        For bBit_Count = 0 To 7
            wTemp = (32 + Calc())                                   ' Pre-Calculate for the comparison
            ClearBit bBar_Buff_4, bBit_Count                        ' Default to a cleared bit
            If wSum < wTemp Then                                    ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_4, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next

        For bBit_Count = 0 To 7
            wTemp = (256 + CalcPlusOne())                           ' Pre-Calculate for the comparison
            ClearBit bBar_Buff_5, bBit_Count                        ' Default to a cleared bit
            If wSum < wTemp Then                                    ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_5, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next

        For bBit_Count = 0 To 7
            wTemp = (512 + CalcPlusOne())                           ' Pre-Calculate for the comparison
            ClearBit bBar_Buff_6, bBit_Count                        ' Default to a cleared bit
            If wSum < wTemp Then                                    ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_6, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next

        For bBit_Count = 0 To 7
            wTemp = (767 + CalcPlusOne())                           ' Pre-Calculate for the comparison
            ClearBit bBar_Buff_7, bBit_Count                        ' Default to a cleared bit
            If wSum < wTemp Then                                    ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff_7, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next
        Send_Bar_Data()                                             ' Display the result
        DelayMS 500                                                 ' Delay for 500ms (also clears the watchdog timer)
    Loop

'---------------------------------------------------------------------------------------------
' Perform a repetative calculation as a procedure call
' Input     : Global variable bBit_Count
' Output    : Returns the calculation's result
' Notes     : Performs the calculation "32 * (bBit_Count + 1)" as a procedure call, to save code space
'
Proc CalcPlusOne(), Word
    Result = 32 * (bBit_Count + 1)
EndProc

'---------------------------------------------------------------------------------------------
' Perform a repetative calculation as a procedure call
' Input     : Global variable bBit_Count
' Output    : Returns the calculation's result
' Notes     : Performs the calculation "32 * bBit_Count" as a procedure call, to save code space
'
Proc Calc(), Word
    Result = 32 * bBit_Count
EndProc

'---------------------------------------------------------------------------------------------
' Bargraph driving
' Input     : bBar_Buff_0 to bBar_Buff_7
' Output    : None
' Notes     : This procedure refreshes the  32-segment bargraph
'
Proc Send_Bar_Data()
    SHOut Disp_Data_Pin, Disp_Clk_Pin, LsbFirst,[bBar_Buff_3, bBar_Buff_2, bBar_Buff_1, bBar_Buff_0]
    SHOut Disp_Data_Pin, Disp_Clk_Pin, MsbFirst,[bBar_Buff_4, bBar_Buff_5, bBar_Buff_6, bBar_Buff_7]
    PinHigh Disp_Strobe_Pin
    Nop
    PinClear Disp_Strobe_Pin
EndProc

top204

#8
Down to 634 words used using some tweaks. However, not tested... I'm sure it could be made to use less words if the, newly created, "bBar_Buff" array is used for the bit loops. i.e. Bits loop within an array element index loop:

    Device = 12F675
    Declare Xtal = 4
    Declare WatchDog = On                                           ' Tell the compiler that the watchdog is enabled, so it adds ClrWdt mnemonics to its library routines
'
' Hardware details
'
    Symbol Disp_Clk_Pin    = GPIO.2
    Symbol Disp_Strobe_Pin = GPIO.5
    Symbol Disp_Data_Pin   = GPIO.4
    Symbol cAn_Buff_Size   = 10
'
' Create variables
'
    Dim bBar_Buff[8] As Byte
    Dim wTemp        As Word
    Dim wSum         As Word
    Dim bAn_Buff_Ptr As Byte
    Dim wAnalog_In   As Word
    Dim bBit_Count   As Byte

    Config BODEN_ON, CPD_ON, CP_ON, MCLRE_OFF, PWRTE_ON, WDT_ON, INTRC_OSC_NOCLKOUT

'---------------------------------------------------------------------------------------------
' The main program starts here
'
    ANSEL = %00110011                                               ' Analog input through pin6 only
    ADCON0 = %10000000                                              ' 5V reference
    GPIO = %00000000                                                ' Pull the bits of GPIO low
    TRISIO = %00001011                                              ' Before configuring direction

Run_Mode:
    Do
        '
        ' Load the first 4 bytes of the bBar_Buff
        '
        wSum = ADC_Get(1)                                           ' Get the averaged ADC values into wSum

        For bBit_Count = 0 To 7                                     ' Create a  loop for the LSB bits
            wTemp = Calc()                                          ' \ Pre-Calculate for the comparison
            wTemp = wTemp + 32                                      ' /
            ClearBit bBar_Buff#0, bBit_Count                        ' Default to a cleared bit
            If wSum < wTemp Then                                    ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff#0, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next

        For bBit_Count = 0 To 7                                     ' Create a  loop for the LSB bits
            wTemp = CalcPlusOne()                                   ' \ Pre-Calculate for the comparison
            wTemp = wTemp + 256                                     ' /
            ClearBit bBar_Buff#1, bBit_Count                        ' Default to a cleared bit
            If wSum < wTemp Then                                    ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff#1, bBit_Count
            EndIf
        Next

        For bBit_Count = 0 To 7                                     ' Create a  loop for the LSB bits
            wTemp = CalcPlusOne()                                   ' \ Pre-Calculate for the comparison
            wTemp = wTemp + 512                                     ' /
            ClearBit bBar_Buff#2, bBit_Count                        ' Default to a cleared bit
            If wSum < wTemp Then                                    ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff#2, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next

        For bBit_Count = 0 To 7                                     ' Create a  loop for the LSB bits
            wTemp = CalcPlusOne()                                   ' \ Pre-Calculate for the comparison
            wTemp = wTemp + 767                                     ' /
            ClearBit bBar_Buff#3, bBit_Count                        ' Default to a cleared bit
            If wSum < wTemp Then                                    ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff#3, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next
        '
        ' Load the next 4 bytes of the bBar_Buff
        '
        wSum = ADC_Get(0)                                           ' Get the averaged ADC values into wSum

        For bBit_Count = 7 DownTo 0                                 ' Create a reversed loop for the MSB bits
            wTemp = Calc()                                          ' \ Pre-Calculate for the comparison
            wTemp = wTemp + 32                                      ' /
            ClearBit bBar_Buff#4, bBit_Count                        ' Default to a cleared bit
            If wSum < wTemp Then                                    ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff#4, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next

        For bBit_Count = 7 DownTo 0                                 ' Create a reversed loop for the MSB bits
            wTemp = CalcPlusOne()                                   ' \ Pre-Calculate for the comparison
            wTemp = wTemp + 256                                     ' /
            ClearBit bBar_Buff#5, bBit_Count                        ' Default to a cleared bit
            If wSum < wTemp Then                                    ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff#5, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next

        For bBit_Count = 7 DownTo 0                                 ' Create a reversed loop for the MSB bits
            wTemp = CalcPlusOne()                                   ' \ Pre-Calculate for the comparison
            wTemp = wTemp + 512                                     ' /
            ClearBit bBar_Buff#6, bBit_Count                        ' Default to a cleared bit
            If wSum < wTemp Then                                    ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff#6, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next

        For bBit_Count = 7 DownTo 0                                 ' Create a reversed loop for the MSB bits
            wTemp = CalcPlusOne()                                   ' \ Pre-Calculate for the comparison
            wTemp = wTemp + 767                                     ' /
            ClearBit bBar_Buff#7, bBit_Count                        ' Default to a cleared bit
            If wSum < wTemp Then                                    ' Is the calculation's result less than the contents of wSum?
                SetBit bBar_Buff#7, bBit_Count                      ' Yes, so set the bit
            EndIf
        Next
        Send_Bar_Data()                                             ' Display the result
        DelayMS 500                                                 ' Delay for 500ms (also clears the watchdog timer)
    Loop

'---------------------------------------------------------------------------------------------
' Perform a repetative calculation as a procedure call
' Input     : Global variable bBit_Count
' Output    : Returns the calculation's result. Also held in global variable "wTemp"
' Notes     : Performs the calculation "32 * (bBit_Count + 1)" as a procedure call, to save code space
'
Proc CalcPlusOne(), wTemp
    Result = bBit_Count + 1
    Result = Result * 32
EndProc

'---------------------------------------------------------------------------------------------
' Perform a repetative calculation as a procedure call
' Input     : Global variable bBit_Count
' Output    : Returns the calculation's result. Also held in global variable "wTemp"
' Notes     : Performs the calculation "32 * bBit_Count" as a procedure call, to save code space
'
Proc Calc(), wTemp
    Result = 32 * bBit_Count
EndProc

'---------------------------------------------------------------------------------------------
' Read the ADC multiple times and create an average value
' Input     : pChan holds the ADC channel to read
' Output    : Returns the averaged ADC value. Also held in the global variable "wSum"
' Notes     : None
'
Proc ADC_Get(pChan As Byte), wSum
    Dim bTemp As Byte

    Result = 0
    For bAn_Buff_Ptr = (cAn_Buff_Size - 1) DownTo 0
        DelayMS 25                                                  ' Loop delay between analog reads (also clears the watchdog timer)
        bTemp = ADIn pChan                                          ' Read the ADC
        Result = Result + bTemp                                     ' Take sample & store in proper location
    Next
    Result = Result / cAn_Buff_Size                                 ' Get the average into wSum
EndProc

'---------------------------------------------------------------------------------------------
' Bargraph driving
' Input     : bBar_Buff#0 to bBar_Buff#7
' Output    : None
' Notes     : This procedure refreshes the  32-segment bargraph
'           : Uses LsbFirst only, because the bits are reversed in the appropriate loops building the data to send
'
Proc Send_Bar_Data()
    SHOut Disp_Data_Pin, Disp_Clk_Pin, LsbFirst,[bBar_Buff#3, bBar_Buff#2, bBar_Buff#1, bBar_Buff#0,_
                                                 bBar_Buff#4, bBar_Buff#5, bBar_Buff#6, bBar_Buff#7]
    'SHOut Disp_Data_Pin, Disp_Clk_Pin, MsbFirst,[bBar_Buff#4, bBar_Buff#5, bBar_Buff#6, bBar_Buff#7]
    PinHigh Disp_Strobe_Pin
    Nop
    PinClear Disp_Strobe_Pin
EndProc


shantanu@india

Nice to be among old friends once again. Thanks Les, thanks Alberto!!!
This is really great support and should nudge me away from the idea of a bigger PIC.
12F675/683 are my old warhorses whom I plan to reintroduce in some applications.
Thanks once again.
Regards
Shantanu

John Lawton

I have a fondness for these as I have been using them for a long time but there are far more capable devices now available, at least in the UK, such as the PIC16F15213 or PIC16F15214 which have more hardware peripherals and features and they are half the price from Farnell of the older parts.

What's not to like?

John

top204

I have a fondness of 28-pin devices, because they are small enough to handle, but also have enough pins for most applications and more RAM, peripherals, and flash memory. And, they just plug into one of my Amicus18 boards, so I can use them for prototyping without having to build a circuit etc...

keytapper

I think that 12F1840 would realize more comfortable programming and it would remain pin compatible with the mentioned MCU.
Ignorance comes with a cost