Electronic – How does a specific pin in a port change its state (PIC Microcontroller)? Software vs Hardware

compilermicrocontrollerpicport

How does, for instance PortB.B0 = 1; command change the state of a specific pin in a microcontroller.

Microcontroller usually has a 8 bit data line, meaning it will write and read from the entire port simultaneously. My question is, is it the compiler's job to read the entire port set the specified bit and write the entire byte back to the port or can the microcontroller change a single bit on its own?

Best Answer

I assume you are talking about the PORT registers in the common hobby PICs. These chips do have bit level set and clear instructions, and a compiler can be expected to translate

PortB.B0 = 1;

to

BSF PORTB, 0

BUT BUT BUT BUT BUT BUT BUT

These bit set and bit clear instructions are executed as a full-8-bit read-modify-write cycle. The CPU reads the 8-bit port, clears the lowest bit, and writes the result back. This would be of only academic interest if not for the fact that reading PORTB reads the logic levels on chips pins. (In most other architectures it would read the PORTB output register.) When the pin is loaded so heavily that its external level does not read the level were the input buffer recognizes it correctly, the value read back can differ from the value last written to it. This is the dreaded read-modify-write problem. The canonical solution is to do your bit operations on a RAM location (called the port's shadow) and then write the shadow buffer to the port using normal 8-bit operations.

If you don't use this canonical approach you will live in interesting times: setting one more pin in an output port can for instance clear the pins you previously set. And of course it will do so only in a production situation, never on your testbed.

side enote: In the Jal langauge (which I designed and implemented long ago, it is now maintained by others) there is some language and library magic to make

pin_a_5 = true

mean

port_a_shadow |= (1 << 5 )
port_a = port_a_shadow

Side note 2:

Modern PICs have a LAT register for each port. Reading these registers yields the value that was last written to them, hence they don't suffer from the read-modify-write problem. AFAIK Jal on those chips does not bother to use a shadow register.