News:

;) This forum is the property of Proton software developers

Main Menu

Position: Using masking to alter bits within a variable or SFR

Started by top204, Apr 06, 2023, 01:33 PM

Previous topic - Next topic

top204

Altering multiple bits within a variable or SFR requires masking with ANDing with 0, to clear the bits first, then ORing in the new value of the bits. But if the bits are further up the assignment variable or SFR, the value to write to them needs shifting left into the correct position before the ORing takes place.

The example below shows a method that can be used:

'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' Demonstrate masking to alter more than one bit within a variable or SFR
'
' 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

    Dim MySFR1 As Byte
   
    Symbol cMaskForBits01 = %11111100               ' Create a mask for bits 0 and 1
    Symbol cMaskForBits234 = %11100011              ' Create a mask for bits 2, 3 and 4
   
'-------------------------------------------------------------------------
' Use masking to alter more than one bit within a variable or SFR
' Input     : pValue holds the value to place into the bits
' Output    : MySFR1 will have its bits 0 and 1 changed
' Notes     : The principle works with ANDs and ORs...
'           : First, the two bits are cleared by ANDing with a mask that represents the bits required to alter.
'           : Then the new bits are ORed into the cleared bits, to place the required value.
'           : This works as it is if the bits are the LSB types, because pValue can be loaded directly into the assignment.
'
$define MySFR1_LoadBits01(pValue)    '
    MySFR1 = MySFR1 & cMaskForBits01 '
    MySFR1 = MySFR1 | pValue
 
'-------------------------------------------------------------------------
' Use masking and shifting to alter more than one bit within a variable or SFR
' Input     : pValue holds the value to place into the bits
' Output    : MySFR1 will have its bits 2, 3, and 4 changed
' Notes     : The principle works with ANDs and ORs...
'           : First... The three bits are cleared by ANDing with a mask that represents the bits required to alter.
'           : Second... The value is shifted left so it fits into the bits position.
'           : Then the new bits are ORed into the cleared bits, to place the required value.
'           : The shift left is a must, otherwise, pValue would simply be placed into the LSBs of the assignment.
'
$define MySFR1_LoadBits234(pValue)    '
    MySFR1 = MySFR1 & cMaskForBits234 '
    WREG = pValue << 2                '
    MySFR1 = MySFR1 | WREG
          
'-------------------------------------------------------------------------
' The main program starts here
'
Main:
    MySFR1 = %10000000                          ' Load MySFR1 with a value, to make sure it remains in place
    HRSOutLn "Raw    : ", Bin8 MySFR1           ' Transmit its binary value to a serial terminal
   
    MySFR1_LoadBits01(1)                        ' Alter bits 0 and 1 of MySFR1 only
    HRSOutLn "Mask01 : ", Bin8 MySFR1           ' Transmit its binary value to a serial terminal
   
    MySFR1_LoadBits234(5)                       ' Alter bits 2, 3, and 4 of MySFR1 only   
    HRSOutLn "Mask234: ", Bin8 MySFR1           ' Transmit its binary value to a serial terminal

With the demo program above, the serial terminal will contain the texts:

Raw    : 10000000
Mask01 : 10000001
Mask234: 10010101


Where Raw is the initial value placed in "MySFR1", to make sure it is not altered after the bit maskings.
Mask01 is the value after a value of 1 (0b00000001) is written to bits 0 and 1 only of "MySFR1".
Mask234 is the value after a value of 5 (0b00000101) is written to bits 2, 3 and 4 only of "MySFR1".

Notice the mask constants for the bits required? : cMaskForBits01  and cMaskForBits234. These hold the positions of the bits to be written, so they can be cleared first.

The same type of mechanism can be used to read multiple bits only from a variable or SFR using a mask constant value and AND and shifts right.