cool Welcome PIC fans!
(to Pascal language fans too!)

Close General documentation

Close How to support PMP

Close Manuals

Close Tips

Other stuff

Close Documentation

Close How to support PMP

Close Off Topic

Close Today's favourites


cadeau.gifTips - The Read-Modify-Write problem on I/O ports

Here is an excellent article on this problem that everybody should be aware of.

Mainly the problem is that when you read a PIC PORTx I/O, you read the input buffer, not the output latch for pins that are defined as outputs.
Some latest processors have separate output latches named LATx that are readable. In this case, the read-modify-write problem does not apply, just use PORTx for inputs and LATx for outputs.

How problems may occur: if the output pin has some load that makes the requested level to not be reached (by an excessive pullup or pulldown, by an heavy capacitive load such as a mosfet gate) the "input" may not reflect immediately (or never at least) what you "output"; so a code like:


may write back a 0 on PORTA.0 at the 2nd instruction (yes, a BSF reads the whole port, changes the bit and writes back to the whole port).

another example:


After this, all pins should be 0, may be not: at the third instruction PORTA is read back before computing the xor, so it may read some zeroes...

What about PMP?

PMP allows direct port write that maps directly to the shortest processor's instructions, so the above remarks apply:

PORTA := 0;
PORTA.0 := true;
PORTA.1 := false;

may write back a 0 on PORTA.0 at the 3rd instruction.


The simplest way is... Do not use such constructions...

Next, if the problem is due to a capacitive load, some delay may be inserted between writes, to allow the cap to charge, but that's empirical and not bulletproof:

PORTA := 0;
PORTA.0 := true;
NOP(2); // or delay(xxx)
PORTA.1 := false;

Next, if the problem is a only due to a capacitive load, we may wait until the cap has charged, but that would hang the processor if nothing happens:

PORTA := 0;
PORTA.0 := true;
repeat until PORTA.0 = true; // wait for capacitance charging
PORTA.1 := false;

Finally, a bulletproof armor uses a shadow register:

SHADA := 0; // Initialize
SHADA.0 := true;
SHADA.1 := true; // start pulse
SHADA.1 := false; // end of pulse

where SHADA is a global byte variable that will reference / hold all manipulations on PORTA for the whole program and that is systematically copied to PORTA after each block of changes.

To do list:

Future implementation of PMP should contain some mechanism to automatically use a shadow register that should be activated by a compiler directive (since this is time / code consuming and everybody does not need it).

Creation date : 2007.06.24 6:14 PM
Last update : 2013.08.05 11:25 AM
Category : Tips
Page read 16197 times

Print the article Print the article

react.gifReactions to this article

Nobody gave a comment yet.
Be the first to do so!

 Members List Members : 94

Your Username:


[ Password lost ? ]

[ Join us ]

Member online :  Member online :
Anonymous online :  Anonymous online : 7

Total visits Total visits: 858652  

Most ever online
Most ever onlineTotal : 77

The 07/11/2014 @ 07:38

Webmaster - Infos



Friends News
Where are you from?

Sentence to think about :  Slow and methodical testing like this will eventually get you to a point where you will either be able to spot the bug, or go quietly insane. Maybe both.  Persistence of Vision 2.1 software documentation.
^ Top ^