Home

Read Modify Write Instructions and Shadow Registers

E-mail Print PDF
( 10 Votes )
Question:
When should I use a Shadow Register to write to a Port? What are Read/Modify/Write Instructions?
When I have an input pin configured as pullup, the value of the input gets stuck to 0 irrespective of the state of the input pin.  What could be the problem?

Answer: When you have input pins configured as Pull Up or Pull Down and if there are other pins on the same port that are configured as outputs, an instruction that is used to update an output pin may accidentally set or clear the input pin thus latching the input.  For example let us consider the following scenario.

P1[0] - PullUP, Connected to a key. 1 has been written to the bit in PRT1DR to enable the pullup
P1[1] - Strong, drives an LED.

Now, the following instruction is used to switch off the LED

and reg[PRT1DR],~0x02

The above instruction is a Read/Modify/Write instruction, ie, it first reads the pin states (not the PRT1DR register), does an and operation with the mask and then writes back the result to PRT1DR register. When this instruction is executed, if the key is pressed, then the pin state of P1[0] would be 0, so the result of the operation would be

Pin State: xxxxxxx0
AND operation: xxxxxxx0 & 11111101 = xxxxxx00
Write back: xxxxxx00

You will find that bit 0 which drives the key has been cleared in PRT1DR now and will never become high.  This will result in the input pin stuck to 0, even if the key is released.

A workaround for this condition is using Port shadow registers. Declare a variable in RAM and initialize this variable in the beginning of code to the initial Port value. After this, do any Read/Modify/Write operation on this shadow register and then write the value of shadow register to the PRTxDR register.

// Declare a shadow register
BYTE Port1Shadow;

// Initialize in the beginning of code
// Bit0 is set to enable the Pullup for the key
Port1Shadow = 0x01;
PRT1DR = Port1Shadow;

// Now to clear the LED
Port1Shadow &= ~0x02;
PRT1DR = Port1Shadow
Comments (0)
Only registered users can write comments!