Writing PIC port bits

Going through some very early PIC code, I came across a really ugly fix I made and have been quietly using since. There was some flakiness writing output port bits individually, and so I just buffered the entire word in RAM and wrote the entire PORT each time. It sucks, but got the job done. Undoing the hack just now, writing a single bit, say RC0 = 1, resets the other pins. WTF? The compiler is HiTech's PICCLITE, although I don't think it matters. The disasssembly shows the expected "BSF 0x7, 0". Having pulled a bit of hair and lost a bit of sleep over this, I just stuck that little "gem" of hack into everything I did since. Now it's time to get rid of it.

My expectation is that writing an output port should be routinely possible, and unusual "side-effects" such as I saw would be show stoppers. Anyway, I don't know where the fault is. It could be the compiler's IRQ state pushing, but that doesn't make sense. I could write the simplest test program on earth to set a few bits, but thought I would start by asking here. (Actually, this isn't the beginning. The beginning caused me to lose a fistful of hair and some sleep.)

Reply to
Mike Young
Loading thread data ...

As someone else said, this is normal and your fix is SOP. It can lead to all sorts of unpleasant bugs if you're not a bit careful.

Later PICs such as the 18F series have a second port memory location (called LATx rather than PORTx) that reads the latch output rather than the current port pin levels, and thus makes RMW instructions work the way you would probably expect.

Best regards, Spehro Pefhany

--
"it\'s the network..."                          "The Journey is the reward"
speff@interlog.com             Info for manufacturers: http://www.trexon.com
Embedded software/hardware/analog  Info for designers:  http://www.speff.com
Reply to
Spehro Pefhany

fix I

writing

in RAM

Undoing

It's called using a shadow register. It's actually the best way to do things.

pins.

If you diddle a single bit on a port, you can run into the dreaded RMW (read modify write) issue. In order to change just one bit, the PIC has to read the whole port value, change the bit and write the whole port value back. The problem lies in reading the port bits. The actual pin state gets read and not the port latch register. This can be a real problem if the pins are heavily loaded and/or the PIC is running at higher clock speeds. Search Google for more than you ever wanted to know about this stuff.

matters.

of

of

Good luck, but I don't think you will likely succeed. Stick with using a shadow register to hold the pin values, it's one less thing to worry about.

possible,

Anyway, I

pushing,

on

This is a common pitfall with PICs.

Reply to
Anthony Fremont

...

Thanks; that helps more than you know. BTW, was your closing remark about PICs in regard to RMW? or to hair and sleeplessness?

Reply to
Mike Young

'Read, modify, write'. If you do a bit set/clear on a bit in the port, the port itself is physically 'read', the bit is toggled, and the result written back to the output. The problem is that if (for instance), the pins have a heavy load, and though driven 'high', do not reach the voltage that the input sees as the 'high' level, the bit concerned will be read as a '0', not a '1', and written back with the wrong value. This example would be in a sense an 'overload' condition on the output concerned, but can be met on a quite reasonably loaded pin, if there is a some capacitance present. The actual 'write' to the port takes place in the last clock cycle of the instruction, while the 'read' takes place in the first clock cycle. So if you perform two successive I/O operations, setting (say) bit 0, then bit

1, on the second operation, there will only be one cycle of the processor clock, since bit 0 was nominally 'set', and it is common to find that the combination of load capacitance and gate drive limits, have not allowed the pin to reach the desired level in this time. It is inherent in the fact that there is only the port itself, and not a seperate output latch. The 18 family chips have a 'shadow register', to allow this to be avoided. On the older chips, doing it in software, or allowing enough time for the pins to correctly reach the required level, are well documented 'fixes' (MicroChip describes this problem comprehensively in a couple of their application notes).

Best Wishes

Reply to
Roger Hamlett

Particularly for open-drain outputs. This one is an accident waiting to happen:

LED Port pin -----[R]-----|

Reply to
Spehro Pefhany

Time will never be enough when the pin is loaded enough to prevent it from reaching the desired level. on the 12 and 14 bit cores a shadow register is realy the only solution.

Wouter van Ooijen

-- ------------------------------------

formatting link
Webshop for PICs and other electronics
formatting link
Teacher electronics and informatics

Reply to
Wouter van Ooijen (www.voti.nl

And the LED will not be lit. Did you intend something else? Are you using the LED as an input device?

Reply to
Richard Henry

Sure, but the LED may not reliably pull it all the way to '1'. RMW will then drive a '0' to the port pin, even if the LED is "off".

--
  Keith
Reply to
Keith Williams

Works fine in that direction, but with an open-drain port pin, the LED+resistor (depending on LED Vf and supply voltage) may not be able to pull up the output pin above the "1" threshold.

Best regards, Spehro Pefhany

--
"it\'s the network..."                          "The Journey is the reward"
speff@interlog.com             Info for manufacturers: http://www.trexon.com
Embedded software/hardware/analog  Info for designers:  http://www.speff.com
Reply to
Spehro Pefhany

Yes, what he said.

Best regards, Spehro Pefhany

--
"it\'s the network..."                          "The Journey is the reward"
speff@interlog.com             Info for manufacturers: http://www.trexon.com
Embedded software/hardware/analog  Info for designers:  http://www.speff.com
Reply to
Spehro Pefhany

Red LED's have lower on-voltage than green ones.

Reply to
Don Foreman

Suppose that the above port pin is open-drain, with the LED connected as above. Suppose the LED has been successfully turned off some time ago (long enough for the voltage to settle out) by a bsf instruction (bit set) operating on the port.

Now suppose that we try to modify another bit of the same port.. with, for example, a bsf or bcf instruction (or other RMW instruction). The RMW instruction first reads the entire port (input levels, not latch), modifies only the bit in question, then writes it back to the latch. If the open drain *output* was not pulled up to a "1", then the R part of the RMW instruction reads a "0" and writes that (unmodified) back to the latch. The LED then turns "on", which is probably not what you intended.

This can be "fixed" with a resistor across the LED, but then you can run into a potential time issue, as I implied in the first paragraph. If the instruction to turn the LED off is too close (time-wise) to the next RMW instruction on the same port for the stray capacitance to be charged reliably to the "1" level then you can have the same thing happening.

Best regards, Spehro Pefhany

--
"it\'s the network..."                          "The Journey is the reward"
speff@interlog.com             Info for manufacturers: http://www.trexon.com
Embedded software/hardware/analog  Info for designers:  http://www.speff.com
Reply to
Spehro Pefhany

It doesn't? Why not? As long as there is a reasonable value resistor, shouldn't the PIC be able to pull the pin all the way to ground?

Reply to
Anthony Fremont

Doh, I get it now. I wasn't looking at that end of things. ;-)

Reply to
Anthony Fremont

A *little* (blue ones are higher), and that's why the statement (above):

"Why does it work with a red LED, but not with a green one?"

--
  Keith
Reply to
keith

It's always the end you're not looking at that you get kicked in! ;-)

There's a bunch of other usefull stuff (much learned the hard way) in this thread too.

--
  Keith
Reply to
keith

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.