Logical and Bit Instructions
A DINT is 32 individual bits. These instructions work on those bits directly: AND, OR, and XOR combine two words bit-by-bit; NOT flips every bit of one word; CLR clears all 32 bits to 0; and BTD moves a run of bits from one position to another. Reach for them when a tag is a bundle of flags rather than a single number — packing several on/off signals into one word, pulling one flag back out, clearing a scratch register, or flipping a bit without disturbing its neighbors.
Like the math instructions, they act as outputs — place them on the right side of a rung, and they run once per scan while the rung is true. They share the Move/Logical tab with MOVE and MVM.
Available Instructions
| Instruction | Symbol | Purpose |
|---|---|---|
AND | AND Source A sourceA Source B sourceB Dest dest | Writes the bitwise AND of Source A and Source B into the destination tag. Each result bit is 1 only where both source bits are 1. |
OR | OR Source A sourceA Source B sourceB Dest dest | Writes the bitwise OR of Source A and Source B into the destination tag. Each result bit is 1 where either source bit is 1. |
XOR | XOR Source A sourceA Source B sourceB Dest dest | Writes the bitwise exclusive-OR of Source A and Source B into the destination tag. Each result bit is 1 where the two source bits differ. |
NOT | NOT Source source Dest dest | Writes the bitwise complement of the source into the destination tag. Every 0 bit becomes 1 and every 1 bit becomes 0. |
CLR | CLR Dest dest | Clears the destination tag to 0. |
BTD | BTD Source source Source Bit sourceBit Dest dest Dest Bit destBit Length length | Copies a run of bits from the Source into the destination starting at a chosen bit, leaving the other destination bits unchanged. |
Operands
AND, OR, XOR:
| Name | Type |
|---|---|
sourceA | DINT | REAL |
sourceB | DINT | REAL |
dest | DINT | REAL |
NOT:
| Name | Type |
|---|---|
source | DINT | REAL |
dest | DINT | REAL |
These are bit operations, so the natural operand is a DINT. A REAL source is allowed but is first converted to a DINT (banker rounding) before the bits are combined — you rarely want that. A BOOL is not accepted: to combine single on/off bits, use ladder contacts (series for AND, a parallel branch for OR), not these instructions.
Bit by bit
For any single bit position, the four instructions do this:
| Source A bit | Source B bit | AND | OR | XOR |
|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 | 1 |
1 | 0 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 |
NOT needs no table — it simply inverts each bit.
Writing masks in hexadecimal or binary makes the bit pattern obvious: 16#00FF is the low 8 bits, 2#0000_0100 is bit 2 alone.
Example — pull one byte out of a word (AND masks)
AND with a mask keeps only the bits the mask has set to 1 and forces the rest to 0. To read just the low byte of a status word:
AND(StatusWord,16#00FF,LowByte)
If StatusWord is 16#12AB, then LowByte becomes 16#00AB — the high half is masked away.
Example — set and clear a flag (OR / AND)
Store several independent flags in one DINT, each on its own bit. OR turns a bit on without touching the others; AND with the inverted mask turns one off.
XIC(In_Fault)OR(Alarms,2#0100,Alarms);XIO(In_Fault)AND(Alarms,16#FFFFFFFB,Alarms)
The first rung sets bit 2 of Alarms while In_Fault is on; the second clears bit 2 (mask 16#FFFFFFFB has every bit set except bit 2) when the fault is gone. The other alarm bits keep their values either way.
Example — toggle a bit (XOR)
XOR against a mask flips exactly the bits the mask sets. A one-shot on the rung makes each press flip the bit once:
XIC(In_Press)ONS(EdgeBit)XOR(Mode,2#0001,Mode)
Every press flips bit 0 of Mode between 0 and 1.
NOT — inverting a whole word
NOT flips all 32 bits of its source. Because a DINT is signed, an all-0 word inverts to all 1s, which reads as -1:
NOT(16#0000000F,Inverted)
Here Inverted becomes 16#FFFFFFF0 (decimal -16). NOT of 0 is -1; NOT of -1 is 0.
This NOT inverts a whole DINT word — it is not a way to invert a single contact on a rung. To pass power when a bit is 0, use a normally-closed contact (XIO). NOT and XIO solve different problems.
CLR — clear a word
CLR writes 0 into its destination. It is the fast way to zero a working register — shorter than MOVE(0, dest) and it reads as "clear this."
| Name | Type |
|---|---|
dest | DINT | REAL |
CLR(Wrk_Accumulator)
While the rung is true, Wrk_Accumulator becomes 0. Unlike the other instructions here, CLR also accepts a REAL destination, which it clears to 0.0.
BTD — bit field distribute
BTD moves a run of bits from one position to another. It takes a length-bit field out of source starting at sourceBit, and lays it into dest starting at destBit. Every other bit of dest is left unchanged, and source itself is never modified.
| Name | Type | Notes |
|---|---|---|
source | DINT | the bits to move |
sourceBit | DINT | 0–31, where the field starts in the source |
dest | DINT | where the field lands |
destBit | DINT | 0–31, where the field starts in the destination |
length | DINT | 1–32, how many bits to move |
sourceBit, destBit, and length are immediate whole numbers typed directly into the block — not tags. sourceBit and destBit are 0–31 (a DINT has 32 bits); length is 1–32.
BTD(In_Packed,0,Out_Word,8,4)
This takes the lowest 4 bits of In_Packed and writes them into bits 8–11 of Out_Word, leaving the rest of Out_Word as it was. If the field would run off the top of the destination, the extra bits are simply dropped — they do not wrap around to bit 0.
Common Mistakes
- Using a
BOOLoperand onAND/OR/XOR/NOT/BTD— these are word (DINT) operations. Combine single bits with contacts and branches instead. - Reaching for
NOTto invert one contact — that is whatXIOis for.NOTinverts all 32 bits of a word. - Forgetting that
NOTandAND-with-an-inverted-mask produce negativeDINTvalues when the high bit ends up set — the bit pattern is correct even though the decimal looks surprising. - Writing
AND/OR/XORthe wrong way around — the destination is the last operand. - Typing a tag into
BTD'ssourceBit,destBit, orlength— those are fixed numbers, not tags. A bit position outside0–31, or a length outside1–32, is a compile error. - Reaching for
CLRon aBOOL— use anOTU(unlatch) to drive a single bit to0.CLRzeroes a wholeDINTorREALword.
Related
- XIO — invert a single bit on a rung (a normally-closed contact)
- MOVE / MVM — copy a whole value, or copy only masked bits
- Array Tags — a bitwise result is also legal inside an array subscript, e.g.
Buffer[Index AND 7] - Logical Operators (Structured Text) — the same
AND/OR/XOR/NOT, written as operators