P1    P2   P3    Disassembler

Soldering and using a prototype PC board
PIC12F629 Data Sheet (.pdf  4,926KB)
INSTRUCTION SET for PIC12F629
blank12F629.asm template
Library of Sub-routines "Cut and Paste
"
Library of routines:   A-E   E-P    P-Z 

WRITING A PROGRAM
Before starting to write a program, there are a number of things you need to know about laying it out.

Let's start:
Anything you write on the page is interpreted by an ASSEMBLER. The assembler will convert anything it understands to MACHINE CODE. Any comments you write on the page are placed after the ";" symbol.
A program is written in a set of columns. Anything in the first column is called a LABEL. If you leave more than 2 spaces, the next item is interpreted as an INSTRUCTION and the next column contains your comments ( ";" is needed before any comments).

Start by giving a name to the program, and revision number plus date.
the ;************************************ simply creates a separator.
The next line identifies the type of microcontroller.
#include <p12f629.inc>  The assembler will need to have this file in the same directory as the assembler program so it can identify some of the words you have used in your program.
See: <p12f629.inc>

The next line is the configuration code. It tells the assembler if you want the Code Protection ON or OFF, and other things such as Watchdog Timer, and Internal 4MHz RC Oscillator. The configuration line starts with double underbar "__"

NAMING THE FILES
One of the first things you will need to do is "list" or "name" or "equate" the files. This is the process of matching each file to a number, so the compiler can compile your program.

The PIC12F629 has 64 general purpose registers or files, starting at 20h (this is two-oh-hex) and is actually 32 files from the start: (1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,10h,11h,12h,13h,14h,15h,16h,17h,18h,1h,1A,1B,1C,1D,1E,1F)
20h.
The 64 files are:
20h,21h,22h,23h,24h,25h,26h,27h,28h,29h,2Ah,2Bh,2Ch,2Dh,2Eh,2Fh,30h,31h,32h,33h,34h
35h,36h,37h,38h,39h,40h,41h,42h,43h,44h,45h,46h,47h,48h,49h,4Ah,4Bh,4Ch,4Dh,4Eh,4Fh,
50h,51h,52h,53h,54h,55h,56h,57h,58h,59h,5Ah,5Bh,5Ch,5Dh,5Eh,5Fh.
These can be used to store values during the running of the program.
For instance, file 20h can be one of the files in the delay routine. We can call it delay1.
The next file can be delay2.
The next file is part of a tone routine, we will call it tone1
The next file is tone2.
These files are called "Variables" and are placed at the beginning of the program.
Each name such as delay1 has to be assigned to a file.
For instance, delay1 will be file 20h
delay2 will be file 21h  etc.
This process is called "equates."  You are equating a name to a file.

;**********************************************************************
;Equates
;**********************************************************************
delay1    equ   20h
delay2    equ   21h
tone1     equ   22h
tone2     equ   23h
 

Instead of writing the word "equ" for each file, there is a short-cut:
It is called "CBLOCK" - for "naming a block for the named constants."
The first line of the short-cut is: cblock and then a number that refers to the  beginning of the files for the block. The number: 0x20 is the same as saying 20h. The following cblock is the same as the above.
The short-cut ends:    "endc"

**********************************************************************
;Variables
;**********************************************************************            
cblock 0x20     ;20h is the first file of the General Purpose Registers
delay1
delay2
tone1
tone2
endc

Another method of defining our files allows 2 or more files with the same name. For instance, the following allows 3 flag files. These are identified as "flags," "flags+1," "flags+2,"  in your program. rand is identified as "rand"  and "rand+1" in your program. You can also identify similar names for files on the same line, such as: temp1, temp2.  In the following, 13 files have been identified and will be given the file numbers: 20h, 21h, 22h, 23h, 24h, 25h, 26h, 27h, 28h, 29h, 2Ah, 2Bh, 2Ch. To give a name such as "flags" more than one file, it is written flags:3 or flags:4 etc. It can also be written  flags1, flags2, flags3, etc.

;**********************************************************************
;File Register usage
;**********************************************************************
cblock 0x20   

count                 ; counter
flags:3                ; various flags
rand:2                ; random number
sensor                ; sensor reading
servo1, servo2     ; servo positions
speed1, speed2  ; motor speeds
temp1, temp2     ; timers

endc
 


The next statement is called START. It is the beginning of the program.
The program starts with the statement ORG  000 or ORG  0x000. Or you can make the ORIGIN of your program 0x004 or 0x34.
This tells the assemble to put the first instruction in the program at location 000 in the program memory, or at location 4 or at location 34hex. This is called a DIRECTIVE and is information for the assembler. The first instruction in our example is "goto SetUp" The sub-routine at SetUp, sets the port bits as IN or OUT. The port is actually a file and has the name GPIO (for General Purpose In Out) and is file 05. All files have 8 bits but only the lowest 6 bits of file 05 are used. These are called GPIO,0   GPIO,1   GPIO,2   GPIO,3  
GPIO,4   GPIO,5  
These can be called "lines" and any or all of them can be configured as input, but only  GPIO,0   GPIO,1   GPIO,2   GPIO,4   GPIO,5  
can be used at output as GPIO,3 (GP3) (pin 4) is an INPUT-ONLY pin.  To get a pin to "work," two things must be done. Firstly the micro must be told if the pin is to be an input or output and them it must be made HIGH or LOW if it is an output pin. Any pin can be changed at any time during the running of a program but it is normal to set up the pins in Set-Up if they are not going to be altered. We discuss setting up the "lines" a little further down the article.

Set-Up is placed at the 7th program location. There is a reason for this. Location 04 is where the microcontroller will return when it is "interrupted." For instance, it may be asleep, and is waiting for one of the inputs to change state. The microcontroller can be programmed to go to location 04 after an interrupt and the instructions at 04 will be carried out. We will leave three lines for three instructions, at 04, 05, 06.  Location 07 is now available for your program.



At the end of SetUp, the microcontroller goes to Main.
Main is always located at the end of your program and all the subroutines are placed before Main, in alphabetical order. This allows you to easily find each sub-routine.
Any tables are placed before the sub-routines.
Here is how the program is laid out:

;**********************************************************************
; SPINNING SIGN  Colin Mitchell  rev 2    19-9-2007
;**********************************************************************
list      p=12f629
#include <p12f629.inc>

; Set configuration register for:
; Code protection off
; Code protection DATA off
; Brown-out detect off
; MCLR disabled (use pins for InOut)
; Watch Dog timer disabled
; Power on reset delay enabled
; Enable Internal Clock Osc, (all pins for InOut)
;

__CONFIG   _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF
           & _WDT_OFF &  _PWRTE_ON & _INTRC_OSC_NOCLKOUT

;**********************************************************************
;Variables
;**********************************************************************            
cblock 0x20     ;20h is the first file of the General Purpose Registers
delay1
delay2
tone1
tone2
endc

;**********************************************************************
;Start
;**********************************************************************

ORG     0x000             ; processor reset vector
goto    SetUp              ; go to "setting up the port as In-Out etc"

ORG    0x004
nop                             ; processor goes here after interrupt
nop                             ; nop = no operation = 1 cycle
nop

SetUp  
instruction goes here
instruction goes here

goto Main

;**********************************************************************
;Tables
;***********************************************************************


;**********************************************************************
;Sub-routines
;***********************************************************************



Main
instruction goes here
instruction goes here

end


SETTING UP THE "LINES':
The "lines" are the input/out pins or "lines."
These are called GPIO,0   GPIO,1   GPIO,2   GPIO,3   GPIO,4   GPIO,5  
Any or all of them can be configured as input, but only  GPIO,0   GPIO,1   GPIO,2   GPIO,4   GPIO,5   can be used at output as GPIO,3 (GP3) (pin 4) is an INPUT-ONLY pin.  
The first thing to do is work out which pins are needed to be input and output. An input pin will be given the value "1" for Input and  "0" for output. Two instructions are needed, are are highlighted:

bsf         STATUS,rp0
movlw     b'00110111'
movwf    TRISIO

bcf         status,rp0

These instructions must be placed between two instructions: bsf   STATUS,rp0  and
bcf    status,rp0     so your instructions are placed in the chip at a special location. These instructions are placed in a file (or register) called the TRISIO file.
The movlw     b'00110111' instruction is a binary number that directly represents each line you want to make input or output. The chip has only 6 lines so the instruction is really:

movlw     b'xx110111' as the two highest bits do not have a corresponding line. They can be 0 or 1 as they have no effect.
The lowest line is called "line 0" or "bit 0" or "GPIO,0" and to make it an input we place a '1' as follows: b'xx - - - - - 1'  To make it an output:  b'xx - - - - - 0'  We have already said GPIO,3 is  INPUT-ONLY so the instruction starts:  b'xx - - 1 - - -' Once you have worked out if each line is to be input or output, the next decision is to make an output line HIGH or LOW.
(If you make an input line high or low, it does not have any effect on the line. It will only function at detecting the voltage applied to it from the outside world.)
To make an output line HIGH, one or two instructions are needed, depending how it is done.
To make any or all the lines HIGH, this can be done with two instructions. This is called "Byte Setting" as the whole byte is acted on in a single operation:

movlw     b'00110111'
movwf    GPIO


If you want to make a line HIGH, you can use "Bit Setting:"

bsf        GPIO,0

You cannot set more than one bit at a time, the micro does not like the following:

bsf        GPIO,0     ;This makes the lowest line go HIGH
bsf        GPIO,2


To set more than one line at a time, read: 
The In/Out Port.

                 
                  ;blink12F629.asm
                  ;This program will blink a LED connected to pin 7 
                  ;17-9-2007


       list p=12F629      ;microcontroller identity
                                ;  0x033 or 33h = hex value
        include "p12f629.inc"

       __CONFIG    _MCLRE_OFF & _CP_OFF & _WDT_OFF &
                     _INTRC_OSC_NOCLKOUT   

;**********************************************************************
;Variables
;*************************************************************************







fileA
fileB
fileC



pin7
pin6
pin5
pin4
pin3
pin2


Start








SetUp















Del

DelX







Main
equ 20h
equ 21h
equ 22h
equ 23h
equ 24h
equ 25h

equ 26h
equ 27h
equ 28h



equ 0
equ 1
equ 2
equ 3  
equ 4
equ 5


org      0x0000
nop
nop
nop
nop
nop
nop
nop


bsf         STATUS,rp0
movlw     b'10000110' 
movwf     OPTION_REG
movlw     b'00110111'
movwf    TRISIO
movlw   0x07 
movwf   CMCON



call        0x3ff
movwf    OSCCAL
bcf         status,rp0
clrf         GPIO  
goto       Main
   
movlw    40h
movwf    fileC
decfsz   fileA,1
goto      DelX
decfsz   fileB,1
goto      DelX
decfsz   fileC,1
goto      DelX
retlw     00


bsf        GPIO,pin7
call       Del
bcf        GPIO,pin7
call       Del
goto     
Main

org       0x3ff
retlw   0x20

END
;this is the first available file






;delay file A
;delay file B
;delay file C

; bits on GPIO

;GP0  output to LED
;GP1
;GP2
;GP3
;GP4
;GP5


;program starts at location 000
;"org" = tells the assembler to start at this address.


;NOPs to get past interrupt address




;Bank 1
;Turn off T0CKI, prescaler for TMR0 = 1:128

;Set GP0 (pin 7) as output

;turn comparator off
; comparator off =111

;calibrating the internal oscillator

;get the calibration value
;calibrate oscillator
;bank 0
;Clear GPIO of junk. This is file 05.


;Delay 0.5 sec

; ,1 denotes the result of the decrement
;     is placed in the file






;turn on LED

;turn off LED


;OSCCAL calibration value
 

THE TEMPLATE LAYOUT:
The template above consists of 6 different areas:
The first area contains the CONFIGURATION values.
The second area contains the "equates" or "variables."
The third area contains the SET UP instructions
The fourth area contains all the sub-routines. These are placed in alphabetical order, so you can easily find them when the program gets lengthy.
The fifth area contains the MAIN routine.
The last area sets the calibration value for the oscillator and the "end" instruction.

The micro will commence at location 000 and execute the Set Up instructions.
It will then go to Main.
In "Main" it will find instructions to "call" sub-routines and return. In this way it will constantly loop "Main" and use sub-routines as required.
If you keep to this form of layout, you will be able to follow programs written by others and be able to come back to your own programs and easily modify them.


Delay Routine
There are two ways to write a Delay Routine (and other routines). The program above uses instructions found in List of Instructions for PIC12F629. The following Delay Routine uses  "$+2" to advance the micro down the program:
 
Del

DelX








Del

DelX







 
movlw    40h
movwf    fileC
decfsz   fileA,1
goto      DelX
decfsz   fileB,1
goto      DelX
decfsz   fileC,1
goto      DelX
retlw     00



movlw    40h
movwf    fileC
decfsz   fileA,1
goto      $+2
decfsz   fileB,1
goto      $+2
decfsz   fileC,1
goto      DelX
retlw     00


 
;Delay 0.5 sec

; ,1 denotes the result of the decrement
;     is placed in the file










$+2 sends the micro to: goto $+2 below

$+2 sends the micro to: goto DelX

The Delay Routine above can be written with only one Label.
 


Del







 


movlw    40h
movwf    fileC
decfsz   fileA,1
goto      $+2
decfsz   fileB,1
goto      $+2
decfsz   fileC,1
goto     
$-5
retlw     00
 
;Delay 0.5 sec




$+2 sends the micro to: goto $+2 below

$+2 sends the micro to: goto goto $-5

$-5 sends the micro to: decfsz fileA,1

Creating 4 micro-second delay:
 










 


nop

nop
nop
nop

-----------------------

goto   $+1
goto   $+1
;Delay 4 micro-seconds

;1 uS
;1 uS
;1 uS
;1 uS

-----------------------------------------------------------------

;2 uS,  $+1 sends the micro to the next instruction
;2 uS,  $+1 sends the micro to the next instruction

 

SLEEP
To put the micro to sleep, a number of things must be done. This routine allows the micro to go to SLEEP when it comes to the SLEEP instruction. The micro wakes up from sleep when it detects a change on GPIO,5 (pin 2).  Pin 2 must have a pull-up resistor for the following program to work and a push-switch to create the change on the pin. The pull-up resistor can be external (about 47k) and a push switch to take the pin low to take the micro out of SLEEP.
Or, to turn on the weak internal 47k pull-up resistor, place the following instructions in SetUp:

      bsf    STATUS,RP0                          ; Sel Bank 1
      bcf    OPTION_REG,NOT_GPPU      ; enable weak pull-up
      bsf    WPU, 5                                  ; enable wpu on GPIO 5 only
      bsf    IOC, 5                                    ; enable Int-On-Change GPIO 5
      bcf    STATUS,RP0                         ; Sel Bank 0

In a sub-routine, place the following instruction:

      goto   sleep             ; goto sleep.

The following sub-routine is suitable to create a sleep condition:
 
Sleep




 
movf     GPIO,W



bcf       INTCON,GPIF
bsf       STATUS,RP0
movlw   0xFF
movwf   TRISIO
sleep
nop
movlw   b'11101000'
movwf   TRISIO
bcf       STATUS,RP0
movf     GPIO,W
bcf       INTCON,GPIF
; Read GPIO clears Int-On-Change flag. Must read
; into W not back to F as it reads port not the output
; latch which may result in output data being
; inadvertently altered.

; Sel bank 1
; Setup W for TRISIO all input
; Write to TRISIO. Reduce power in sleep mode
; Go to sleep
;
; Wake from sleep and set
; TRISIO for input and output for your project
; Sel Bank 0
; Read GPIO register
; and clear GPIF flag in interrupt register

CREATING A MACRO
Suppose you want to create an instruction the assemble does not understand, such as:
 

             movlf   0A0h,sensor  

In the instruction above you want to move the value A0h into file 26h (by referring to the list above:
 

count                 ; counter
flags:3                ; various flags
rand:2                ; random number
sensor                ; sensor reading

count will be allotted file 20h, flags will be allotted file 21h, flags+1 will be give 22h, flags+2 will be give file 23h, rand will be 24h, rand+1 will be 25h and sensor will be 26h.
But the assembler does not have an instruction of the above. It requires two instructions:
 

             movlw      0A0h
             movwf      sensor

Creating your own instructions for the assembler is called a "macro."
To tell the assembler how to handle an instruction in which the value 0Ah (called a "constant" or "literal") is to be moved to file 26h (the "sensor" file), a macro can be written to allow any "literal" to be written to any "file:"
 

movlf       macro      n,f         ; move literal to file
              movlw       n
              movwf       f
              endm

When the assembler sees the instruction:  movlf   it looks to see if a macro has been produced. The instructions in the macro are then added to the program (called the "source").

The macro is written with a label in the first column. The word "macro" is then written to tell the assembler the next instructions are "macro instructions." On the same line we write the parameters that will be used in the macro. The macro ends with "endm."


START HERE
If you will want to burn a chip and make sure it works in a test circuit. To help you, we have written a simple program, called "blink12F629.asm". This will blink a LED on Pin 7.
The circuit for this is:

 


Click .asm and .hex  for blink12F629.asm  files.

                 
                  ;blink12F629.asm
                  ;This program will blink a LED connected to pin 7 
                  ;17-12-2005


       list p=12F629      ;microcontroller identity
                                ;  0x033 or 33h = hex value
        include "p12f629.inc"

       __CONFIG    _MCLRE_OFF & _CP_OFF & _WDT_OFF &
                     _INTRC_OSC_NOCLKOUT               ;Internal osc.
 








fileA
fileB
fileC



pin7
pin6
pin5
pin4
pin3
pin2


Start








SetUp















Del

DelX







Main

equ 20h
equ 21h
equ 22h
equ 23h
equ 24h
equ 25h

equ 26h
equ 27h
equ 28h



equ 0
equ 1
equ 2
equ 3  
equ 4
equ 5


org      0x0000
nop
nop
nop
nop
nop
nop
nop


bsf         STATUS,rp0
movlw     b'10000110' 
movwf     OPTION_REG
movlw     b'00110111'
movwf    TRISIO
movlw   0x07 
movwf   CMCON



call        0x3ff
movwf    OSCCAL
bcf         status,rp0
clrf         GPIO  
goto       Main
   
movlw    40h
movwf    fileC
decfsz   fileA,1
goto      DelX
decfsz   fileB,1
goto      DelX
decfsz   fileC,1
goto      DelX
retlw     00


bsf        GPIO,pin7
call       Del
bcf        GPIO,pin7
call       Del
goto     
Main

org       0x3ff
retlw   0x20

END
; globals
;this is the first available file






;delay file A
;delay file B
;delay file C

; bits on GPIO

;GP0  output to LED
;GP1
;GP2
;GP3
;GP4
;GP5


;program starts at location 000
;"org" = tells the assembler to go to this address.


;NOPs to get past interrupt address




;Bank 1
;Turn off T0CKI, prescaler for TMR0 = 1:128

;Set GP0 (pin 7) as output

;turn comparator off
; comparator off =111

;calibrating the internal oscillator

;get the calibration value
;calibrate oscillator
;bank 0
;Clear GPIO of junk. This is file 05.


;Delay 0.5 sec

; ,1 denotes the result of the decrement
;     is placed in the file







;turn on LED

;turn off LED


;OSCCAL calibration value
 

 


 

 

 

 

 


YOUR FIRST PROGRAM:
We are now ready to start writing a program.
You will need the INSTRUCTION SET for the PIC12F629
Below is the blank12F629.asm template:

The instructions for your program are arranged in three columns.
The first column contains the "labels." They identify the address of the first instruction for a sub-routine.
The second column contains the "instructions" - called the mnemonics. The "half-computer" "half-English" instructions that both computer and micro understands.
The third column contains the "comments." It must have a ";" before each line so that they are not assembled - so they don't appear in the final .hex file!

Click .asm and .hex  for "blank12F629.asm"  files. The .asm file is used by your compiler (MPASM) to produce a .hex file for your ICProg burner program.

                 
                ;blank12F629.asmm
               
;Template for PIC12F629 microcontroller   17-12-2005
                ;CONFIG defines internal oscillator, code-protection OFF, pin 4 is GP3,
                ;     watchdog timer OFF.


       list p=12F629      ;microcontroller identity
                                ;  0x033 or 33h = hex value
        include "p12f629.inc"

       __CONFIG    _MCLRE_OFF & _CP_OFF & _WDT_OFF &
                     _INTRC_OSC_NOCLKOUT               ;Internal osc.
 








fileA
fileB
fileC



pin7
pin6
pin5
pin4
pin3
pin2







Start







SetUp












Del_1

DelX







Main

equ 20h
equ 21h
equ 22h
equ 23h
equ 24h
equ 25h

equ 26h
equ 27h
equ 28h



equ 0
equ 1
equ 2
equ 3  
equ 4
equ 5







org      0x0000
nop
nop
nop
nop
nop
nop


call        0x3ff
bsf         STATUS,rp0
movwf    OSCCAL
movlw     b'10000110' 
movwf     OPTION_REG
movlw     b'00001000'
movwf    TRISIO
bcf         status,rp0
clrf         GPIO  
goto       Main   



movlw    40h
movwf    fileC
decfsz   fileA,1
goto      DelX
decfsz   fileB,1
goto      DelX
decfsz   fileC,1
goto      DelX
retlw     00


your instruction goes here
your instruction goes here
your instruction goes here
call Del_1
your instruction goes here
your instruction goes here
your instruction goes here
goto Main



org       0x3ff
retlw   0x20

END
; globals
;this is the first available file






;delay file A
;delay file B
;delay file C

; bits on GPIO

;GP0 
;GP1
;GP2
;GP3
;GP4
;GP5

    
;***************************************************
;* Start of program *
;***************************************************


;program starts at location 000
;"org" = tells the assembler to go to this address.


;NOPs to get past reset vector address



;get the calibration value
;Bank 1
;calibrate oscillator
;Turn off T0CKI, prescaler for TMR0 = 1:128

;Set GP0's as output, GP3 = input.

;bank 0
;Clear GPIO of junk




;Delay_1  0.5sec

; ,1 denotes the result of the decrement
;     is placed in the file
















;OSCCAL calibration value

 

BURNING YOUR PROGRAM
The first program you will burn will be "blink12F629.asm"
Open Notepad.exe or Unzip Notepad.zip in our Programming folder on the left-side of the screen and load it with the blink12F629.asm file by sliding it into Notepad. It will then show in Notepad.
You can now make any changes to the program.
Save the result in a folder called PIC12F629Pgms (programs).
To burn blink12F629.asm into a PIC12F629, you will need to assemble the .asm file in MPASM to create a .hex file. To do this, place MPASM in a folder (or unzip MPASM.zip in the folder) and create a shortcut to desktop.
Click on MPASM on your desktop and it will open.
Locate blink12F629.asm in PIC12F629Pgms folder and load it into MPASM.
Use:
 Radix: Default,  Warning Level: Default, Hex Output: Default,  Generated Files: Error File and List file,  Do not tick: Case Sensitive, Macro Expansion: Default, Processor PIC12F629,  Tab Size: 8, Tick: Save settings on exit.
Click: Assemble.
Your blink12F629.hex file will be put into the same folder.
To burn a PIC12F629, you will need the Multi Chip Programmer. Make sure the programmer is the latest version with 628 on the underside of the PCB.
Connect it to your computer via the serial cable supplied in the kit and the green LED will illuminate.
Install IC Prog on your desktop or unzip IC Prog.zip
Click on the folder on the top left-hand side and locate Expt-1.hex
Make sure you have selected PIC12F629 before loading the .hex file.
The configuration settings will be automatically set according to the configuration value supplied in the program - or you can change anything before burning the new program.
Fit a chip into the programmer and click on the "lightening" icon.
The programmer will now burn the program into the chip. The LEDs on the Multi-Chip Programmer will show the action taking place.
When the chip is "burnt," place it in the socket on the project and the LED will flash.
This might seem a lot of work to create a simple effect, but the same amount of work will produce a compete project - it's just the size of the program will be different.

WRITING YOUR PROGRAM
Writing a program consists of creating small routines called sub-routines.
The basic layout of a program has already been shown above.
It is now a matter of creating subroutines that perform a function.
When these are executed at high-speed, the program performs a task.
The most interesting subroutines carry out an operation that appears to have "intelligence."
These type of subroutines can be found in a game, where the player is pitted against the computer.
The basics behind an "intelligent" sub-routine is simple. You simply provide an answer for ALL the possible combinations.
When this sub-routine is executed in the program, it creates the illusion of intelligence.
This type of sub-routine is interesting and challenging to create.
There are a number of very common games played with matches and marbles or markers, that can be converted to a program.
Once you master the technique of writing a sub-routine that solves a problem, all other routines will be easy to create.
 

HERE ARE SOME PROGRAMMING HINTS:
Before we start, the PIC12F629 has only 5 output lines and this prevents it from directly driving a 7-digit display. We have designed a project called 2-Digit Counter that shows how to expand the outputs to drive the displays.

1. Indirect Addressing

One of the things you may want to do is access a list of values from a table.

A number of files can be addressed by a sub-routine and the information can be moved into each file or read from each file. The files must be a group.
Suppose we have 8 files and need to read the contents and output it to a display. 
The files are:  21h, 22h, 23h, 24h, 25h, 26h, 27h, and 28h. 
There are two special files that allow a sub-routine to be created to look at the 8 files and read the contents. 
They are: INDF and FSR
The INDF file is not a real file. It is like a Robot Arm. It reaches down the list of files and picks up the contents or delivers the contents of a file to the programmer. The file it reaches is determined by the value in FSR. 
FSR is loaded with the address of the file you wish to read or write. 
This arrangement has an advantage. By loading FSR with a value, you can reach a file and by incrementing FSR, you can reach the next file etc. 
If you load a value into INDF, you will actually load the value into the file pointed to by FSR.
If you read INDF, you will actually read the contents of the file pointed to by FSR. 
You can consecutively read 8, 10 or 20 files or clear 20 files or load into 20 or more files with a simple looping sub-routine. It's a very powerful feature. 
The following instructions put a value of 8Fh into file 21h. 




 
MOVLW 21h
MOVWF 04
MOVLW 8Fh
MOVWF 00
;Load W with start of 8 files
;Load 21h into FSR
;Put 8F into W
;Put 8Fh into file 21h
 

The animation below shows how the information passes to the files:


Using INDF and FSR 

 The following instructions put a value of 8Fh into files 21h, 22h, 23h, 24h, 25h, 26h, 27h and 28h. 






Loop1
MOVLW 08
MOVWF 20h
MOVLW 21h
MOVWF 04
MOVLW 8Fh
MOVWF 00
INCF 04
DECFSZ 20h
GOTO Loop1
RETLW 00
;8 loops of the program
;File 20h is the decrementing file
;Load W with start of 8 files
;Load 21h into FSR
;Put 8F into W
;Put 8Fh into file 21h
;Increment FSR to make INDF go to next file 
 

The following instructions read files 21h, 22h and 23h, and outputs to GPIO.




Loop1
 
MOVLW 03
MOVWF 20h
MOVLW 21h
MOVWF 04
MOVF 00,0
MOVWF GPIO
CALL Delay
INCF 04
DECFSZ 20h
GOTO Loop1
RETLW 00
;3 loops of the program
;File 20h is the decrementing file
;Load W with start of 3 files
;Load 21h into FSR
;Copy file 21h (or next file) into W
;Move W to output GPIO
;Show value on set of 3 LEDs
;Increment FSR to make INDF go to next file 
 


P1    P2   P3