previous | start | next


Introducing the PIC’84

Architecture

A microcontroller such as the ’84 is- by its nature- a complete computer on a chip. It has 1: a processor and 2: registers, as well as 3: program and 4: data memory. This makes it different from ‘mere’ CPUs which have only the processor and registers.

1: The PIC’84 has an 8-bit processor, and that’s all we need to know about it!

2: The 58 registers are the processor’s internal working storage. Referring to [PIC figure 4-2 The page, figure, and table numbers reffered to here come from an older version of the '84 datasheet which is available at http://www.piclist.com/images/piclist/30445B.PDF the current datasheet for the modern version of the '84 is available at microchip.com], you’ll see that some of these have names (STATUS, PORTB etc): these have special functions and we’ll examine them later. PORTA, for instance, contains the contents of one of the I/O ports, namely port A. There are 36 general purpose registers [now 68 in the 16F84A], and we can consider these as ours (as opposed to the processor’s special ones) and use them as our ‘scratch pad’.

3: The ’84 has 1K x 14 program memory: that means there are 1024 program locations, and each is 14 bits wide. You’ll see from [PIC fig 3.4.1] that the memory goes from 0000h to 03FFh: 03FFhex is 1023 in decimal so there are 1024 locations including 0000. The ‘14 bits wide’ part comes from the length of each instruction: look at any one in [PIC section 4.2] and you’ll see that each is 14 bits long. For instance, ADDLW is 11 111X kkkk kkkk : don’t worry about what this means, just count it! We’ll be using this memory extensively later on.

4: It has 64 bytes data memory, which is used for storage of, for instance, calibration values. We’ll look at the use of this EEPROM memory last in this booklet.

In addition, the device includes 5: four types of interrupt and 6: 13 I/O pins.

5: Interrupts are means of something preempting the program. A button press by an operator, could interrupt the program’s normal flow and cause some special treatment. We’ll examine the ‘84’s interrupt techniques later.

6: The use of the I/O pins is key to the use of a device like the ’84, since any process consists of 3 parts- the input to the process, the process itself, and the output. The ’84 has 13 pins configured as 2 ports: port A comprises 5 pins and port B has 8; and we’ll be using them later.

Instruction Set

There are 35 instructions in the PIC84 instruction set; all are 14 bits long, and consist of an opcode and operand/s. Basically, the opcode specifies what to do and the operand/s specify how or where. These instructions are split into 3 groups: byte-oriented, bit-oriented and literal & control. Later on we will use each and every one of these operations, firstly individually (usually trivially) and secondly with others in more meaningful scenarios.

For now, let’s look at one of the instructions. Concentrate more on the format thereof, rather than the function which we’ll see closely later. I’ve chosen the instruction ADDWF- see [PIC table 4.2]. In this tutorial, I have adopted the Courier font below for all coding examples. The syntax of this instruction is:

ADDWF f,d

and you’ll see this sort of look in many other instructions.

This is an appropriate time to introduce the working register: this is a special register (over and above those already mentioned) known as the W register, and it is where the arithmetic and logic unit (ALU) does the maths. Any instruction with the ‘W’ in the name acts on the working register. Generally, some other register is known as ‘F’ in these commands. So- almost intuitively- we can understand that the command ADDWF adds the working register to register F. But where is register F?

Have a look at [PIC fig 4-2]: each register (other than W, that is, which isn’t in the figure since it is a special one) is given a hexadecimal address. For instance, PORTA is 05h, TRISA is 85h and we could use one of the 36 GP registers between 0Ch and 2Fh like 3Ch. The ‘f’ in the command is a place holder for the actual address of the register F; remember there is no register F as such- it is a generic name for some register or other. So, we would code the instruction as:

ADDWF 3Ch,d

Well, not quite- what’s the ‘d’ for? It is the destination of the result, and you’ll see this in many operations. Depending on our needs at the time, we need to choose to put the result either back into the working register or register F itself. [PIC page 51] explains that ‘d’ may be 1 or 0: a 0 causes the result to go to W, and a 1 puts it in F. Finally, therefore, this command could be either of the following, depending on our needs:

ADDWF 3Ch,0 ; adds W to reg 3C, result to W

ADDWF 3Ch,1 ; adds W to reg 3C, result to 3C

Let’s get on with actually writing a simple program . . . .

A simple PIC’84 program

This sample program serves a number of purposes. Apart from showing how to use a few instructions, it also introduces a couple of the assembler concepts and will also show some simple simulator techniques. The program, simple.asm is presented below; I’ll walk you through it line by line.

"...tried to build it i got a cannot find .hex message when i looked closer 3 lines needed altering H'10' H'15' and H'08' needed changing to 0010h 0015h and 0008h then it worked perfectly"

Program 1: simple . asm

;simple.asm
;to demonstrate
the look & feel of a program
; and introduce some instructions & directives
;***************** setup *******************************
processor 16C84        ;processor type
org 0010h        ;origin of program in memory
w equ 0 ;in byte instructions, use w & f
f equ 1 ;instead of 0 & 1, it’s much clearer
my_reg_1 equ H’10’ ;position my 2 registers in file
my_reg_2 equ H’15’ ; map at h‘10’ &H‘15’

;***************** program ******************************
;all we're going to do, is load the accum (reg w) with
; some values and play around with some arithmetic in w
; and my_reg_1&2
    movlw H’08’   ;put value H’08’ into w register
    movwf my_reg_1  ;move contents of w to my_reg_1
            ; note- same as movwf 10h, since
            ; my_reg_1 and 10h are same thing
    movlw 32h   ;put 32h into w reg
    addwf my_reg_1,f ;add contents of w to that of my_reg_1
            ; answer goes into my_reg_1, due to f
    movlw 92h   ;put value 92h into w register
    movwf my_reg_2  ;move contents of w to my_reg_2
            ; note- same as movwf 15h, since
            ; my_reg_2 and 15h are same thing
    movlw 26h   ;put 26h into w reg
    subwf my_reg_2,w ;subtr w from my_reg_2
            ; answer goes into w
    end

Let’s examine this sample program. You should verify the following by finding each directive or instruction in the appropriate Microchip book:

In the part called ‘program’, we meet a number of ’84 instructions. Check the full descriptions in [PIC] if you like; we’ll be looking at them later, anyway.

Let’s assemble and run this program . . .
 
 

Using MPLAB to debug the program

This is a three step process: edit the source code, assemble it, and then run the simulator to see what happens. If you worked through the MPLAB tutorial, you will already know about the editing and assembling. I’ll assume you have and do, and so we can move to the simulation.

With sample .asm successfully assembled, and the editor being the only window open in MPLAB, single-step through the program (the footstep icon). Not too helpful- you see each line of the program being highlighted as it is activated, but that’s it.

So, let’s start to use a few of the simulator’s other facilities. I suggest you open the following other windows in MPLAB. They all serve similar purposes- namely to see what’s happening in the registers- but all implement differently. I found it useful to have them all open at once, to compare the implementations:

Window > File Register

This window lists the contents of all file registers from 00 to 2F- ie, it does not show those in the region 80 to 8B. As you step through the program, you will be able to see the hex contents of registers 10h and 15h change. Note that any register whose contents have just changed is shown in red- this goes back to blue on the next step (unless there’s another change of course).

Window > Special Function Registers

Here you can see the SFRs by name, rather than location which is what the previous window shows. The contents are shown in decimal, hex and binary.

Window > New Watch Window

This is your custom window into the registers, and it allows you to select which registers you want to monitor. All registers are available to choose, both SFRs and GPRs. When you choose New Watch Window, you are prompted with an input box and a down arrow. Click the arrow, and a list of all available registers appears: choose the one you want (eg, my_reg_1) and then OK. You’ll see the contents of the register displayed in the window. To add other registers you can either click in the watch window’s top-left-corner icon, and then choose Add Watch; or just press the Insert key (while the watch window is selected). You can save oft used combinations as .wat files, and then load them back later with Window > Load Watch Window.

A word of warning . . . Where did the list of register names to select from, come from? The SFRs are obvious: the MPLAB knows about them anyway. The others, like my_reg_1&2, come from the equ directives in your code, which is great. However, in our example, we have also used w equ 0 and f equ 1 although these are not intended as register names. However, they still appear in the list of possibilities. So what’s the problem- just don’t choose them you say. But don’t forget that w is a register: so now there are 2 w entries in the list, one was there all along (the working register), and we caused the other with the equ. Using either of them, causes a symbol not found error in your watch table, meaning that you cannot monitor the working register if you have declared a w equ in your code. Try it yourself, then comment the offending line out with a ;, re-assemble and try again. Now you can use the working register in the watch.

With these three windows, step through your program: you’ve now got some insight into what’s going on. Satisfy yourself that all is working to plan.

Pause to reflect

Where shall we go from here? Well, where are we now? We’ve looked at the architecture and instruction set briefly; we’ve created a simple program and examined the code to get the feel of it; we’ve edited & assembled this program; and we’ve seen some of the simulator’s facilities.

I think we should move on to look more fully at the instruction set. I know that [PIC] covers all the registers, flags, interrupts, timers and stuff before going on to the instructions, but I found this the better way.



previous | start | next

Questions: