News:

;) This forum is the property of Proton software developers

Main Menu

Determining the type of an array variable using the preprocessor?

Started by Yasin, Oct 25, 2024, 08:38 AM

Previous topic - Next topic

Yasin

Hello everyone. I want to reduce the code clutter used in a procedure. What I want to do is to select based on variable type using preprocessor.

For example;
$define Size 10
Dim MyArrays[Size] Byte or Word or Dword...

$if MyArrays _type Byte
....
....
$endif

$if MyArrays _type Word
....
....
$endif

$if MyArrays _type DWord
....
....
$endif


Since I don't know how to use the Preprocessor, the example I want to give above is a representation. So is there a way to know the type of the variable?

Best regards.

trastikata

Hello Yasin, this is an example of what I'd use:

$define Size 10
$define ArrayType 0     '0=byte / 1=Word / 2=DWord ...

$if ArrayType = 0
    Dim MyArrays[Size] As Byte
    '....
$elseif ArrayType = 1
    Dim MyArrays[Size] As Word
    '....
$elseif ArrayType = 2
    Dim MyArrays[Size] As Dword
    '....
$else
    'nothing
$endif

Yasin

#2
Thanks a lot @trastikata. Maybe it will be useful to someone.
The code snippet I shared below is for quickly finding out the state of any bit in an array. It works fine and produces very little code. I will add the bit loading later.

For example:
Device 18F25K22
Declare Xtal 20

'-------------------------------------------------------------------------------------------
'------------------ Quick to find out the status of any bit in the array -------------------
'-------------------------------------------------------------------------------------------
$define ArraySize 10
$define ArrayType 1                                                                         'Select Variable type 0=Byte / 1=Word / 2=Dword
$if ArrayType = 0                                                                           'If the variable type is Byte
    Dim Arrays[ArraySize] As Byte                                                           'Define variable array as Byte type
    $define Read_Array_Bit(pBitOrder) ((Arrays[pBitOrder >> 3] >> (pBitOrder // 8)) & 1)    'Find the desired bit number in the byte array and find out the status
$elseif ArrayType = 1                                                                       'If the variable type is Word
    Dim Arrays[ArraySize] As Word                                                          'Define variable array as Word type
    $define Read_Array_Bit(pBitOrder) ((Arrays[pBitOrder >> 4] >> (pBitOrder // 16)) & 1)   'Find the desired Bit number in the Word array And find out the STATUS
$elseif ArrayType = 2                                                                       'If the variable type is DWord
    Dim Arrays[ArraySize] As Dword                                                          'Define variable array as Dword type
    $define Read_Array_Bit(pBitOrder) ((Arrays[pBitOrder >> 5] >> (pBitOrder // 32)) & 1)      'Find the desired Bit number in the DWord array And find out the STATUS
$endif                                                                                      '
'-------------------------------------------------------------------------------------------
'------------------ Quick to find out the status of any bit in the array -------------------
'-------------------------------------------------------------------------------------------
Dim Bit_stat As Byte'Bit
Dim i As Byte

Arrays[0] = $5555
Arrays[1] = $FFFF
Arrays[2] = $FF00
Main:

    Bit_stat = Read_Array_Bit(i)
    DelayMS 100
    HSerOut ["Bit Status: " , Dec Bit_stat," index: ",Dec i,13,10]
    Inc i   
GoTo Main

top204

A nice piece of coding Yasin, and a good method trastikata.

I created Bit array reading and writing procedures a few months ago, and I'm sure I put it on the forum, but below is the code listing for them. They may come in useful:

'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' Write and read bits to/from a Byte array's elements, and treat it as a form of Bit array.
' Because it uses some indirect SFRs, the program is only suitable for an 18F device.
'
' This version uses masking to read and write the bit within an array's element, instead of the GetBit and LoadBit commands within the procedures.
' The replacements make the code more efficient and easier to understand and follow.
'
' Written for the Positron8 compiler by Les Johnson.
'
    Device = 18F25K20                                   ' Tell the compiler what device to compile for
    Declare Xtal = 16                                   ' Tell the compiler what frequency the device will be operating at (in MHz)
'
' Setup USART1
'
    Declare Hserial1_Baud = 9600                        ' Set the Baud rate to 9600
    Declare HRSOut1_Pin = PORTC.6                       ' Set the TX pin
'
' Create some variables for the demo
'
    Dim MyByteArray[160 / 8] As Byte Heap               ' Create a byte array large enough to holds 160 bits
    Dim MyBit As Bit                                    ' Holds the bit written and read to/from the array
    Dim bBitNum As Byte                                 ' Holds the bit number within the array

'-------------------------------------------------------------------------
' The main program starts here
' Write bits to a Byte array, then read them back and display them on a serial terminal.
'
Main:
    Seed $0345                                          ' Seed the pseudo random number generator
    Clear MyByteArray                                   ' Clear the array holding the bits
'
' Write bits to the array
'
    HRSOut "Write:"
    For bBitNum = 0 To 109                              ' Create a loop for the bit numbers
        MyBit = Random                                  ' Get a pseudo random bit
        WriteBit(MyByteArray, bBitNum, MyBit)           ' Load the array's bit with the random value
        If bBitNum // 8 = 0 Then                        ' \
            HRSOut "|"                                  ' | Place a boundary around each 8-bits displayed
        EndIf                                           ' /
        HRSOut Bin1 MyBit                               ' Transmit the bit written to a serial terminal
    Next
'
' Read the bits from the array
'
    HRSOut "\rRead :"
    For bBitNum = 0 To 109                              ' Create a loop for the bit numbers
        MyBit = ReadBit(MyByteArray, bBitNum)           ' Read a bit from the array
        If bBitNum // 8 = 0 Then                        ' \
            HRSOut "|"                                  ' | Place a boundary around each 8-bits displayed
        EndIf                                           ' /
        HRSOut Bin1 MyBit                               ' Transmit the bit read to a serial terminal
    Next
    HRSOut 13

'-------------------------------------------------------------------------
' Read a bit from a byte array
' Input     : pArrAddr holds the address of the Byte array holding the bits
'           : pBitNum holds the bit number to read (0 to 255)
' Output    : Returns the state of the bit
' Notes     : Uses masking for the bit to read
'
Proc ReadBit(ByRef pArrAddr As wRdFSR1, pBitNum As PP0), Bit
    Dim PP0H       As Byte System                       ' Create a temporary compiler system variable
    Dim bMask      As PP0H                              ' Holds the bit mask
Global Dim wRdFSR1 As FSR1L.Word                        ' Create a global 16-bit SFR of FSR1L\H so it can be used as a parameter
Global Dim PP0     As Byte System                       ' Create a global 8-bit compiler system variable so it can be used as a parameter

    pArrAddr = pArrAddr + (pBitNum / 8)                 ' Find the element of the array that holds the bit, and move up to it
    bMask = pBitNum // 8                                ' Calculate a mask for the bit's position within the byte
    WREG = INDF1                                        ' \
    WREG = WREG >> bMask                                ' | Return the bit from its position within the array's element
    Result = WREG.0                                     ' /
EndProc

'-------------------------------------------------------------------------
' Write a bit to a byte array
' Input     : pArrAddr holds the address of the byte array holding the bits
'           : pBitNum holds the bit number to write (0 to 255)
'           : pValue holds the value to write to the bit (1 or 0)
' Output    : None
' Notes     : Uses masking for the bit to write
'
Proc WriteBit(ByRef pArrAddr As wWrFSR1, pBitNum As PP0, pValue As Bit)
    Dim PP0H       As Byte System                       ' Create a temporary compiler system variable
    Dim bMask      As PP0H                              ' Holds the bit mask
Global Dim wWrFSR1 As FSR1L.Word                        ' Create a global 16-bit SFR of FSR1L\H so it can be used as a parameter
Global Dim PP0     As Byte System                       ' Create a global 8-bit compiler system variable so it can be used as a parameter

    pArrAddr = pArrAddr + (pBitNum / 8)                 ' Find the element of the array that holds the bit, and move up to it
    WREG = pBitNum // 8                                 ' \
    bMask = 1 << WREG                                   ' / Calculate a mask for the bit's position within the byte
    If pValue = 1 Then                                  ' Is the bit to be set?
        bMask = INDF1 | bMask                           ' Yes. So Or in the bit mask
    Else                                                ' Otherwise... The bit is to be cleared
        bMask = ~bMask                                  ' So... Complement the mask first
        bMask = INDF1 & bMask                           ' And in the bit mask
    EndIf
    INDF1 = bMask                                       ' Write the modified byte to the array's element
EndProc

The procedures use Byte arrays, but could easily be altered for Word arrays, Long arrays, Dword arrays, or Float arrays. Then they could be wrapped in preprocessor comparisons, or just named appropriately and called when a different array's bits need to be read from or written too.

Because they are procedures, when a bit is read or written it will not have to perform the long expression to extract a bit from an array inline, so will save code space.