Logical BIT setting

General discussion on mikroC PRO for PIC.
Post Reply
Author
Message
white-eagle
Posts: 17
Joined: 30 Mar 2009 21:03

Logical BIT setting

#1 Post by white-eagle » 14 Apr 2009 16:21

How do I set only the 4 LSB of a port byte by reading 4 bits from an arry?
I read 4 bits from an arry and want to set the according 4 output ports, without affecting the 4 other ports.

I don't want to use if then statements and PORTA.Fx
Is this possible?

Sparky1039
Posts: 1179
Joined: 24 Nov 2005 20:07
Location: Colorado, USA

#2 Post by Sparky1039 » 14 Apr 2009 17:11

You apply a "bit mask" by using the bit-wise AND (&) and bit-wise OR (|) operators. Use the AND operator to clear bits, and the OR operator to set bits.

Check the help file for more info.

Or this: http://en.wikipedia.org/wiki/Bit_mask

white-eagle
Posts: 17
Joined: 30 Mar 2009 21:03

#3 Post by white-eagle » 14 Apr 2009 19:05

You mean like this:

portvalue = xxxxyyyy

xxxx must remain the same yyyy has to become 1010 (for instance)

xxxxyyyy
00001010 OR
-----------
xxxx1y1y

xxxx1y1y
11111010 AND
----------
xxxx1010

Sparky1039
Posts: 1179
Joined: 24 Nov 2005 20:07
Location: Colorado, USA

#4 Post by Sparky1039 » 15 Apr 2009 00:38

Yes this is the idea. The best way to do what you want is to create a shadow register for manipulating the port state. This register is a normal declared variable of char size and always holds the current state of the port. Think of it as a scratch pad for writing to the port.
Example:
The PIC needs to start out with an initial state of 11101001

Code: Select all

char ShadowReg_B;
ShadowReg_B = 0b11111001;   // load shadow register variable with port initial state
PORTB = ShadowReg_B; // write it port B
Now you want to clear bits 1 and 4 and leave the rest unchanged

Code: Select all

ShadowReg_B = ShadowReg_B & 11110110;  // apply AND bit mask
PORTB = ShadowReg_B;  // port B now is 11110000
To set bits 2 and 3

Code: Select all

ShadowReg_B = ShadowReg_B | 00000110// Apply OR bit mask
PORTB = ShadowReg_B;  // port B now is 1110011
There is another way to do this kind of port manipulation, it's called the read-modify-write method (RMW).
However it has to be done carefully because it can give you back erroneous results. I don't recommend using it.

The difference between the above code and RMW is that you first "read" the port into the shadow register. The problem with this step is the PIC reads the actual logic state on the port pins, not the output latch register. If the port pins are not sufficiently pulled high or low the value read can be wrong. This is especially troublesome if for example you are driving a MOSFET transistor. The MOSFET gate is a capacitor and depending upon the previous logic state it will be either charging or discharging. So when the PIC actually reads the port, the voltage on this gate may be somewhere between a logic high or logic low. So as you can see the result can be erroneous. Sometimes it's correct other times it's not.

The RMW example:

Code: Select all

char ShadowReg_B;
ShadowReg_B = 0b11111001;   // load shadow register variable with port initial state
PORTB = ShadowReg_B; // write it port B
Now you want to clear bits 1 and 4 using RMW and leave the rest unchanged

Code: Select all

ShadowReg_B = PORTB   //   >>> The READ step <<<
ShadowReg_B = ShadowReg_B & 11110110;  // apply AND bit mask >>> the MODIFY step <<<
PORTB = ShadowReg_B;  // port B now is 11110000  >>> The WRITE step <<<

Post Reply

Return to “mikroC PRO for PIC General”