Many developers, especially the new users of the PIC architectures, are confused when it’s coming about the usage of either PORTx or LATx registers.
The general rule is that you should always use PORTx when you are reading from an IO pin and always use LATx when writing to it. The reason for doing it this way is the read-modify-write behavior of the BSET and BCLR instructions.
This article will present some practical examples, and hopefully will eliminate all the confusion generated on this topic.
Let’s take a look on the following lines of code:
In the disassembly listing, you will see that RA0 – RA7 bits are set with BSET instructions.
BSET, BCLR, as many other instructions of the PIC24 architecture are read-modify-write operations and will require two machine cycles to execute: one cycle to fetch the PORTA value, and a second cycle to modify the corresponding bit and to write back the result.
In our example, because a first BSET instruction is already in the pipeline, the second BSET instruction will fetch the PORTA value before the result of the first operation was written back (RA0 = 0). At the end of the second machine cycle, the execution of the first BSET instruction is finish and it will write back the result (with RA0 = 1). In the third machine cycle, the second BSET instruction will also finish the execution and will write back its result (with RA1 = 1, but also with RA0 = 0).
As you can see bellow, the result is that only RA1 is set to 1, even the intension was to set both RA0 and RA1:
A workaround is to add NOPs instructions after each read-modify-write operation with PORTx registers. This will avoid the problem presented above, but still you will not be on the safe side. When you have a high capacity load on the port; the load will slow the voltage rise and fall times, delaying the time when the new logic level is reached. Also, the problem can appear when you connect devices that can take a lot of current from the IO port (some LEDs, for example), creating gray area logic levels.
The problem can really be avoided if the LATx is used instead of PORTx when you are writing data to the IO port: