Electronic – Separate registers for input and output in microcontrollers

microcontrollermsp430pic

I'm used to using PIC microcontrollers and they have only one register for input and output.

Now I'm studying MSP430 and I see they provide separate registers for input and output.

So, why is it useful to provide separate registers for input and output?

EDIT

I'm reading this book: MSP430 Microcontroller Basics

enter image description here

Normally this book compares MSP430 with PIC16 family. PIC10/12/16 don't have the register LATx. But PIC16 enhanced has.

Best Answer

I don't know the MSP430 in any detail, but have a lot of experience with PICs. PICs don't specifically have a separate register for input and output, but many of them do in practise. The PORT register contains the immediate pin states, for input and output. The LAT resgister contains the last-written values, so I suppose you can call it a output register. If you use PORT for input and LAT for output, then you have separate input and output registers. Just ignore that PORT could be used for output too, with slightly different properties than LAT.

The low PICs from 16 on down don't have LAT registers, only the PORT register. You therefore use the same register for input and output. That's no big deal since reading and writing are separate operations.

There is one wrinkle with this that sometimes catches people, and much superstition-based programming has evolved around it. The issue is that the PORT register always reflects the actual pin states. This may sound simple and harmless, but you can get into trouble when the external circuit holds the pin in the opposite state it was written in. Note that enough capacitance on the pin will do this, at least for a little while.

This becomes a problem when you perform a read-modify-write operation on a port register shortly before having changed a output pin. Let's take the really obvious case of ORing 0 into the PORT register. OR is a read-modify-write operation. The OR instruction will read the existing register value, perform the OR, then write the result back to the register. Now imagine the previous instruction wrote a new value to a output pin, but that pin hasn't had time to get to its new state yet. The read part of the OR instruction reads the current PORT register value, which is not the most recent value written to it because the pin hasn't slewed to its new state. The OR with 0 doesn't change anything, so the old state of the PORT register is written back to it, essentially cancelling the previous write.

Now you may say that ORing 0 into a PORT register is silly. In most cases that's true, but that was just to make a obvious example. Consider that the BSF and BCF (bit set and bit clear) instructions actually perform a read-modify-write on the whole port register. Consider the instruction sequence:

     banksel portb
     bsf   portb, 1
     bsf   portb, 2

Let's assume all port B pins are set to outputs and are all low to start with. After the first instruction RB1 will start going high. Due to capacitive loading, RB1 is still low and PORTB therefore reads 0 when fetched as part of the second instruction. Bit 2 is now set, so the value 4 is written to PORTB. RB1 will now go low again since 0 was written to that bit. RB2 will start going high. The net result of this instruction sequence could be that only RB2 is high, not RB1 and RB2 as probably intended.

The LAT register was introduced to avoid this problem. It holds the last written value, not the actual instantaneous pins state. If this instruction sequence was performed on LATB instead of PORTB, both RB1 and RB2 would be driven high at the end regardless of how slowly they might get there.

So what do you do? On a PIC 18 and higher read from PORT and write to LAT, and there'll be no problems. On the other PICs, avoid any read-modify-write operation on PORT until you know all pin states have settled. Some people will tell you to always use a shadow copy, modify that, then write that to the PORT register. That's just silly voodoo programming, of course. You know your circuit. Most of the time a single NOP between a write and any read-modify-write is all that's needed. If the pin can't get to its new state in at least one whole instruction cycle, then the circuit should most likely be fixed anyway. In rare cases shadow register can be useful, but those are rare cases indeed. Mostly they are just a waste of cycles, RAM, and one more thing to mess up, especially for the kind of people that blindly follow rules like "always use a shadow register". A much simpler answer is that those kind of people should just stick to a PIC 18 or higher.