CHAPTER 2. Introducing the PIC mid-range family and the 16F84A – Designing Embedded Systems with PIC Microcontrollers, 2nd Edition

CHAPTER 2. Introducing the PIC mid-range family and the 16F84A
In Chapter 1 we introduced embedded systems and surveyed the different PIC microcontroller families that are available, using the 12F508 as an introductory device. We are now going to step up a gear and begin to look at the detail of the PIC ‘mid-range’ family. As an example device we will mainly use the 16F84A. We chose this because compared to most microcontrollers it is small and simple and therefore easy to learn from, even though it is not the most recent device. Six chapters later the focus of study will change to the 16F873A, a larger member of the same family. Note carefully that the ’F84A is an almost direct subset of the ’F873A. Therefore, don't worry if you are more interested in the latter device. Everything you learn about the smaller microcontroller is directly applicable to the larger, and forms part of it. Indeed, just about everything we meet in the following chapters applies to all of the mid-range family of microcontrollers, and to all microcontrollers in general.
We will explore the overall architecture of the device and take time to go into some detail about its memory – both the technology and the memory maps.
In this chapter you will therefore learn about:
• The PIC mid-range family, in overview.
• The overall architecture of the 16F84A.
• The 16F84A memory system, along with a review of memory technologies.
• Other hardware features of the 16F84A, including the reset system.

2.1. The main idea – the PIC mid-range family

2.1.1. A family overview

The PIC mid-range family is growing rapidly, with a huge and almost bewildering diversity of members. Therefore, when we talk of ‘family’ here, we are applying the concept of ‘extended family’, and a very large one at that. Nevertheless, the mid-range group stays true to the concept that all family members have identical core and instruction sets, with the difference arising from different peripherals and other features being implemented and different package sizes. Hence, the pattern of Figure 1.9 is followed.
A good example of Figure 1.9 is Table 2.1, which summarises those members of the mid-range family that we meet, in one place or another, in this book. Even with a limited number of microcontrollers, it is a formidable table. Let's begin to make some sense of it.
TABLE 2.1 Some members of the PIC mid-range family (shading applied to highlight groups and aid readability)
ADC, analog-to-digital converter; PWM, pulse width modulation; ICSP, in-circuit serial programming.
For DIP package only.
Device numberNumberof pinsClock speedMemory (K = Kbytes, i.e. 1024 bytes)Peripherals/special features
16F84A18DC to 20 MHz
1K program memory,
68 bytes RAM,
64 bytes EEPROM
1 8-bit timer,
1 5-bit parallel port,
1 8-bit parallel port,
16LF84A18DC to 20 MHzas aboveas above, with extended supply voltage range
16F84A-0418DC to 4 MHzas aboveas above
16F8718DC to 20 MHz
4K program memory,
368 bytes RAM,
256 bytes EEPROM
2 parallel ports,
3 counters/timers,
2 capture/compare/PWM modules,
2 serial communication modules,
2 analog comparators,
nanoWatt technology,
software-selectable oscillator block,
16F8818DC to 20 MHzas above
as above, and
7 10-bit ADC channels
16F873A28DC to 20 MHz
4K program memory,
192 bytes RAM,
128 bytes EEPROM
3 parallel ports, 3 counters/timers,
2 capture/compare/PWM modules,
2 serial communication modules,
16F876A28DC to 20 MHz
8K program memory
368 bytes RAM,
256 bytes EEPROM
5 10-bit ADC channels,
2 analog comparators,
16F874A40DC to 20 MHz
4K program memory
192 bytes RAM,
128 bytes EEPROM
5 parallel ports,
3 counters/timers,
2 capture/compare/PWM modules,
2 serial communication modules,
8 10-bit ADC channels,
2 analog comparators,
16F877A40DC to 20 MHz
8K program memory
368 bytes RAM,
256 bytes EEPROM
16F88228DC to 20 MHz
2K program memory
128 bytes RAM,
128 bytes EEPROM
3 parallel ports, plus one bit
3 counters/timers,
enhanced capture/compare/PWM module,
2 serial communication modules,
11 10-bit ADC channels,
2 analog comparators,
nanoWatt technology, software-selectable oscillator block,
16F88328DC to 20 MHz
4K program memory
256 bytes RAM,
256 bytes EEPROM
16F88628DC to 20 MHz
8K program memory
368 bytes RAM,
256 bytes EEPROM
16F88440DC to 20 MHz
4K program memory
256 bytes RAM,
256 bytes EEPROM
5 parallel ports,
3 counter/timers,
enhanced capture/compare/PWM module,
2 serial communication modules,
14 10-bit ADC channels,
2 analog comparators,
nanoWatt technology,
software-selectable oscillator block,
16F88740DC to 20 MHz
8K program memory
368 bytes RAM,
256 bytes EEPROM
Within the listing shown, we find four groupings of closely related controllers: the 16F84A and its clones; the 16F87 with its near-twin, the ’88; the 16F87XA cluster; and the 16F88X. What is a little less obvious is that two of these groups are somewhat older, and two newer.
The 16F84A is listed first, with features we are about to explore in detail. Table 2.1 shows the number of pins, a modest 18, and clock frequency range. Like all the other microcontrollers in the list, it has three types of memory. The underlying technology of these will be outlined in the next few pages. In the final column we have the peripherals, a listing that is modest in the extreme – two input/output ports and a timer. The sheer simplicity of this little fellow makes it a compelling choice as an introductory device to work with. A variant is the 16LF84A, whose extended supply voltage range allows operation at lower voltages, attractive indeed for battery-powered products. Either of these controllers is available in different packages, different operating temperature ranges and different clock speed ranges. For example, the 16F84A is available in 4 and 20 MHz versions.
Coming in with the same package size as the 16F84A is the ’F87/88 duo. These have a very similar internal structure to the ’F84A, and are pin-for-pin compatible. Nevertheless they carry a number of extra peripherals, as the final column of the table shows. The fact that they are more recent is hinted by the ‘software selectable oscillator block’, and ‘nanoWatt technology'. The latter is a collection of features which allow these two to operate in extremely power-conscious applications. We return to these in Chapter 12.
The 16F87XA is a diverse grouping, as can be seen. There are two package sizes and two memory sizes. It is easy to see that package size is linked directly to the number of input/outputs that are available. The 40-pin versions have five parallel ports (which translates to 33 lines of parallel digital input/output), as well as more analog input, compared with their 28-pin relatives. There is otherwise not much difference. Each package size, however, comes with two different memory sizes. The bigger memory of course gives the opportunity for longer programs and more data storage, but also costs a little more.
The 16F88X is effectively an upgrade of the 16F87XA group. There is the same pattern of two package sizes, with input/output matching the greater or lesser number of pins. Each package size also has several memory size options. There are again the new technology features that were mentioned with the 16F87/88 duo. This group carries very similar peripherals to the 16F87XA clan. Several of these appear in an ‘enhanced' version, adding further capability to already powerful extras.
As is normal Microchip practice, each member or group of the mid-range family has its own comprehensive data sheet, available from Microchip's website. Reference 2.1 is the data sheet for the 16F84A. As well as this, there is a manual covering the features that are common to all members of the family [Ref. 2.2]. While it is not necessary to refer to these while reading this chapter, it is worth knowing they are there, and they are extremely useful for looking up the finer details of a microcontroller's design and use.
If the last group described, the 16F88X, is the biggest, best and most recent of the list, why don't we immediately use its members as our introductory examples? The answer is that they are also pretty complicated. It will be well worth learning basic concepts from smaller and simpler devices. Once these have been understood, it is easy to make the transfer up the food chain to the more complex device. Nothing is lost in this approach, and there is less risk of being overwhelmed with excessive detail.

2.1.2. The 16F84A

The 16F84A, along with its direct predecessors, has been one of many PIC success stories. It first appeared as the 16C84. At a time when most microcontroller manufacturers were trying to make their products bigger, more sophisticated and more complex, Microchip took the bold decision to stay small, simple and easy to use. While many microcontrollers of the day did have on-chip program memory, it was usually EPROM (Erasable Programmable Read-Only Memory), with the attendant time-consuming EPROM erase cycle. With the 16C84, Microchip chose to use EEPROM (Electrically Erasable Programmable Read-Only Memory) for program memory. Thus, it could be programmed rapidly and repeatedly changed. Then, as Flash memory technology became more accessible, the ’C84 was reissued as the 16F84 with the new memory technology. With further upgrading it became the 16F84A. At the time of writing, this is the current version. A 16LF84A, intended for low-power applications, is also available.

2.1.3. A caution on upgrades

As technological expertise develops, any microcontroller design is inevitably upgraded. These upgrades are normally spelled out in documentation published by the manufacturer (e.g. Ref. 2.3). While each upgrade is generally to be welcomed, the changes introduced need to be watched with care. Some are of obvious benefit. For example, the ‘A’ version of the 16F84 can run at a higher speed than before (20 MHz maximum instead of 10 MHz). However, the technical upgrade sometimes has side-effects. These are of no direct advantage and sometimes make it difficult to replace a microcontroller in an existing product with its upgraded version. For example, operating power supply voltages and logic input thresholds are different between the ’F84 and the ’F84A.

2.2. An architecture overview of the 16F84A

The pin connection diagram of the 16F84A is shown in Figure 2.1 and its block diagram in Figure 2.2. A comparison of these figures with the equivalent ones for the PIC 12F508 in Chapter 1 shows some interesting similarities and differences. With 18 pins in play, there isn't the intense pressure to squeeze several functions onto each pin. Separate and dedicated pins are now provided, for example, for clock oscillator (pins 15 and 16) and Reset (pin 4 – MCLR). Nevertheless, compared to most, the ’F84A remains a small microcontroller.
Figure 2.1
The PIC 16F84A pin connection diagram
Figure 2.2
Block diagram of the 16F84A (supplementary labels in shaded boxes added by the author)
Architecturally there is clear similarity between the 12F508 and the 16F84A. In fact, the former is a direct subset of the ’F84A, with near identical CPU, memory, bus structure and counter/timer (TMR0) peripheral. Notice first, however, that the address bus sizes have been increased to meet the needs of the whole PIC mid-range family. As a smaller member of that family, the ’F84A doesn't fully exploit all these developments. The program address bus is now 13-bit and the instruction word size is 14-bit. Therefore, 213 (i.e. 8192) memory locations could be addressed. Program memory size, at 1K, is however only one eighth of this. The larger bus size will prove to be useful in the larger mid-range devices, as can be seen in the program memory size of the 16F876A and 16F877A (Table 2.1). RAM size has crept up cautiously to 68 locations and the stack to 8 locations.
A number of important new additions have appeared. The inclusion of an EEPROM memory gives the valuable capability of being able to store data values even when the chip is powered down. There are now two digital input/output ports. These are Port A, with five pins, and Port B, with eight. Importantly, there is the addition of an interrupt capability (which we explore in detail in Chapter 6). This can be seen externally on pin 6, where bit 0 of Port B is shared with the external interrupt input. We will also see that there are three further internal interrupt sources, generated by the peripherals.
Overall, we have a microcontroller that, while only modestly more complex than the 12F508, has proved incredibly diverse and useful in small applications.

2.2.1. The Status register

The result of any CPU operation is held in the Working register, but this does not necessarily tell everything about the operation that has just occurred. What if, for example, the 8-bit range has been exceeded in an addition instruction, for example by adding binary numbers 1000 0000 and 1111 1101? The Working register has no way of indicating this and would simply hold an incorrect result. Therefore, a set of logic bits, sometimes called ‘condition code’ flags, is built into any computer CPU. These are used to carry extra information about the result of the instruction most recently executed, for example whether the result is zero, negative or positive. For the 16F84A, these flags are held in the Status register, shown in Figure 2.3. Only three of these Status register bits genuinely fall into the category of condition codes. These are bits 0 to 2, i.e. bits C, DC and Z. As the key to the figure shows, these indicate respectively whether a Carry or Digit Carry has been generated, or if the result is Zero. Their use is explored further in Chapter 4 and Chapter 5.
Figure 2.3
The 16F84A Status register

2.3. A review of memory technologies

In order to examine the memory capabilities of the 16F84A, and to work with embedded systems in general, it is important to have some knowledge of the characteristics of the memory technologies in use. A detailed survey can be found in Chapter 4 of Ref. 1.1. The following section gives just a brief overview of the different memory technologies currently used by Microchip.
An ideal memory reads and writes in negligible time, retains its stored value indefinitely, occupies negligible space and consumes negligible power. In practice no memory technology meets all these happy ideals! In general, different technologies are strong in one or more of these characteristics and weaker in others. There is not one best memory technology, and different technologies are therefore applied for different applications, according to their needs.
Any memory is made up of an ‘array’ of memory ‘cells’, where each cell holds one bit of data. The characteristics of the single cell reflect the characteristics of the overall array; therefore, each technology is described here simply in terms of its cell design.

2.3.1. Static RAM (SRAM)

Here each memory cell is designed as a simple flip-flop, using two pairs of transistors connected back-to-back. Two further transistors allow the cell to connect into the main array. Data is held only as long as power is supplied. Hence the SRAM technology is volatile. With each cell taking six transistors, SRAM is not a high-density technology. However, if made from CMOS (Complementary Metal Oxide Semiconductor) it can be made to consume very little power, and can retain its data down to a low voltage (around 2 V). It has thus been a popular technology in battery-powered systems. SRAM is mainly used for data memory (RAM) in a microcontroller.

2.3.2. EPROM (Erasable Programmable Read-Only Memory)

In this technology each memory cell is made of a single MOS transistor – but with a difference. Within the transistor there is embedded a ‘floating gate’. Using a technique known as hot electron injection (HEI), the floating gate can be charged. When it is not charged, the transistor behaves normally and the cell output takes one logic state when activated. When it is charged, the transistor no longer works properly and it no longer responds when it is activated. The charge placed on the floating gate is totally trapped by the surrounding insulator. Hence EPROM technology is non-volatile. EPROM can, however, be erased by exposing it to intense ultraviolet light. This gives the trapped electrons the energy to leave the floating gate.
A special version of EPROM is OTP (One Time Programmable). Here the EPROM is packaged in plastic, without a window. Therefore, OTP can be programmed only once and never erased.
With a single transistor for a cell, EPROM is very high density and robust. Its requirement of a quartz window and ceramic packaging, to enable erasing, raises its price and reduces its flexibility. EPROM used to be integrated onto many microcontrollers for program memory, forcing the whole microcontroller to be ceramic-packaged with a quartz window (as seen in Figure 1.10). As a technology, EPROM has now almost completely given way to Flash, which follows shortly, but you may come across it in older systems.

2.3.3. EEPROM (Electrically Erasable Programmable Read-Only Memory)

EEPROM also uses floating gate technology. Its dimensions are finer, so that it can exploit another means of charging its floating gate. This is known as Nordheim–Fowler tunnelling (NFT). With NFT, it is possible to electrically erase the memory cell as well as write to it. To allow this to happen, a number of switching transistors need to be included around the memory element itself, so the high density of EPROM is lost.
Generally, EEPROM can be written to and erased on a byte-by-byte basis. This makes it especially useful for storing single items of data, like television settings or mobile phone numbers. Both writing and erasing take finite time, up to several milliseconds, although a read can be accomplished at normal semiconductor memory access times, i.e. within microseconds or less. Again, like EPROM, because the charge on the floating gate is totally trapped by the surrounding insulator, EEPROM is non-volatile. Because the EEPROM structure is now so fine, it suffers from certain wear-out mechanisms. Manufacturers usually therefore define a guaranteed minimum number of erase/write cycles that their memory can successfully undergo.

2.3.4. Flash

Flash represents a further evolution of floating-gate technology. With a single transistor per memory cell, it uses both HEI and NFT to allow electrical writing and erasing. It does not include the extra switch transistors that EEPROM has, so can only erase in blocks. It therefore returns to the exceptionally high density of EPROM. Like EEPROM, it has wear-out mechanisms, so cannot be written and erased indefinitely.
Apart from its inability to erase byte-by-byte, Flash is an incredibly powerful technology. It is now a central feature of a huge range of products, including digital cameras, ‘memory sticks’, laptop computers and microcontroller program memory.

2.4. The 16F84A memory

As Figure 2.2 shows, there are no less than four areas of memory in the 16F84A, as summarised in Table 2.2. Each memory has its own distinct function and means of access.
TABLE 2.2 16F84A memory features
Information obtained from full 16F84A data sheet [Ref. 2.1].
Memory functionTechnologySizeVolatile/non-volatileSpecial characteristics
ProgramFlash1K × 14 bitsNon-volatile10 000 erase/write cycles, typically
Data memory (file registers)SRAM68 bytesVolatileRetains data down to supply voltage of 1.5 V
Data memory (EEPROM)EEPROM64 bytesNon-volatile10 000 000 erase/write cycles, typically
StackSRAM8 × 13 bitsVolatile

2.4.1. Program memory and the stack

The 16F84A program memory map is shown in Figure 2.4. Looking at this diagram, we can see that it actually shows three things: the Program Counter, the Stack and the actual program memory. The three work inextricably together. The program memory is loaded with the program code that the microcontroller executes. The program is in the form of a list of instructions and the Program Counter holds the address of the next instruction that is to be executed by the microcontroller. Therefore, it acts as a pointer to program memory, as indicated in the diagram. We can see that the address range of the program memory is from 0000 to 03FFH. With its 13-bit Program Counter, the microcontroller can theoretically address a range from 0000 to 1FFFH. The extra address space is shown (in grey), although it is of no use here.
Figure 2.4
The 16F84A – program memory and Stack (supplementary labels in shaded boxes added by the author)
A ‘Stack’, in general computing terms, defines a particular type of temporary memory. Its main feature is that it is structured as a LIFO memory – last in, first out. Think of a pile of dinner plates in a small restaurant; the person drying the dishes keeps adding to the pile, while the waiter keeps taking dishes from the pile. Whenever the waiter takes a plate, he takes from the top, taking the last one that the dish-dryer has put there. This is the basis of a LIFO memory. Data words can be transferred to it (often called a ‘push’ to stack), and they can be taken from it (often called a ‘pop’ from stack). Whatever is ‘popped’ is always the last word to have been pushed there. That word is effectively removed from the stack, and the next most recent one will be popped next, unless another push occurs. In some microcontrollers the programmer can control the Stack. In the 16 Series microcontrollers it is under automatic hardware control, only. Here, the value of the Program Counter can be moved onto the Stack. This occurs when either a subroutine or an interrupt occurs. The instructions indicated in the diagram, CALL, RETURN, RETFIE and RETLW, all relate to subroutines and interrupts. We will meet them in the coming chapters – don't worry if they have no meaning to you at present!
The very first location in the program memory is labelled the ‘reset vector’. When the program starts running for the first time, for example on power-up, the Program Counter is set to 0000. Therefore, the first memory location that it points to is the reset vector. The programmer must therefore place his/her first instruction at this location. The ‘peripheral interrupt vector’ acts in a similar way for interrupt service routines, as we shall see in Chapter 6.

2.4.2. Data and Special Function register memory (RAM)

The RAM memory map is shown in Figure 2.5. The memory area is ‘banked’, and is divided into two important areas. The first is the general-purpose data memory, which occupies locations 0CH to 4FH. Above that are the Special Function registers (SFRs). Let us explore the two concepts just mentioned, as they are likely to be unfamiliar.
Figure 2.5
Data memory and Special Function register map of the 16F84A (supplementary labels in shaded boxes added by the author)

‘Banked’ addressing

A problem with any memory space is that the larger the memory is, the larger the address bus must be. One way of avoiding big address buses is to divide the memory into a number of smaller blocks – called banks – each identical in size. Now a smaller address bus can be used. It can access all banks in an identical way, with just one of the banks being identified at any one time as the target of the address specified.
PIC microcontrollers adopt a banked structure for their RAM, with the 16F84A having just two banks. The address of either bank is the 7-bit RAM address (‘RAM addr’) seen in Figure 2.2. The active bank is selected by bit 5 in the Status register (Figure 2.3). The programmer must ensure that the bank bit in the Status register is correctly set before making any access to memory.

Special Function registers

The SFRs are the gateway to interaction between the CPU and the peripherals, and we will get to know them very well. To the CPU, an SFR acts more or less like a normal memory location – you can usually write to it or read from it. What makes it ‘special’ is that the bits of that memory location have a dual purpose. Each bit is wired across to one or other of the microcontroller peripherals. Each is then used either to set up the operating mode of the peripheral or to transfer data between the peripheral and the microcontroller core. As we get to know the peripherals of the 16F84A, we will get to know each of the SFRs shown in Figure 2.5. Note that four SFRs appear in Figure 2.2. Can you identify what they are?

RAM addressing

Figure 2.2 shows that there are two possible sources of the RAM address, selected through the address multiplexer (‘Addr Mux’). One possibility is that the address forms part of the instruction and is routed across to the address multiplexer from the Instruction register. This is called ‘direct’ addressing. Alternatively, the address is taken from the File Select Register, or FSR, which can be found as one of the SFRs in Figure 2.5. If the user loads an address into the FSR, that can then be used as an address to data memory, a technique known as ‘indirect’ addressing. This will be described in Chapter 5.
The actual memory addresses are shown in Figure 2.5, labelled as ‘file address’. These addresses, at least in the right-hand column, appear to be 8-bit. We know, however, from Figure 2.2, that the RAM address bus is only 7-bit, or only 5 valid bits if direct addressing is used. It is important to understand that the addresses shown are made up of this 7-bit RAM address, with the bank select bit from the Status register inserted as the eighth, most significant, bit. When programming it is necessary to separate the two, ensuring that the MSB in Figure 2.5 is used for the bank select bit. This will become clear as we start to program.

2.4.3. The Configuration Word

A special part of the 16F84A program memory is its ‘Configuration Word’ (Figure 2.6). This allows the user to define certain configurable features of the microcontroller, at the time of program download. These are fixed until the next time the microcontroller is programmed. This is distinct from those many selectable features, like the setting of SFRs, which are under normal program control. While the Configuration Word is part of program memory, it is not accessible within the program or in any way while the program is running. The actual features it controls, which can be read on the diagram, are explained in this and later chapters.
Figure 2.6
16F84A Configuration Word

2.4.4. EEPROM

The EEPROM is non-volatile and is particularly useful for holding data variables that can be changed but are likely to be needed for the medium to long term. Examples include TV tuner settings, phone numbers stored in a cell phone or calibration settings on a measuring instrument.
In the 16F84A (and indeed any PIC microcontroller), the EEPROM is not placed in the main data memory map. Instead (as the top right of Figure 2.2 neatly shows) it is addressed through the EEADR register and data is transferred through the EEDATA register. These are both SFRs, seen in Figure 2.5.
As the earlier review of memory technology suggests, reading from EEPROM is a simple process but writing to it is not. The latter takes significant time in electronic terms (i.e. milliseconds) and care must be taken to avoid accidental writes. A set of controls is therefore required to start the process and (for write) to detect when it is ended. These are found in the bits of the EECON1 register; see Figure 2.7. To read an EEPROM location, the required address must be placed in EEADR and the RD bit set in EECON1. The data in that memory location is then copied to the EEDATA register and can be read immediately. To write to an EEPROM location, the required data and address must be placed in EEDATA and EEADR respectively. The write process is enabled by the WREN (Write Enable) bit being set high, followed by the bytes 55H followed by AAH being sent to the EECON2 register. The built-in requirement for these codes helps to ensure that accidental writes do not take place, for example on power-up or -down. The WR bit is then set high and writing actually commences. The write completion is signalled by the setting of bit EEIF in EECON1.
Figure 2.7
The EECON1 Special Function register (address 88H)

2.5. Some issues of timing

2.5.1. Clock oscillator and instruction cycle

Any microprocessor or microcontroller is a complex electronic circuit, made up of sequential and combinational logic. At fantastic speed it steps in turn through a series of complex states, each state being dependent on the instruction sequence it is executing. While the detail of this process is invisible to us, it is still necessary to provide the ‘clock’ signal, a continuously running fixed-frequency logic square wave. The overall speed of the microcontroller operation is entirely dependent on this clock frequency. It is not just the CPU that is dependent on the clock. In most microcontrollers many essential timing functions are also derived from it, ranging from counter/timer functions to serial communications. Furthermore, the overall power consumption of the microcontroller has a strong dependence on clock frequency, with high-speed operation being much more power-hungry than low-speed.
As Table 2.1 shows, every microcontroller has a specified range for its clock frequency. It is up to the designer to determine the clock frequency needed and to select a means of generating the clock source. With so many things depending on the clock frequency and its stability, these can be challenging decisions. These are taken further in Chapter 3.
Within any microprocessor, the main clock signal is immediately divided down by a fixed value into a lower-frequency signal. Each cycle of this slower signal is called either a ‘machine cycle’ or an ‘instruction cycle’. Microchip use the latter terminology. The instruction cycle becomes the primary unit of time in the action of the processor, for example being used as a measure for how long an instruction takes to execute. The original clock signal is retained to create phases or time stages within the instruction cycle. In PIC mid-range microcontrollers the main oscillator signal is divided by four to produce the instruction cycle time.
Table 2.3 gives some popular clock frequencies, with their resulting instruction cycle durations. For the fastest clock frequency, 20 MHz, the instruction cycle frequency is 5 MHz, with a period of 200 ns. The slightly cheaper version of the controller, the 16F84-04, with maximum clock frequency of 4 MHz, has at this frequency an instruction cycle time of 1 μs. As we will see, this unsurprisingly is a convenient value for a range of simple timing applications, using software delay loops and the counter/timer. A popular clock frequency for very low-power applications, including wristwatches, is 32.768 kHz. This has an instruction cycle period of 122.07 μs. The result is very low power, but strictly no high-speed calculations!
TABLE 2.3 PIC mid-range instruction cycle durations for various clock frequencies
Clock frequencyInstruction cycle
20 MHz5 MHz200 ns
4 MHz1 MHz1 μs
1 MHz250 kHz4 μs
32.768 kHz8.192 kHz122.07 μs

2.5.2. Pipelining

The combination of the RISC instruction set and the Harvard memory map used by PIC microcontrollers has an added advantage: instructions can be ‘pipelined’. Every instruction in a computer's program memory has first to be fetched and then executed. In many CPUs these two steps are done one after the other – first the CPU fetches and then it executes. If, however, program memory has its own address and data bus, separate from data memory (i.e. a Harvard structure), then there is no reason why a CPU cannot be designed so that while it is executing one instruction, it is already fetching the next. This is called ‘pipelining’. Pipelining works best if fetch and execute cycles are always of the same duration, such as a RISC structure gives. This fairly simple design upgrade gives a doubling in execution speed!
All PIC microcontrollers implement pipelining, which is one of the reasons for their comparatively high speed of operation. Each instruction is fetched while the previous one is being executed. Pipelining fails only for instructions that cause the value in the Program Counter to be changed, for example a program branch or jump. In this case, the instruction fetched is no longer the one needed. The pipelining process must then start again, with the consequent loss of an instruction cycle.
A diagram representing the pipelining process in mid-range microcontrollers is shown in Figure 2.8. Here we can see that while instruction 1 is being executed, instruction 2 is already being fetched, the same happening as instruction 2 is executed, and so on. An example sequence of instructions is shown to the left of the diagram. It is not, however, necessary to understand their meaning to understand the diagram, except to know that the CALL instruction causes a program branch. The instruction following it, instruction 4, is fetched while instruction 3 is being executed. Due to the program branch, however, instruction 4 is no longer needed, and a cycle has to be lost while the new instruction is fetched.
Figure 2.8
Instruction pipelining

2.6. Power-up and Reset

When the microcontroller powers up, it must start running its program from its beginning (i.e. for the 16F84A from its reset vector, seen in Figure 2.4). This will only happen if explicit circuitry is built in to detect power-up and force the Program Counter to zero. Along with this, it is also very useful to set SFRs so that peripherals are initially in a safe and disabled state. This ‘ready-to-start’ condition is called ‘Reset’. The CPU starts running its program when it leaves the Reset condition.
In the 16F84A there is a Reset input, (‘Master Clear’), on pin 4. this can be seen in Figure 2.1. As long as this is held low, the microcontroller is held in Reset. When it is taken high, program execution starts. If the pin is taken low while the program is running, then program execution stops immediately and the microcontroller is forced back into Reset mode.
There remains the question of when program execution should actually be allowed to start. The moment power is applied is a dangerous one for any embedded system. Both the power supply and the clock oscillator take a finite amount of time to stabilise, and in a complex system power to different parts of the circuit may become stable at different times. Clearly, this situation takes some careful handling. How can the start of program execution be delayed until power has stabilised?
A simple way to resolve the ‘what do we do as power is applied?’ question is shown in Figure 2.9 (a), illustrated here for any microcontroller which has an active low Reset input. If a resistor capacitor circuit is connected to the Reset input, then when power is applied the capacitor voltage rises according to the RC time constant, which can be made as big as is wanted. For a certain time, because it is rising comparatively slowly, the input is at Logic 0. Thus, the microcontroller can be held in Reset while its power supply stabilises and while the clock oscillator starts up.
Figure 2.9
External Reset circuits – generic microcontroller with Reset input. (a) Power-on Reset, simplest possible. (b) Power-on Reset, with discharge diode and protective resistor. (c) User Reset button
A small problem arises with this circuit if the power is switched off and then on again quickly (a cruel and challenging thing to do to any electronic device). With the circuit of Figure 2.9 (a) the capacitor wouldn't have time to discharge and the Reset condition might not be properly applied when power is applied again. More dangerously, the capacitor voltage might exceed the voltage supplied to the microcontroller and excessive current could then flow from the capacitor into the input. By adding a simple discharge diode, as shown in the circuit in Figure 2.9 (b), we can ensure that the capacitor discharges more or less at the same rate as the VDD supply. The resistor RS is also included to limit current into the input if the capacitor voltage does inadvertently exceed the voltage supplied to the microcontroller or another fault condition occurs.
If the designer wishes to include a Reset button, then the circuit of Figure 2.9 (c) can be applied. This is particularly useful for prototype circuits, where a large amount of testing is expected. Then it is convenient to be able to reset a program that may have crashed. R is a pull-up resistor, whose value can be in the range 10−100 kΩ. In a commercial device it is usually not desirable to have a Reset button; the aim here is to design the product so that reset by the user is never needed.
One of Microchip's goals is to minimise the number of external components needed for their microcontrollers, and the components of Figure 2.9 fall exactly into this category. Therefore, the 16F84A includes some clever on-chip reset circuitry, which in many situations makes the components of Figure 2.9 (a) or (b) unnecessary. A Power-up Timer is included on-chip, which can be enabled by the user with bit 3 of the Configuration Word (Figure 2.6). The 16F84A detects that power has been applied and the Power-up Timer then holds the controller in Reset for a fixed time. Once this is over the microcontroller leaves Reset and program execution begins. Using this Timer, the circuit of Figure 2.9 (b) need only be applied if the supply voltage rises very slowly. The Power-up Timer, and further details of the internal Reset circuit, are covered in greater detail in Section 2.8.
So what should be done with the 16F84A input if we don't want to make use of it? It is essential to recognise that this input must not just be left unconnected. The simplest thing to do is to tie it to the supply rail and then forget about it.

2.7. Taking things further – the 16F84A on-chip reset circuit

Let's take a closer look at the 16F84A on-chip reset circuitry, shown in simplified form in Figure 2.10. This takes some understanding, but it is worth doing.
Figure 2.10
The 16F84A reset circuitry
The actual reset to the CPU, , is generated by a flip-flop, which appears to the right of the diagram. This has two inputs, S (Set) and R (Reset). The CPU enters Reset mode when goes low, which is caused by the S line going high. It stays there until the flip-flop is cleared, caused by the R line going high.
So what causes a reset? The S input to the flip-flop goes high, via a three-input OR gate, if any of the following goes high:
• External Reset, from the line, as we have already seen.
• Time-out Reset, from the Watchdog Timer (WDT); this is designed to occur if a program crash occurs – the details are given in Chapter 6.
• Power-on Reset, output of the circuit that detects power being applied (‘VDD Rise Detect’).
Once any of these occurs, the flip-flop is set, the line goes low and the PIC microcontroller is held in Reset.
The line returns to 1 (and the PIC microcontroller is enabled) if the R input to the flip-flop is activated. The three requirements to be satisfied here, determined by the inputs to the associated AND gate, are that both power supply and oscillator have stabilised, and that any demand for Reset has been cleared. The first two of these requirements are achieved by two interesting timers, the Power-up Timer (PWRT) and the Oscillator Start-up Timer (OST). The Power-up Timer can be enabled by setting its bit in the Configuration Word (Figure 2.6). The Oscillator Start-up Timer is enabled via the Enable OST line. This is set automatically by the user oscillator setting in the Configuration Word, which enables it for all oscillator modes except RC. The Power-up Timer is clocked by its own on-chip RC oscillator, and when enabled counts 1024 cycles of its oscillator before setting its output to 1. This time duration turns out to be around 72 ms. This is long enough for the average power supply to have stabilised, though is not enough for a slowly rising supply. Once the Power-up Timer has completed its count, the Oscillator Start-up Timer is then activated, which in turn counts 1024 cycles of the main oscillator signal. This tests for a reliably running clock oscillator – if the oscillator isn't running, then of course it can't count. The outputs of both counters, and the inverse of the S input to the flip-flop, are ANDed together to form the R input to the flip-flop. If all lines are high, i.e. both counters have completed their count and there is no demand for a Reset, then the flip-flop is cleared. The CPU accordingly leaves the Reset condition and starts running.
The reset sequence just described is shown in Figure 2.11 for the common situation of being tied to VDD. Try to follow this, relating it to Figure 2.10. The application of power is seen in the rise of the VDD trace, which brings the line with it. This change is detected, as seen in the change of state of the ‘internal POR’ line. This in turn triggers the Power-up Timer, which runs for a period TPWRT. When TPWRT is up, the Oscillator Start-up Timer, whose time delay is TOST, is activated. Notice that TOST depends on the main oscillator running successfully and also on its frequency. For a 4 MHz oscillator, it will be 1024 × 250 ns, or 256 μs. When TOST is complete, the R line in Figure 2.11 goes high and the microcontroller leaves the Reset state.
Figure 2.11
Reset sequence on power-up, with MCLR tied to VDD


• The PIC mid-range is a diverse and effective family of microcontrollers.
• The 16F84A architecture is representative of all mid-range microcontrollers, with Harvard structure, pipelining and a RISC instruction set.
• The PIC 16F84A has a limited set of peripherals, chosen for small and low-cost applications. It is thus a smaller member of the family, with features that are a subset of any of the larger ones.
• The 16F84A uses three distinct memory technologies for its different memory areas.
• A particular type of memory location is the Special Function register, which acts as the link between the CPU and the peripherals.
• Reset mechanisms ensure that the CPU starts running when the appropriate operating conditions have been met, and can be used to restart the CPU in case of program failure.
2.1. PIC 16F84A Data Sheet (2001). Microchip Technology Inc., Reference no. DS35007B;
2.2. PICmicro Mid-Range MCU Family Reference Manual (1997). Microchip Technology Inc., Reference no. DS33023A;
2.3. PIC16F84 to PIC16F84A Migration (2001). Microchip Technology Inc., Reference no. DS30072B;
2.4. PIC 16F87/88 Data Sheet (2005). Microchip Technology Inc., Reference no. DS30487C;
1. From the 16F84A data sheet, Ref. 2.1, find out:
(a) how many read/write cycles each of EEPROM and Flash memory can be expected to undertake in their lifetime;
(b) the data retention duration for the EEPROM memory;
(c) the value of SFRs STATUS and PCL on power-up.
2. A non-technical friend asks you why his digital camera can ‘remember' pictures, and a mobile phone can ‘remember' numbers and text messages. In a simple way explain EEPROM and Flash program technology and their differences.
3. The pairs of numbers shown below are added in a 16F84A program. What is the result in each case and the value of the Status register bits Z, DC and C after each addition? 0101 1101 added to 0001 0011; 1110 1001 added to 0001 0111; 0001 0101 added to 0100 1001.
4. The Configuration Word of a 16F84A is read as 11 1111 1111 0010. Identify and explain the settings.
5. For a precise timing application, an instruction cycle time of 1.973 μs is required. What clock frequency will give this?
6. In a certain design, based on the 16F84A, the line is tied to the power supply. The clock oscillator is 8 MHz. The power supply rises nearly instantaneously. Both Power-up Timer and Oscillator Start-up Timer are enabled. How long is it before the microcontroller leaves the reset condition?