How does a microcontroller "remember" a program?

The PIC includes a type of nonvolatile memory called "Flash EEPROM". When you "send your program to the microcontroller", the special adapter is in fact programming your code into this memory. The physical memory is a special kind of transistor with a floating gate that can store a charge more or less indefinitely, even with no power applied. In most devices, "charged" = 0, "no charge" = 1.

Whenever the PIC is reset or powered-up, it begins executing your code, fetching it directly from this memory.

On the PIC, this memory is integrated into the same chip that holds the CPU and the rest of the logic (peripherals, etc.). The same kind of memory is used to hold the BIOS in your desktop/laptop PC, but it's a separate chip from the CPU. The first few screens you see when you switch on your PC come from the BIOS, which then loads your operating system from hard drive or SSD and runs that.


There are quite a few parts to make the magic of programming a microcontroller work.

Your development toolchain (compiler, assembler, linker etc) translates your program from source code to a series of machine instructions which will be stored on the microcontroller.

The micro controller normally stores the program in flash memory (UV erasable and one-time programmable microcontrollers also exist). This is a special type of memory that is designed to retain data even when the power is turned off. These rely on a structure known as a "floating gate mosfet". Essentially each mosfet in the memory array has a tiny capacitor in series with it's gate and the charge on this capacitor changes the behavior of the transistor.

The floating gate is surrounded by insulating material and therefore under normal conditions charge can neither enter or leave the floating gate. This allows the floating gate to retain charge and hence information even when the circuit is powered off.

However when sufficiently high voltages are applied, electrons can cross the insulating layer. This allows charge to be added to or removed from the floating gate. Generally the mechanism for charging the gates (known as "programming") can be done on an individual bit basis, but the method for removing charge (known as "erasing) can only be done for a whole block of memory at a time.

When you connect your programming adapter and tell the software to program the micro-controller, it puts the microcontroller into a special "program mode". The details of this vary between different microcontrollers, but on your PIC16f877a it is normally done by applying 13V to the Vpp/MCLR line. On older flash chips Vpp would actually supply the power needed for programming, but on your PIC it is just a signal line with whatever voltages are needed to program the flash array generated internally. Once in program mode the processor stops executing normal instructions and instead responds to special commands sent over the programming interface. On PICs this is a synchronous serial interface with a unidirectional clock line PGC and a bidirectional data line PGD.

Once in programming mode mode, the programming software will send a series of serial commands through the programming adapter to write your program to flash. Two different approches are possible, in one approach "erase and program" commands are used to erase and reprogram one block at a time. In the other approach the whole chip is erased with a "bulk erase" command, then "program only" commands can be used to program the new data. In both cases before issuing an "erase and program" or "program only" command the data must first be loaded into staging registers. You can find the gory details in http://ww1.microchip.com/downloads/en/devicedoc/39589b.pdf


First things first...do you understand how a one-time programmable fusible memory works? Like if I had a billion little wires and each one I choose to connect to either +V for a logic HI (ONE )and GND for a logic LO (ZERO), do you understand how that stores a program in itself of ones and zeroes? You could take a voltmeter and for each wire you could measure whether it is connected to +V or GND to figure out whether the bit at that location is a HI or LO. A microcontroller does the same thing.

Everything else is a fancy, more flexible version of this concept: How does ROM work?

This tends to lead to the question: "How does a microcontroller take the program of ones and zeroes and do stuff with it What happens at hardware level when we feed a code?