Program Execution
The program consists of a sequence of 14-bit codes, which contain both the operation code and operand in a fixed length instruction. This machine code program is derived from a source code program created as a text file on a host PC, assembled and downloaded, as detailed in Chapter 4. At the moment we are not too concerned about exactly how the downloading is carried out; all we need to know for now is that the program is received in serial form from the host PC via an input/output (I/O) port pin (RB7/PGD/ICSPDAT). The data transfer is controlled by a data clock signal on an adjacent pin (RB6/PGC/ICSPCLK), while a high programming voltage (14 V) is applied to !MCLR. A low-voltage programming option is also available, which eliminates the need for this high programming voltage. In-circuit serial programming (ICSP) can be carried out while the chip remains in circuit; the programmer module is then connected via a six-pin connector on the application board (see Figure 1.9). The PIC program memory is usually implemented as flash read memory (ROM), so an existing program can be replaced by simply overwriting with a new version.
Program Memory
The program counter register holds the current address, reset automatically to 0000 when the chip is powered up or reset. The user program must therefore start at address 0000, but the first instruction is often GOTO the start of the program at some other labeled address. This is necessary when using interrupts, as we shall see later, because the interrupt service routine (GOTO ISR) must be placed at address 0004. For now, we can place the start of the program at address zero.
The program counter consists of a pair of 8-bit registers. The program counter low (PCL) register holds the low byte of the current address, and the program counter high (PCLATH) register holds the high byte. In the original PIC 16 specification, the current address is fed to program memory from the program counter via a 13-bit address bus, so the high bits (5, 6 and 7) of PCLATH are unused, and the maximum program size accessible is 213 ¼ 8 k (see Appendix C).
Program memory capacity has been extended in more recent chips, using additional bits of PCLATH and a wider address bus. A maximum 64 k program instruction is possible with a 16-bit address. In normal operation, the PCL is incremented during each instruction cycle, and PCLATH incremented when PCL overflows (i.e. when PCL rolls over from 255 to 0). The memory space is therefore divided into pages of 256 instructions, the range addressed by the 8 bits of PCL. See Appendix C for details of memory sizing.
Instruction Execution
The program execution section of the MCU contains the instruction register, instruction decoder, and timing and control logic. The 14-bit instructions stored in program memory are copied to the instruction register for decoding; each instruction contains both the operation code and operand. The instruction decoder logic converts the op-code bits into settings for all the internal control lines. The operand provides a literal, file register address or program address, which will be used by the instruction.
If, for example, the instruction is MOVLW (Move a Literal into W), the control lines will be set up to feed the literal operand to W via literal data bus to the multiplexer and ALU. If the instruction is MOVWF, the control lines will be set up to copy the contents of W to the specified file register via the internal data bus. The operand will be the address of the file register (00 to 4F) required. If we look at the ‘move’ instruction codes quoted in the instruction set, we can see the difference in the code structure for the three move instructions:
In the MOVLW instruction, the operation code is the high 4 bits (1100), ‘x’ are ‘don’t care’ bits, and ‘k’ represents the literal bits, the low byte of the instruction. In the MOVWF instruction, the operation code is 0000001 (7 bits) and ‘f’ bits specify the file register address.
Only 7 bits are used for the register address, allowing a maximum of 27 ¼ 128 registers to be addressed. In the MOVF instruction the operation code is 001000, and the file register address is needed as before to identify the data source register. Bit 7 (d) controls the data destination. This bit must be 0 to direct the data into W, the usual operation. For example, to move an 8-bit data word from file register 0C to W requires the syntax MOVF 0C,W.
Data Processing
The arithmetic and logic unit (ALU) can add, subtract or carry out logical operations on single data bytes or pairs of numbers (see Chapter 2). These operations are carried out in conjunction with the data multiplexer and working register. The multiplexer allows new data to be fed from the instruction (a literal) or a register. This may be combined with data from W, or register data manipulated in a single register operation. W is used in register pair operations as a temporary data source or store, but the final result must usually be copied back into a file register, since W may be needed for the next operation.
Jump Instructions
If a GOTO instruction is executed, the program counter will be loaded with the program memory address of the jump destination given as the instruction operand. The program
label used in the source code will have been replaced by the destination address by the
assembler. For conditional branching (making decisions), any file register bit can be tested by a ‘Bit Test & Skip’ instruction, which is then followed by a GOTO or CALL instruction.
When a CALL instruction is executed, the destination address is loaded into the PC in the same way as for the GOTO, but in addition, the address following the CALL is stored on the stack, the return address. The subroutine is then executed until a RETURN instruction is encountered. At this point, the return address is automatically pulled from the stack and replaced in the PC, allowing program execution to pass back to the original point.
The stack works on a last in, first out (LIFO) basis, with the last address stored being the first to be recovered. In conventional processors, the stack can be modified directly as it is located in the main memory, but in the PIC16 this not possible.