## Setting a bit within a byte

To set a bit to 1 use theORoperator.The

ORoperator is similar to theADDoperator in that it takes two arguments and produces a result.The XCSB

ORoperator is the'|'(vertical bar) character

BEWARE:XCSB has both a bitwiseORoperator and a logicalORoperator. The logicalORoperator is'||'(two vertical bar characters).## How it works

TheORoperator forces a 1 in a column where a 1 exists in either the first argument or the second argument.e.g.Written in XCSB this would be

argument 1 00100100argument 2 00100001result 00100101The above example shows the result of a bitwiseARG1 = 0x24 ARG2 = 0x21 result = ARG1 | ARG2 // this could be written using constants as result = ARG1 | 0x21 // or as result = 0x24 | ARG2ORoperation.Setting bits within an existing variable or output PORT is achived by assigning the result back to one of the arguments

This is equivalent to forcing bits 0 and 5 to 1 in PORTAPORTA = PORTA | 0x21## Clearing a bit within a byte

To set a bit to 0 use theANDoperator.The

ANDoperator is similar to theADDoperator in that it takes two arguments and produces a result.The XCSB

ANDoperator is the'&'(ampersand) character

BEWARE:XCSB has both a bitwiseANDoperator and a logicalANDoperator. The logicalANDoperator is'&&'(two ampersand characters).## How it works

TheANDoperator forces a 0 in a column where a 0 exists in either the first argument or the second argument.e.g.Written in XCSB this would be

argument 1 01001000argument 2 01000010result 01000000The above example shows the result of a bitwiseARG1 = 0x48 ARG2 = 0x42 result = ARG1 & ARG2 // this could be written using constants as result = ARG1 & 0x42 // or as result = 0x48 & ARG2ANDoperation.Clearing bits within an existing variable or output PORT is achived by assigning the result back to one of the arguments

This is equivalent to forcing all bits except bits 1 and 6 to 0 in PORTAPORTA = PORTA & 0x42This turns out to be difficult to visualise. It would be much simpler if we could force all bits represented by 1 to 0;

This is actually very easy to accomplish if we use the bitwise

NOToperator. The XCSB bitwiseNOToperator is the'~'(tilda) character (NOTE:this operator only takes one argument, it is like placeing a minus in front of an expression to change the sign of the result)This is equivalent to forcing bits 1 and 6 to 0 in PORTAPORTA = PORTA & ~0x42(see a more detailed explanation of AND operator)

The XCSB bitwise

NOToperator has the effect of changing all ones to zeros and all zeros to onese.g.

argument 01000010result 10111101## Using bit numbers instead of masks

Instead of using a bit mask such as 0x40 it is possible to use a bit number to address a bit within a byte. For any memory location (including PORTA) the bits within the location are numbered as:

76543210To set bit 6 of PORTA to 1 we could use the XCSB statement

XCSB is actually clever enough to realise what it meant and it will generate the single PIC instruction to perform the operationPORTA = PORTA | (1 << 6)To set bit 6 of PORTA to 0 we could use the XCSB statementbsf PORTA,6Again XCSB is clever enough to realise what it meant and it will generate the single PIC instruction to perform the operationPORTA = PORTA & ~(1 << 6)The advantage of using bit numbers over simple masks is not clear from these simple examples. The fact is that in some circumstances it is much simpler to perform calculations on bit numbers than it is on masks. Consider the situation where you need to store a PORT address and a bit within the port in a table so that you can step through the table turning PIN's on and off. If you use a mask you will also need to store the address of the port along with the mask. If you store a bit number you can code this into 3 bits (0 to 7) which leaves the remaining 5 bits available for use as a port number.bcf PORTA,6for j=0 while j<64 step j+=1 do acc = tbl[j] bit_number = acc & 7 port_number = acc >> 3 PORTA[port_number] = PORTA[port_number] | (1 << bit_number) wait() done## Bits and Masks

BITSHEXBit76543210Expr000000000x00(0 << 0)000000010x01(1 << 0)000000100x02(1 << 1)000001000x04(1 << 2)000010000x08(1 << 3)000100000x10(1 << 4)001000000x20(1 << 5)010000000x40(1 << 6)100000000x80(1 << 7)