Classic Logic

Memory Organization in PIC Microcontroller

(This post is currently undergoing revisions)

I’ve been working with the PIC microcontrollers lately, and I kind of figured I might as well document what I’ve been learning.

The microcontroller I’m talking about in this post is the P16F877A, and keep in mind that whenever I’m referring to “PIC”, I’m talking about this particular microcontroller.

The PIC microcontroller has a Harvard architecture, which in simple terms mean that they have separate memory for both program and data, called program memory and data memory respectively. One advantage of this architecture is that they can simultaneously access both program memory and data memory. In addition to both these memory, there’s also a stack, which I’ll talk about in more detail later.

Data Memory

The data memory has 512 bytes of storage – quite sufficient for our academic purposes. You could also say that it has for 512 “words” of storage, with a word-length being 8 bits. Also, to address all the 512 words, you would require 9 bits (since 2^9 = 512).

Number of words: 512

Number of bits in a word: 8 bits

Number of bits required to address each word: 9 bits

The 512 words of the data memory are divided into four banks of 128 words each, as shown in the figure below.

![Data Memory in PIC]({{ site.url }}/assets/images/PIC_DataMemory.jpg)

And now, let me explicitly state the starting and ending addresses of the four banks.

Bank Starting Address Ending Address
Bank 0 0 0000 0000 0 0111 1111
Bank 1 0 1000 0000 0 1111 1111
Bank 2 1 0000 0000 1 0111 1111
Bank 3 1 1000 0000 1 1111 1111

With the number of words being 512, one would normally require 9 bits for addressing all the words. However, as you would eventually learn, the instructions refer to data registers using just 7 bits. So here’s the big question - how do you address 512 words using just 7 bits (instead of the intuitive 9)?

Observe more closely at the starting and ending addresses (in binary) of each bank. You’ll notice that the first seven bits are identical across all banks – 000 0000 for the starting address and 111 1111 for the ending address. It is the two remaining bits that really decide to which bank a register belongs to.

So, while addressing the data memory, only the first seven bits of the data memory are taken from the instruction itself. The remaining two bits are taken from a Special Function Register (SFR) called the status register – more specifically, the 5th and 6th bit of the status register, which are called register pointers RP0 and RP1 respectively.

Depending on the values of the register pointers, the currently selected banks are as follows:

RP0 RP1 BANK
0 0 Bank 0
0 1 Bank 1
1 0 Bank 2
1 1 Bank 3

I’ll talk more about the status register in a later post.

Program Memory

The program memory is where you would store instructions. It has 8K words (with K being 1024), and the length of a word is 14 bits. That means, you would need 13 bits to address each of the words in the program memory.

Number of words: 8K words

Number of bits in a word: 14 bits

Number of bits required to address each word: 13 bits

The way each bit of a word in the program memory is used depends on the specific instructions. I’ll talk more about the program memory in a future post when I elucidate the instruction set of PIC.

Additional Resources

[P16F877A Datasheet]({{ site.url }}/assets/pdf/P16F877A_DataSheet.pdf) (obtained from official Microchip website)