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

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

Search




Downloads
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:

BSF PORTA, 0
BSF PORTA, 1


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:

MOVLW h'FF'
MOVWF PORTA
XORWF PORTA, f


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.

Workarounds:

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
PORTA := SHADA;
SHADA.1 := false; // end of pulse
PORTA := SHADA;

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 25572 times


Print the article Print the article


react.gifReactions to this article

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


Connection...
 Members List Members : 75

Your Username:

Password:

[ Password lost ? ]


[ Join us ]


Member online :  Member online :
Anonymous online :  Anonymous online : 5

Total visits Total visits: 1572703  

Most ever online
Most ever onlineTotal : 170

The 01/01/2021 @ 17:50


Webmaster - Infos

Ip: 23.20.220.59

Search




Friends News
Where are you from?

Sentence to think about :  The enterprise's computing [...] is just like of an archaeological site. [...] Deep inside, you find real fossils, calcified: the punched card is no longer physically there,
but one can find
its "footprint" on the latest hard drives, up to traces of organization in eighty "columns".
  
Pierre Vandevingste, La Recherche, december 1996
^ Top ^