News:

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

Main Menu

Is it possible to create a 160 bit variable

Started by RGV250, Apr 18, 2023, 07:39 AM

Previous topic - Next topic

RGV250

Hi,
I very much doubt this is possible but I am prepared to be amazed as Les normally pulls the rabbit out of the hat.
I would like to use GetBit but it does not appear to work with arrays, I could move the array variables to a word in a loop but wondered if it was possible to place variables sequencially in RAM so like in a Dword you can read bits 0-31 I would like to daisy chain several so I can use GetBit 0 to 159 in a simple loop.

Bob

AlbertoFS

Hi Bob,
Some years ago I wrote some code with arrays of bits.
See here in LostOldCodes: https://protoncompiler.com/index.php/topic,1595.0.html

Alberto
73's de EA3AGV

top204

#2
Using procedures and indirect access for the RAM, accessing individual bits within an array's element is pretty straightforward, and is very similar to writing and reading a graphic LCD that uses bytes for its display instead of individual pixels. The demo program below shows two procedures. One to write bits to a Byte array and one to read bits from a Byte array. Because it is using SFRs (Special Function Registers), it is only suitable for 18F devices, but could be changed for enhanced 14-bit core devices as well:

'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' Write and read bits in an array's elements.
' Because the program listing uses the indirect SFRs, the program is only suitable for an 18F device.
'
' 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 pseudo random 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 so it is easier to view
        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 so it is easier to view
        EndIf                                       ' /
        HRSOut Bin1 MyBit                           ' Transmit the bit read to a serial terminal
    Next
    HRSOut 13
    
'-------------------------------------------------------------------------
' Read a single bit from an array
' Input     : pArrAddr (FSR1L\H) holds the address of the byte array containing the bits
'           : pBitNum holds the bit number to read (0 to 255)
' Output    : Returns the state of the bit
' Notes     : None
'
Proc ReadBit(ByRef pArrAddr As wRdFSR1, pBitNum As Byte), Bit
Global Dim wRdFSR1 As FSR1L.Word                        ' Create a global 16-bit SFR of FSR1L\H. It can also be used as a parameter   
      
    pArrAddr = pArrAddr + (pBitNum / 8)                 ' Find the element of the array that holds the bit, and move up to it
    Result = GetBit(INDF1, (pBitNum // 8))              ' Read the bit from its position within the array's element
EndProc

'-------------------------------------------------------------------------
' Write a single bit to an array
' Input     : pArrAddr (FSR1L\H) holds the address of the byte array to write the bit to
'           : 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     : None
'
Proc WriteBit(ByRef pArrAddr As wWrFSR1, pBitNum As Byte, pValue As Bit)
    Dim bTemp      As PRODL                             ' Holds the element's contents because LoadBit also uses indirect access
Global Dim wWrFSR1 As FSR1L.Word                        ' Create a global 16-bit SFR of FSR1L\H. It can also be used as a parameter
      
    pArrAddr = pArrAddr + (pBitNum / 8)                 ' Find the element of the array that holds the bit, and move up to it
    bTemp = INDF1                                       ' Transfer the element's value into a temporary variable
    LoadBit(bTemp, (pBitNum // 8), pValue)              ' Write the bit
    INDF1 = bTemp                                       ' Transfer the value into the array's element
EndProc

Notice the, still beta, Global directive that will create a variable that can also be used as a parameter because it is global and created before the procedure, but only if the procedure is called in the program's listing. It is still beta, but seems to work well, and will allow parameters to use global variables that are only ever created when the procedure is called. In theory anyway. :-)

The procedures are, essentially, creating a Bit array mechanism from a Byte array, so may come in handy someday.

Below is a screenshot of the above program working with a reliable device in Proteus:
Write and Read Array Bits.jpg