0% found this document useful (0 votes)
161 views

Library of Routines

This document provides a library of subroutines for programming the PIC12F629 microcontroller. It includes over 70 subroutines organized alphabetically that cover common tasks like input/output, arithmetic, logic operations, and more. The subroutines can be copied and pasted from the provided "Copy and Paste" section into programs to simplify development. Instructions are provided on using the subroutines and ensuring correct operation.

Uploaded by

Laith Adhary
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
161 views

Library of Routines

This document provides a library of subroutines for programming the PIC12F629 microcontroller. It includes over 70 subroutines organized alphabetically that cover common tasks like input/output, arithmetic, logic operations, and more. The subroutines can be copied and pasted from the provided "Copy and Paste" section into programs to simplify development. Instructions are provided on using the subroutines and ensuring correct operation.

Uploaded by

Laith Adhary
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 56

Library of Routines

for PIC12F629
Nearly all these instructions also work with
PIC16F628. Just check on Port value(s) and
first available file.
see: Talking Electronics website
A-E   E-P    P-Z

See the article Start Here with PIC12F629 for helpful programming notes and a map of the
files.
The following is a list of sub-routines, ideas, and help for the PIC12F629.  They apply to any
project using the PIC12F629.
They can be put into your program and modified in any way -  to suit the input/output lines. 
The "Copy and Paste" version of these sub-routines can be found HERE.
Your program should be created on a template in a text editor such as NotePad, using
blank12F629.asm  as a starting layout.  It provides the correct layout and spacing. 
An unusual problem you may get is a failure to compile your program due to hidden
formatting/characters.  MPASM will not produce the needed .hex file if any problem exists in a
program but it will produce a .lst file containing the faults. If you open .lst and see unusual
mistakes, they will be due to hidden formatting characters. Simply retype all the wording
around the mistake (in the .asm file) and the program will compile.  Do not use EditPad as it
produces hidden characters.
To use the Library of Routines below, go to the NotePad set of "Copy and Paste" Routines 
and "Copy and Paste" them into your program in another NotePad, as needed. 
Additional sub-routines can be found in the PIC Programming Course. This is on the
subscription section of the website.

Make sure each sub-routine uses a file (a register) with a name (a hex number) that doesn't
clash with any other sub-routine you have created.
Make sure CALLs go to a sub-routine that has a RETURN (use retlw  00) to bring the micro
back to the correct pace in the program and create Labels that let you know what the sub-
routine is doing.
The following library is presented in alphabetical order. Using these sub-routines will get you
started very quickly and will assist you with 70% - 90% of a new project.  
Read through the entire library so you know what is possible.  
Simply think of a word or requirement, go to the word and read about it. Many of the sub-
routines are also available in the "Copy and Paste" section.
Paste them into your program and modify them to suit. The micro will take each instruction
and carry it out. Make sure you have a RETLW 00 that brings the micro back to Main.
Get each sub-section working correctly before adding more instructions. Gradually build up
your program and save it as a NEW NAME so it can be recalled if a major problem develops.
Do not save it as the previous name as MPASM will sometimes not assemble it (it will think it
has already been assembled and  - do nothing!!) and you will wonder why the improvements
do not work!!

Add a value to a File


The PIC12F629 does not have a single instruction to add a number to a file. Two instructions
are needed to carry out this operation.
Add MOVLW 0CCh ;Put CCh into W
ADDWF 2Eh,1 ;CC will be added to the contents of file "2E."

Add "bits" to a port - turn on bits or "lines."


This is handy when more than one output line needs to be turned on.

;suppose GPIO has bits 0, 1 and 2 HIGH and we need


;   to turn on bit 5
MOVLW 10h ;Put 10h into W - this is bit 5
IORWF GPIO,1 ;10h will be added to the contents of file "05."

alternately, bit 5 can be SET

   bsf  GPIO,5

If more than one line needs to be made "HIGH" or "LOW," at the same time, you need to use:

   movlw   xxh
   iorwf     GPIO,1

This is necessary as the PIC12F629 will fail to set two or more lines via the following
instructions:

   bsf   GPIO, 0
   bsf   GPIO, 2

The author has found the PIC12F629 will fail to set the second line.

Address a File
This means "to act on" or "work with" a file. It can be to "move a value into a file," "increment
a file," "decrement a file" or other similar operation.  Only files can be addressed (the
instructions in the program cannot be address or altered). The files we are talking about are
the "empty" files from 20h to 5F.  None of the program or the values in the tables can be
altered. The values in a table can be accessed and copied by a set of instructions covered in
CALL Table.
Typical addressing instructions are:

MOVWF 2A,0 ;Copy file 2A into W


DECFSZ 2A,1 ;Decrement file 2A
INCF 2A,1 ;Increment file 2A
INCF 2A,0 ;will put the increment of file 2A into W but file 2A will not alter!!

Addressing a Set of Files


A number of files can be used to store temporary data, such as the digits or letters of a score-
board. 
This is sometimes called a "scratchpad" or "scratchpad area."  The files should be sequential
to make programming easy. 
Suppose we have 8 files and need to address them with a simple sub-routine to output the
data to a display. The sub-routine is called INDIRECT ADDRESSING. See Indirect
Addressing.
ALL THE FLAGS AND BITS
Here are some of the common flags and bits.
For the other flags, see PIC12F629 Data Sheet (.pdf  4,926KB)

bank select: bsf 03,5 selects bank 1 - this is where the OPTION register is accessed.
  bcf 03,5 selects bank 0 - this is the normal programming area
carry 03,0 Test the carry bit:
btfss  03,0  ;skip if a carry-out of the most significant bit has  
                        occurred.
prescaler bsf  Option_reg,3 see: Watchdog timer
assigned to or: Option register is in bank 1
WDT bsf  81h,3
prescaler bcf  Option_reg,3 Timer0 is in bank 0
assigned to or:
Timer0 bcf  81h,3
GPIO file 05h see input/output port. "Setting the port bits HIGH or LOW"
TRISIO file 85h see "Setting the ports bits input or output"
Status file 03 Contains the carry, bank select and zero flags.
zero flag 03,2 zero flag is bit 2 of file 03 (the STATUS file)
zero bit 1 = The result of an arithmetic or logic operation is zero
0 = The result of an arithmetic or logic operation is not zero
You can look at bit 2:
btfss 03,2    ; skip if the zero bit is SET

AND - see also Mask


The AND operation will mask any or all the bits in a file. In this way you can "remove" any bit
or the upper or lower nibble etc.
The quickest way to perform the operation is as follows:
To mask (remove) the lower nibble, it is ANDed with F0h (written as 0F0h)
To mask (remove) the upper nibble, it is ANDed with 0Fh (can be written 00Fh)

Place the value (say countA) to be operated on, into w:


     movf      countA,w
     andlw    0F0h           ;only the upper 4 bits will be in w.

ARITHMETIC OPERATORS AND  PRECEDENCE


     - see also Pseudo Instructions

OPERATOR Example
Current/Return Program
$ goto $ + 3
Counter
( Left parenthesis 1 + ( d * 4)
) Right parenthesis (length + 1) * 256
! NOT (logical complement) if !  (a == b)
– Negation (2's complement) – 1 * length
~ Complement flags = ~ flags
* Multiply a=b*c

/ Divide a=b/c

% Modulus entry_len = tot_len % 16

+ Add tot_len  = entry_len * 8 + 1


– Subtract entry_len = (tot – 1) / 8
<< Left Shift flags = flags << 1

>> Right Shift flags = flags >> 1

>= Greater or equal if entry_idx >= num_entries

> Greater than if entry_idx > num_entries


< Less than if entry_idx < num_entries
<= Less or equal if entry_idx <= num_entries
== Equal to if entry_idx == num_entries
!= Not equal to if entry_idx ! = num_entries
& Bitwise AND flags = flags & ERROR_BIT
^ Bitwise EXclusive OR flags = flags ^ ERROR_BIT
| Bitwise Inclusive OR flags = flags | ERROR_BIT
&& Logical AND if (len == 512) && (b == c)
|| Logical OR if (len == 512) | | (b == c)
= Set equal to entry index = 0
+= Add to, set equal entry index += 1
–= Subtract, set equal entry index – = 1
*= Multiply, set equal entry index *= entry_length
/= Divide, set equal entry total  /= entry_length
%= Modulus, set equal entry index %= 8
<<= Left shift, set equal flags <<= 3
>>= Right shift, set equal flags >>= 3
&= AND, set equal flags &= ERROR_FLAG
|= Inclusive OR, set equal flags | = ERROR_FLAG
^= EXclusive OR, set equal flags ^= ERROR_FLAG
++ Increment i ++
–– Decrement i  – –

Beep see Tone


A Beep is a tone of short duration. 
Binary to HEX: see Decimal to Binary to HEX

Binary Hex and Decimal numbers


Any mixture of binary, Hex and decimal numbers can be shown in a program.
Binary numbers are presented as: 0b00000000'  or b'00000000'  or B'00000000' or
00000000b or b'0100' indicates the lowest 4.
Hex numbers are shown as:   0x2    or 0x0F (= fifteen)  or 0x3C or h'  or $ 
or <digits>h (must begin with 0 ....9)
Decimal numbers are shown as:  d'250'  or decimal numbers without a prefix.

Button see Switch

bz    - branch on zero flag being set to "1"   See more instructions in "MACRO."
 

NewSw movf   Sw,0 ;Move file "Sw" to W


bz      timeout ;If Sw file is zero, the result of moving it to w (or to itself) will
xxxxxxx ;set the zero flag to "1" and the micro will goto "timeout."
yyyyyyyyy
 

timeout

CALL see also Stack


CALL means to branch to, and return from a subroutine. It does NOT mean GOTO. GOTO
means to branch unconditionally and maybe not return to the present routine. CALL means to
branch to another sub-routine and RETURN to the next address. Every CALL must have its
own RETURN or RETLW 00 to 0FFh statement.
Use only RETLW 00.   Do not use RETURN.
When a CALL instruction is executed, the next address-value is placed on the stack and the
micro goes to the location identified in the instruction.
Do not "GOTO" a sub-routine that has a RETURN at the end of it. The micro will not know
where to return as the GOTO instruction does not put a return address into memory (the
stack).
The CALL instruction works to the full 1024 locations in a PIC12F629 chip.

USING THE CALL INSTRUCTION


The micro will come to CALL Delay in the sub-routine below. It will then advance down the
program to Delay and carry out instructions until it reaches RETURN. The micro will then
move up the program to the xxxxxxxxx line. 

CALL Delay
xxxxxxxxx
--------
--------
--------

Delay MOVLW 80h ;Put 80h into W


MOVWF 2A ;Copy 80h into file 21A
DECFSZ 2A,1 ;Decrement file 21A
DelA GOTO DelA ;Loop until file 2A is zero
RETLW 00

CALL Table   see also Table and Output a Table Value 


The instructions CALL Table uses the value in W and adds it to the Program Counter (PC -
location 02 (file 02) - the ,1 indicates the value in W will be placed in the Program Counter
file) to create a JUMP VALUE to jump down a Table and pick up a value. The instruction
beside each value in a table places the value in W and makes the micro return to the
instruction after CALL Table. The next instruction should be to move the value from W to a
file.

Call MOVF 2A,0 ;File 2A contains 05. Move it to W


CALL Table ;W will return with 6D
MOVWF 2C ;Move 6D to file 2C

Table ADDWF 02h,1 ;Add W to the Program Counter to create a jump. 


RETLW 3Fh  
RETLW 06h
RETLW 5Bh
RETLW 4Fh
RETLW 66h
RETLW 6Dh
RETLW 7Dh
RETLW 07h
RETLW 7Fh
RETLW 6Fh

Carry  - see also ROTATE for one of the operations involving CARRY.
The carry bit is located in the STATUS register (file 03) and is bit 0. 
The carry bit is SET when the result of an operation is larger than 0ffh.
The carry bit is SET when the result of an operation is less than zero.
It is cleared by the instruction: 
BCF 03,0 - clear bit0 in file 03
Carry is SET by the instruction:
BSF 03,0   

To test the carry:


BTFSS 03,0
GOTO AAA     ;The micro will go HERE if the carry is NOT set.
GOTO BBB     ;The micro will go HERE if the carry is SET.
The carry is also used when a file is rotated left or right.
When a file is rotated left, the MSB (most significant bit (bit 7) is passed into the carry and the
carry-bit is passed into the file as bit 0. If you don't want the "carry bit" to affect the outcome of
the operation it must be cleared before-hand, thus:
       bcf      03,0

CBLOCK - (define a Block of Constants)


This is a directive used for defining files that will be reserved for an application. The format of 
CBLOCK is:

cblock 0x20 ;define the start of the files. The first "file" or "register" for a 12F629 is
20h
Lowbyte ;this will be file 20h
Medbyte ;this will be file 21h
Hibyte ;this will be file 22h etc  etc  etc
endc

This method of declaring variables is quite good, but macros cannot take advantage of it.

The alternative to cblock is:


Lowbyte equ 20h
Medbyte equ 21h
Hibyte equ 22h

cblock can use other files, starting at say 4Ch: The 3 files d1, d2 and d3 are files for a
delay routine and are files 4Ch, 4Dh and 4Eh.

cblock 0x4C
d1
d2
d3
endc

Another method of defining files is:

org   20h

save     ds   1
flag       ds   2
count    ds   1
csave   ds    1
temp    ds    2
  ontime  ds   1
oftime   ds   1
timer    ds    3
freq       ds    2
mode    ds   1
rate      ds   1
hi         ds   1
low       ds   1
delay    ds   3
 
The compiler will allow one file (20h) for "save" and two files for "flag." timer will be given 3
files.
When writing the program, you write the instruction such as incf flag,1 for the first flag file
and
btfss flag+1 for the second flag file.

Change Direction 
The direction of an input/output line (or a whole port) can be changed at any time during the
running of a program.  The file we are loading or setting or clearing is file 85. It is in Bank 1.
This file is called TRISIO.

BSF 03,5 ;Go to Bank 1


BSF TRISIO,1 ;Make GP1 input
  BCF 03,5 ;Go to Bank 0 - the program memory area.

BSF 03,5 ;Go to Bank 1


BCF TRISIO,1 ;Make GP1 output
  BCF 03,5 ;Go to Bank 0 - the program memory area.

See also: SetUp for setting up the Input/Output lines. See Input for the instruction(s) to make
a line Input. See Output to make a line Output. Lines are changed by setting or clearing bits
of the TRISIO register. This is called BIT MANIPULATION. This prevents touching (and
upsetting) other lines.

See Toggle to change the STATE of a line (from HIGH to LOW or LOW to HIGH). 

Compare
To compare two values, you can use XOR.
To compare two numbers, they are XORed together and if they are the same, the Z flag will
be set. Take two numbers: 

number  =  7A    =    0111 1010 


W         =  7A    =     0111 1010 

Starting at the right hand end, ask yourself the question, "Is one OR the other a 1?" The
answer is no. The next column. "Is one number OR the other a 1?" No BOTH the numbers
are 1! so that's why the answer is NO. In this way every column has the answer NO, when
both numbers match. 
When all the answers are Zero, the flag rises! to say the result is ZERO. In other words it is
SET. 
To find the zero flag look in the STATUS register, bit 2, i.e. File 03,2. 

e.g: To compare two files: 

                MOVF 2A,0           ;Move one file into W 


                XORWF 2B,0         ;XOR W and 2B 
                BTFSS 03,2           ;Test Z flag  If Z flag is SET (ie 1) the two files are the SAME! 

The same thing can be done by using the subtract operation:


                MOVF 2A,0           ;Move one file into W 
                SUBWF 2B,0         ;Subtract W from 1B 
                BTFSS 03,2           ;Test Z flag  If Z flag is SET (ie 1) the two files are the SAME! 

Same: Z flag is SET (ie 1) when the two files are the SAME!

Comparison
The contents of a file can be compared with the contents of the working register (W) to
determine their relative magnitudes. This is done by subtracting the contents of W from the
selected file. By testing the Carry and Zero flags, 4 results can be obtained: 
E.g: 

                MOVLW 22h          ;Put 22h in W 


                MOVWF 3C           ;Move 22h to file 3C 
                MOVLW 15h          ;Put 15h in W 
                SUBWF 3C,1         ;Subtract 15h from 22h 
                BTFSS 03,2           ;Test Zero flag 

OR 

                BTFSS 03,0           ;Test Carry flag 

Zero flag is SET if W = File value = Match 


Zero flag is CLEAR if no Match 
Carry flag is SET if a borrow did not occur (W is less than or equal to file value) 
Carry flag is CLEAR if a borrow occurred (W is greater than file value) 

(Put a value into W and perform SUBWF). Test Carry:


More than: Carry flag is CLEAR if W is greater than file value.
Less than: Carry flag is SET if W is less than or equal to file value.

Suppose a file (file 3E) is incremented to 8 such as in the Logic Probe with Pulser. We need
to know if the file is 1, 2 or 3. The first thing to do is eliminate the possibility of zero. 

TestA    MOVLW 00h          ;Eliminate file 3E if it is zero, 


             XORWF 3E,0         ;XOR file 3E with W
             BTFSC 03,2          ;Test the zero flag to see if file 3E is zero
             GOTO TestA1       ;File 3E is zero

The SUBWF operation below subtracts the W register (via a process called the 2's
complement method) from file 3E and the carry flag in the Option register (file 03) will be SET
if 3E is equal to W or more than W (i.e: 4 or more). 

             MOVLW 04            ;Put 04 into W for subtract operation


             SUBWF 3E,0          ;Carry will be set if 3E is = or more than 4
             BTFSS 03,0            ;Test the carry flag 
             GOTO Hi                ;Go to another sub-routine such as "Hi"

Here is the outcome for all the possibilities for file3E:


     If 3E = 0   C = 0  (we have eliminated the possibility of zero via the first 4 lines above)
     If 3E = 1   C = 0  (carry is zero - this is not the CARRY BIT it is the SET (1) or clear (0)
indicator)
     If 3E = 2   C = 0
     If 3E = 3   C = 0 (carry is clear)
     If 3E = 4   C = 1 (carry is set)
     If 3E = 5   C = 1
     If 3E = 6   C = 1
     If 3E = 7   C = 1
     If 3E = 8   C = 1

The carry bit in the Option file is bit 0.  Therefore we test bit 0 of file 03:
       BTFSS 03,0
The result in 3E can only be 1, 2, or 3. 

 Config  - configuration
The configuration word is located at address 2007h and is only accessed during
programming.
'__CONFIG' directive is used to embed configuration data within .asm file.
Note the double underbar at the front of "config."
Some of the configuration settings:
_CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _LVP_OFF
Each setting has a single underbar and a "&" sign, with a single space between "&" sign.

Here is an example of how the configuration word is created:

; ----- Configuration Word -----------


; Bandgap                 11                 Highest voltage (00 lowest voltage) for BOD and POR
; Unimplemented           000              Read as '0'
; Data code protection        1             CPD disabled (0=enabled)
; Code protection                 1            CP disabled (0 = program memory code protection
enabled)
; Brown-out detect                 1           BOD enabled (0=BOD disabled)
; GP3/MCLRE                         0          digital I/O, MCLR internally tied to Vdd
; Power-up timer                        1         PWRT disabled (0=PWRT enabled)
; Watchdog timer                        0        WDT disabled (0=WDT disabled)
; Oscillator                                   100     INTOSC I/O on GP4 & GP5
 
 __config                b'11000111010100'

Oscillator: 
000  = LP oscillator Low power crystal on GP4 and GP5
001  = XT oscillator  Crystal/resonator on GP4 and GP5
010  = HS oscillator  High Speed crystal/resonator on GP4 and GP5
011  = EC: I/O function on GP4  ClkIn on GP5
100  = INTOSC oscillator I/O on GP4 & GP5
101  = INTOSC ClkOut on GP4  I/O on GP5
110  = RC oscillator I/O function on GP4  RC on GP5
111  = RC oscillator ClkOut on GP4  RC on GP5

Count
If you want to count the number of pulses from a push-button or switch, the easiest way is to
increment a file. A file will hold up to 255. The result is stored as a hexadecimal number from
01 to FF.
If you want to count to three, pre-load a file with 3 and decrement it and detect zero.

 
 

Data Table - see DT below


 

Debounce a Button (Switch)


See Switch and Poll

Debug
This is not a term used in creating a program in PIC language, however we have two
suggestions for finding a "bug" or problem in a program. 
1. Go back to your previously saved version and note the differences in the programs. Try to
visually detect the fault. 
2. "Home-in" on the faulty section and see how far the micro is getting through by inserting a
Wait instruction. (See Wait)   A LED on an output line will illuminate to indicate the micro has
reached the instruction.    

Decimal, Hex and Binary numbers


Any mixture of binary, Hex and decimal numbers can be shown in a program.
Binary numbers are presented as: 0b00000000'  or b'00000000'  or B'00000000' or
00000000b or b'0100' indicates the lowest 4.
Hex numbers are shown as:   0x2    or 0x0F (= fifteen)  or 0x3C or h'  or $ 
or <digits>h (must begin with 0 ....9)
Decimal numbers are shown as:  d'250'  or decimal numbers without a prefix.

Decimal to Binary to HEX:

                     
0 0000 0000 0 16 0001 0000 10h 32 0010 0000 20h
1 0000 0001 1 17 0001 0001 11h 33 0010 0001 21h
2 0000 0010 2 18 0001 0010 12h 34 0010 0010 22h
0010
3 0000 0011 3 19 0001 0011 13h 35 23h
00110
4 0000 0100 4 20 0001 0100 14h 36 0010 0100 24h
5 0000 0100 5 21 0001 0101 15h 37 0010 0101 25h
6 0000 0110 6 22 0001 0110 16h 38 0010 0110 26h
7 0000 0111 7 23 0001 0111 17h 39 0010 0111 27h
8 0000 1000 8 24 0001 1000 18h 40 0010 1000 28h
9 0000 1001 9 25 0001 1001 19h 41 0010 1001 29h
10 0000 1010 A 26 0001 1010 1Ah 42 0010 0010 2Ah
0010
11 0000 1011 B 27 0001 1011 1Bh 43 2Bh
10110
12 0000 1100 C 28 0001 1100 1Ch 44 0010 1100 2Ch
13 0000 1101 D 29 0001 1101 1Dh 45 0010 1101 2Dh
14 0000 1110 E 30 0001 1110 1Eh 46 0010 1110 2Eh
15 0000 1111 F 31 0001 1111 1Fh 47 0010 1111 2Fh
                   

                 
48 0011 0000 30h 64 0100 0000 40h 80 0101 0000 50h
49 0011 0001 31h 65 0100 0001 41h 81 0101 0001 51h
50 0011 0010 32h 66 0100 0010 42h 82 0101 0010 52h
0101
51 0011 0011 33h 67 0100 0011 43h 83 53h
00110
52 0011 0100 34h 68 0100 0100 44h 84 0101 0100 54h
53 0011 0100 35h 69 0100 0101 45h 85 0101 0101 55h
54 0011 0110 36h 70 0100 0110 46h 86 0101 0110 56h
55 0011 0111 37h 71 0100 0111 47h   87 0101 0111 57h
 
56 0011 1000 38h 72 0100 1000 48h 88 0101 1000 58h
57 0011 1001 39h 73 0100 1001 49h 89 0101 1001 59h
58 0011 1010 3Ah 74 0100 1010 4Ah 90 0101 0010 5Ah
0101
59 0011 1011 3Bh 75 0100 1011 4Bh 91 5Bh
10110
60 0011 1100 3Ch 76 0100 1100 4Ch 92 0101 1100 5Ch
61 0011 1101 3Dh 77 0100 1101 4Dh 93 0101 1101 5Dh
62 0011 1110 3Eh 78 0100 1110 4Eh 94 0101 1110 5Eh
63 0011 1111 3Fh 79 0100 1111 4Fh 95 0101 1111 5Fh
                   

                     
96 0101 0000 60h 112 0111 0000 70h 128 1000 0000 80h
97 0101 0001 61h 113 0111 0001 71h 129 1000 0001 81h
98 0101 0010 62h 114 0111 0010 72h 130 1000 0010 82h
99 0101 0011 63h 115 0111 0011 73h 131 1000 00110 83h
100 0101 0100 64h 116 0111 0100 74h 132 1000 0100 84h
101 0101 0100 65h 117 0111 0101 75h 133 10000 0101 85h
102 0101 0110 66h 118 0111 0110 76h 134 1000 0110 86h
103 0101 0111 67h 119 0111 0111 77h 135 1000 0111 87h
104 0101 1000 68h 120 0111 1000 78h 136 1000 1000 88h
105 0101 1001 69h 121 0111 1001 79h 137 1000 1001 89h
106 0101 1010 6Ah 122 0111 1010 7Ah 138 1000 0010 8Ah
107 0101 1011 6Bh 123 0111 1011 7Bh 139 1000 10110 8Bh
108 0101 1100 6Ch 124 0111 1100 7Ch 140 1000 1100 8Ch
109 0101 1101 6Dh 125 0111 1101 7Dh 141 1000 1101 8Dh
110 0101 1110 6Eh 126 0111 1110 7Eh 142 1000 1110 2Eh
111 0101 1111 6Fh 127 0111 1111 1Fh 143 1000 1111 8Fh
                   

                 
144 1001 0000 90h 160 1010 0000 A0h 176 1011 0000 B0h
145 1001 0001 91h 161 1010 0001 A1h 177 1011 0001 B1h
146 1001 0010 92h 162 1010 0010 A2h 178 1011 0010 B2h
147 1001 0011 93h 163 10100011 A3h 179 1011 00110 B3h
148 1001 0100 94h 164 1010 0100 A4h 180 1011 0100 B4h
149 1001 0100 95h 165 1010 0101 A5h 181 11011 0101 B5h
150 1001 0110 96h 166 1010 0110 A6h 182 1011 0110 B6h
151 1001 0111 97h 167 1010 0111 A7h   183 1011 0111 B7h
 
152 1001 1000 98h 168 1010 1000 A8h 184 1011 1000 B8h
153 1001 1001 99h 169 1010 1001 A9h 185 1011 1001 B9h
154 1001 1010 9Ah 170 1010 1010 AAh 186 1011 0010 BAh
155 1001 1011 9Bh 171 1010 1011 ABh 187 1011 10110 BBh
156 1001 1100 9Ch 172 1010 1100 7Ch 188 1011 1100 BCh
157 1001 1101 9Dh 173 1010 1101 ADh 189 1011 1101 8Dh
158 1001 1110 9Eh 174 1010 1110 AEh 190 1011 1110 BEh
159 1001 1111 9Fh 175 1010 1111 AFh 191 1011 1111 BFh
                   

                     
192 1100 0000 C0h 208 1101 0000 D0h 224 1110 0000 E0h
193 1100 0001 C1h 209 1101 0001 D1h 225 1110 0001 E1h
194 1100 0010 C2h 210 1101 0010 D2h 226 1110 0010 E2h
195 1100 0011 C3h 211 1101 0011 D3h 227 1110 00110 E3h
196 1100 0100 64h 212 1101 0100 D4h 228 1110 0100 E4h
197 1100 0100 C5h 213 1101 0101 D5h 229 11100 0101 E5h
198 1100 0110 C6h 214 1101 0110 D6h 230 1110 0110 E6h
199 1100 0111 C7h 215 1101 0111 D7h 231 1110 0111 E7h
200 1100 1000 C8h 216 1101 1000 D8h 232 1110 1000 E8h
201 1100 1001 69h 217 1101 1001 D9h 233 1110 1001 E9h
202 1100 1010 6Ah 218 1101 1010 DAh 234 1110 0010 EAh
203 1100 1011 6Bh 219 1101 1011 DBh 235 1110 10110 EBh
204 1100 1100 CCh 220 1101 1100 DCh 236 1110 1100 ECh
205 1100 1101 CDh 221 1101 1101 7Dh 237 11100 1101 EDh
206 1100 1110 CEh 222 1101 1110 DEh 238 1110 1110 2Eh
207 1100 1111 CFh 223 1101 1111 DFh 239 1110 1111 EFh
                   

     
240 1111 0000 F0h
241 1111 0001 F1h
242 1111 0010 F2h
243 1111 0011 F3h
244 1111 0100 F4h
245 1111 0100 F5h
246 1111 0110 F6h
247 1111 0111 F7h
238 1111 1000 F8h
249 1111 1001 F9h
250 1111 1010 FAh
251 1111 1011 FBh
242 1111 1100 FCh
243 1111 1101 FDh
254 1111 1110 FEh
255 1111 1111 FFh
     

Decrement
To decrement a file, use the instruction: DECF 3A,1. This puts the new value back into the
file. Do not use DECF 3A,0 as the new value goes into W!
To decrement a file twice, use:
DECF 3A,1
DECF 3A,1
To halve the value of a file, the contents is shifted right:
RRF 3A,1- the file must not have a bit in bit0. 
A file can be decremented until it is zero:   
DECFSZ, 3A,1   
To decrement W we can use the instruction: addlw  -1  

Delay
A delay sub-routine is needed for almost every program. One of the main purposes is to slow
down the execution of a program to allow displays to be viewed and tones to be produced. 
The shortest delay is NOP. This is a "do nothing" instruction that takes 1 micro-second. 
You will need one million "NOP's" to produce a 1 second delay. 
This is impractical as the program space will only allow about 1,000 instructions. 
The answer is to create a loop. If a file is loaded with a value and decremented, it will create a
short delay. The two instructions: DECFSZ 3A,1 and GOTO DelA will take 3uS.    80h loops =
127 loops x 3 + 1 loop x 2uS  +  2uS on entry + 1uS on exit = 386uS      
Del MOVLW 80h ;Put 80h into W
MOVWF 3A ;Copy 80h into file 1A
DelA DECFSZ 3A,1 ;Decrement file 3A
GOTO DelA ;Loop until file 3A is zero
RETLW 00

A simpler delay routine below decrements a file with 256 loops. Each loop is 4uS and the
result is slightly more than 1,000uS = 1mS. The routine exits with 00h in the file. On the
second execution, the routine performs 256 loops - the file does not have to be pre-loaded. 
The longest delay (such as the one below) using a single file is approx 1mS.      

Del NOP
DECFSZ 3A,1 ;Decrement file 3A
GOTO Del ;Loop until file 3A is zero
RETLW 00
1mS delay

NESTED DELAYS
To produce delays longer than 1mS, two or more files are needed. Each file is placed around
the previous to get a multiplying effect. The inner delay produces 256 loops, the output file
produces 256 loops of the inner file. This results in 256 x 256 loops = 256mS.
The simplest delay decrements a file to zero. At the end of an execution, a delay contains 00
and this produces the longest delay, the next time it is used. 
This means a file does not have to be pre-loaded. 
The following is a two-file nested delay. The delay time is approx 260mS (say 1/4Sec): 

Del NOP
DECFSZ 3A,1 ;Decrement file 3A
GOTO Del ;Loop until file 3A is zero
DECFSZ 3B,1 ;Decrement file 3B
GOTO Del ;Loop until file 3B is zero
RETLW 00
260mS Delay

If you want a delay between 1mS and 256mS, you will need to pre-load file 3B. For each
value loaded into file 3B, a delay of 1mS will be produced. A 125mS delay is shown below:     

Del MOVLW 7Dh ;Load W with 125 for 125mS delay


MOVLW 3B
Del1 NOP
DECFSZ 3A,1 ;Decrement file 3A
GOTO Del1 ;Loop until file 3A is zero
DECFSZ 3B,1 ;Decrement file 3B
GOTO Del1 ;Loop until file 3B is zero
RETLW 00
125mS Delay 

A 0.5 second delay:

     ; Delay = 0.5 seconds = 500,000 cycles


     ; Clock frequency = 4 MHz

cblock 0x20    ;delay files d1, d2 and d3 are at 20h, 21h and 22h
d1
d2
d3
endc
Delay1 movlw     0x0B0h ;499994 cycles
movwf     d1
movlw     17h
movwf     d2
movlw     0x02
movwf     d3
Delay2 decfsz    d1, f
goto       $+2
decfsz    d2, f
goto       $+2 ;this sends the micro to: goto Delay2
decfsz    d3, f
goto       Delay2
goto       $+1 ;2 cycle instruction that advances the
goto       $+1 ; micro to the next instruction
goto       $+1 ; 2 more cycles
retlw      00                      checked 3-2-08

The goto $+2 instruction is a 2-cycle instruction that sends the micro 2-instructions down the
program. This instruction has two advantages. It provides a delay of 2 microseconds @4MHz
and saves creating a label.
In the decrementing section of the sub-routine (Delay2), the instruction: goto $+2  makes the
micro go to 2 instructions down the program. This is simply a new and novel way to produce a
delay routine.
The second goto $+2 sends the micro to: goto Delay2. The first instruction could have been
goto $+4 but this routine is designed to "waste" time and every instruction adds to the delay.

A 2 second delay:

     ; Delay = 2 seconds = 2,000,000 cycles


     ; Clock frequency = 4 MHz

cblock 0x20    ;delay files d1, d2 and d3 are at 20h, 21h and 22h
d1
d2
d3
endc
Delay1 movlw     0x11 ;1,999,996 cycles
movwf     d1
movlw     0x5D
movwf     d2
movlw     0x05
movwf     d3
Delay2 decfsz    d1, f
goto       $+2
decfsz    d2, f
goto       $+2 ;this sends the micro to: goto Delay2
decfsz    d3, f
goto       Delay2
goto       $+1 ;2 cycle instruction that advances the
goto       $+1 ; micro to the next instruction
retlw      00
Code generated by http://www.golovchenko.org/cgi-bin/delay

The following sub-routine will produce a delay of "X" minutes and "Y" seconds.
The following example make the micro wait EXACTLY 930,000,000 instruction cycles.
i.e: 15 minutes 30 seconds
Example:
movlw   0x0F                 ;This will produce 15 minutes. This the "X" value
call       _WAIT_1Min
movlw   0x30                 ;This will produce 30 seconds.  This is the "Y" value
call       _WAIT_1s
 

; The following delays are calibrated for operation at 4MHz


;
; OPERATION: Create a literal in W. This literal represents the
multiplier
; of the delay. Immediately call the function.
;
; Example:
; movlw 0x0F
; call _WAIT_1Min
; movlw 0x30
; call _WAIT_1s
;

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
cblock 0x20 - the names of the files below will start at file 20h
;......
minute
second
deci
milli
micro
;......
endc
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
_WAIT_1Min ; W * 60,000,000
movwf minute
movlw 0x3B ; 59 * 1,000,000
call _WAIT_1s
movlw 0x09 ; 9 * 100,000
call _WAIT_100m
movlw 0x63 ; 99 * 1000
call _WAIT_1m
movlw 0x63 ; 99 * 10
call _WAIT_10us
goto dec4 ; <= 59,999,996 cycles

NOP
goto $+1
goto $+1
goto $+1
movlw 0x3B
call _WAIT_1s
movlw 0x09
call _WAIT_100m
movlw 0x63
call _WAIT_1m
movlw 0x63
call _WAIT_10us

dec4
decfsz minute,F
goto $-0x0D - micro will go to "NOP" above
return
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
_WAIT_1s ; W * 1,000,000
movwf second
movlw 0x09 ; 9 * 100,000
call _WAIT_100m
movlw 0x63 ; 99 * 1000
call _WAIT_1m
movlw 0x63 ; 99 * 10
call _WAIT_10us
goto dec3 ; <= 999,996 cycles

NOP
goto $+1
goto $+1
goto $+1
movlw 0x09
call _WAIT_100m
movlw 0x63
call _WAIT_1m
movlw 0x63
call _WAIT_10us

dec3
decfsz second,F
goto $-0x0B
return
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
_WAIT_100m ; W * 100,000
movwf deci
movlw 0x63 ; 99 * 1000
call _WAIT_1m
movlw 0x63 ; 99 * 10
call _WAIT_10us
goto dec2 ; <= 99,996 cycles

NOP
goto $+1
goto $+1
goto $+1
movlw 0x63
call _WAIT_1m
movlw 0x63
call _WAIT_10us

dec2
decfsz deci,F
goto $-9 - micro will go to "NOP" above
return
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
_WAIT_1m ; W * 1000 cycles
movwf milli
movlw 0x63 ; 99 * 10?s = .99ms
call _WAIT_10us
goto dec

NOP
goto $+1
goto $+1
goto $+1
movlw 0x63
call _WAIT_10us

dec
decfsz milli,F
goto $-7 - micro will go to "NOP" above
return
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
_WAIT_10us ; W * 10cycles
movwf micro
goto dec5
NOP
goto $+1
goto $+1
goto $+1
dec5
decfsz micro,F
goto $-5
return

A delay can be created using the timers in the PIC12F629. Timer0 is 8-bit and is identified as:
tmr0       equ           H'0001'

Timer1 is 16 bit and can be used a two 8-bit timers:


tmr1L      equ           H'000E'
tmr1H      equ           H'000F'

(this is equal to three 8-bit timers)

No pre-setting-up is required. You can use them in place of a file.

           ;1 second delay using timer1L and timer1H

_1Sec
        movlw 05h
        movwf delC
        nop
        decfsz tmr1L,1
        goto                 $-2
       decfsz tmr1H,1
       goto                 $-4
       decfsz delC,1
       goto                $-6
       retlw                00

Detect a value
If a file has been incremented in a sub-routine you may want to know the value it contains. 
You may want to know its exact value or if it is higher or lower than a certain value. 
To see if it is an exact value, it is XORed with a known value. See XOR.
To detect a particular value, they are XORed together. See XOR. 
You can also detect a particular value by BIT TESTING. You must make sure that all the
numbers being tested can be distinguished by testing a single bit. For example: 1, 2, 4, 8, 10h
can be tested via bits 0, 1, 2, 3, 4. But if 3 is included in your requirement, you cannot test a
single bit.  

Different
To find out if two numbers are different, they are XORed together. See XOR

Divide
Simple division such as divide by 2 can be performed by the RRF instruction. Successive
RRF's will divide by 4, 8, sixteen etc. Other divisions are beyond the scope of this course. The
number cannot have a bit in bit0, if an accurate division is required.

DS   or ds
This term can be seen in some programs, as:

count     ds    2
sum      ds     1
dve        ds    3

It is the code for: "advances the load pointer by the specified value." 
Reserve the number of file locations. ORG must be set for this to work.
It simply allocates two locations for count, one for sum and three for dve    This allows the
programmer to produce files for:  count, count+1, sum, dve, dve+1, dve+2   

DT - Data Table
The DT directive (command) allows you to create a table without having to write:
      retlw  40h
      retlw  79h
      retlw  3Ah
      retlw  4Ch

For example:

SegTable  ANDLW 0Fh       ; convert a number in W to segment form


               ADDWF PCL,F

               DT     40h,79h,24h,30h,19h,12h,02h,78h,00h,10h


               DT     7Fh,7Fh,7Fh,7Fh,7Fh,7Fh

Will compile to:

SegTable  ANDLW 0Fh       ; convert a number in W to 7-segment form


               ADDWF PCL,F
               retlw  40h
               retlw  79h
               retlw  24h   etc
Double
To double the value of the contents of a file, it is shifted LEFT (RLF 3A,1).    The number must
be less than 80h. (it must not have a bit in location bit7).

EEPROM 
The PIC12F629 has 128 bytes of EEPROM, from 00h to 7F to permanently store data. 
If you need to store only a few bytes of data for a short period of time, use files that are not
required for the running of the program. This information will be lost when power is removed. 
The 128 bytes of EEPROM requires a special set of instructions to place data into EEPROM.
The actual writing time for this data is very long (in computer terms) and can be done in the
background, while the main program is executing. A flag will SET when the data has been
written and this will allow another byte of data to be entered. 
Each EEPROM cell can be written about 1 million times. 

Before reading a value in a location in the EEPROM, it must be loaded with a value during
"burning." To load the first location in EEPROM with a value, the following instructions are
placed in a program. The EEPROM starts at location 2100h and the term DE means: "define
EEPROM." There are 128 EEPROM locations and by following the layout in the second table,
any location can be addressed during burning.      

ORG 2100h   ;Starting point of EEPROM


DE 43h   ;First EEPROM location holds the value 43h
END

 The locations in EEPROM:

ORG 2100h   ;Starting point 


DE 84h, 16h, 23h, 80h, 0CAh, 32h, 7Bh, 0A2h  ;
DE 34h, 53h, 25h, 02h, 0FFh, 20h, 03h, 04h  ;
;for up to eight lines
END
 

READ EEPROM:
The sub-routine to read a value in the EEPROM is shown below.         

EERead bsf      Status, rp0  ;go to Bank 1


movlw  Config_addr  ;
movwf  EEADR ;address to read
bsf      EECON1, rd ;EE read
movf    EEDATA,0 ;move data to W
bcf      Status, rp0 ;back to bank 0
retlw   00  

 
WRITE TO EEPROM:
The sub-routine to write to EEPROM is shown below.             

EEWrite bsf        status,rp0 ;bank1


bsf        EECN1,WREN ;enable write
bcf        INTCON,GIE ;disable interrupts
molw     55h ;unlock write
movwf    EECON2 ;
movlw    AAh ;
movwf    EECON2 ;
bsf        EECON,WR :start the write
bsf        INTCON,GIE ;enable interrupts
bcf        Status,rp0 ;bank 0
retlw     00 ;Return

 
End
This is a directive, placed at the end of of program to tell the assembler to finish the job of
assembling the instructions into .hex code. The directive is:

      end

End of Table
The end of a table can be detected in two different ways.
If a value such as FF is not used in any of the data, it can be used as an End of Table
marker. The sub-routine calling the table must look for 0FFh to detect End of Table.

Table ADDWF 02h,1 ;Add W to the Program Counter to create a jump. 


RETLW 3Fh ;0    format= gfedcba
RETLW 06h ;1    
RETLW 5Bh ;2    
RETLW 4Fh ;3
RETLW 66h ;4
RETLW 6Dh ;5
RETLW 7Dh ;6
RETLW 07h ;7
RETLW 7Fh ;8
RETLW 6Fh ;9 
RETLW 0FFh ;End of table marker

The other method is to count the number of items in a table and make sure the sub-routine
calling the table doe not CALL values beyond this value.

Equal
To detect if two files are equal, they are XORed together. See XOR.

Equates   "equ"
Equates assign an easy to remember label to a numeric value. This value can be a file or bit
in a file.
e.g:
delay1  equ   20h    ;every time "delay1" is inserted into a program, the assembler will assign
file 20h.

in your program:

   movlw   80h
   movwf   delay1       ;the assembler will put 80h into file 20h

The in/out pins on a 12F629 are 2,3,4,5,6 and 7.


These are GP5, GP4, GP3, GP2, GP1 and GP0
These correspond to GPIO,5  GPIO,4  GPIO,3  GPIO,2  GPIO,1 and GPIO,0 in a program.
Suppose GPIO,3 is called "switch"   and GPIO,5 is called "LED" (it drives a red LED).
In the equates section of your program (at the top of your program) you can equate bit "3" of
the GPIO file as "switch and bit "5" as "LED."
The equates will appear as: 

switch    equ   3
LED       equ   5

in your program:

   btfss   GPIO,switch
or
   bsf     GPIO,LED

Error Message  302


If you get an error message when MPASM is compiling your program to a .hex file,  it will not
produce the .hex file.
To find the error messages, open the .lst file.
Some error messages are just a warning such as:

Message[302] myfile.ASM 136 :


Register in operand not in bank 0. Ensure that bank bits are
correct.

The above is a warning that you need to select the correct bank.
You can remove the warning message by inserting the following at the top of your .asm
program

ERRORLEVEL -302 ;remove messages

FSR See Indirect Addressing 


This is a special file called File Select Register. It has the address 04. It is not a file like the
other files in the micro but a POINTER FILE and is used in conjunction with another file called
INDF. 
INDF has the address 00. 
INDF is not actually a file but a robot arm. It grabs the contents (or delivers contents) to a file
pointed to by FSR. These are two special files (devices) that allow very powerful (low
instruction) programming to be produced.  
For instance, if FSR is loaded with 2C, it will tell INDF to grab (or deliver) contents to file 2C. 
To do this, we need the instructions:
MOVLW 2C
MOVF 04
If we now put 8Fh into INDF, the value will actually go into file 2C. 
This is called INDIRECT ADDRESSING.  

GOTO
The GOTO instruction causes the micro to go to the address identified by a label such as
"No" or "Yes."
 
BTFSS GPIO,0 ;Is button pressed?
GOTO No ;No
GOTO Yes ;Yes
No RETLW 00
Yes MOVLW  3Fh
etc

The instruction:    goto   $ + 2   

"$" means the current address.

"+ 2" means to advance two instructions down the program.


 

btfss GPIO,0
goto  $ + 2 ;this will end the micro to instruction y
instruction x
instruction y ;the micro will advance to this instruction
  instruction z ;the micro will never execute this instruction!!!!

To go "up" the program, the goto instruction is:


goto  $ –3
or
goto  $ –0dh
or     $ –.16   (minus decimal sixteen).  The instruction should be written without any gaps: 
$–.16

When writing a program, you must make sure the micro will get back to the "Main" routine.
If you use a "call" instructions such as:

    call   delay_1

make sure the sub-routine has:

    retlw   00

to get the micro back to "Main."

You cannot use the instruction:

    goto   delay_1

as the "retlw   00"  in the delay_1 routine will not take the micro back to "Main" as the return
address has not been remembered with a "goto" instruction.

You can also define a location by writing the LABEL (in this case "Step") and an offset - in this
case +1. The micro will go to  "movwf  tmr2."  This has an advantage. It is easy to see, rather
than writing $–4, when a large number of instructions are to be counted.
 

Step movlw     25
movwf     tmr2
btfsc       Sw2  
goto       newpress
  decfsz   Sw2,f
goto      Step+1
retlw      00

Halt
Do not use the word "Halt" as a label, the assembler does not like it. Use Loop, Pause, Stop,
Wait.  See Loop and Stop.

To create a "halt" instruction:

Loop         goto  $            This will cause the microcontroller to keep looping the same
instruction.

Halve (Half)
To halve (half - divide by two) the value of the contents of a file, it is shifted RIGHT (RRF
1A,1).    The number must be an even number (it cannot have a bit in bit0). 

HEX: see Decimal to Binary to HEX

Hex,  Binary and Decimal numbers


Any mixture of binary, Hex and decimal numbers can be shown in a program.
Binary numbers are presented as: 0b00000000'  or b'00000000'  or B'00000000' or
00000000b or b'0100' indicates the lowest 4.
Hex numbers are shown as:   0x2    or 0x0F (= fifteen)  or 0x3C or h'  or $ 
or <digits>h (must begin with 0 ....9)
Decimal numbers are shown as:  d'250'  or decimal numbers without a prefix.

Higher
To find out if a number is higher than a know value, a comparison is made. See
Comparison. 

Increment
To increment a file, use the instruction: INCF 2A,1. This puts the new value back into the file.
Using INCF 2A,0 puts the new value also into W!
To add two to a file, it can be incremented twice:
INCF 2A,1
INCF 2A,1
To double the value of a file, the contents is shifted left:
RLF 2A,1
A file can be incremented until it "rolls over to zero."  Normally a file is decremented to zero
and a skip occurs when it is zero. But the same effect can be produced by incrementing a
file: 
INCFSZ, 2A,1  
To increment W, use ADDLW, thus:  ADDLW  01   or  ADDLW 3Bh
 

Indirect Addressing 
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 ;Load W with start of 8 files
MOVWF 04 ;Load 21h into FSR
MOVLW 8Fh ;Put 8F into W
MOVWF 00 ;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. 

MOVLW 08 ;8 loops of the program


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

The following instructions read files 21h, 22h, 23h, 24h, 25h, 26h, 27h and 28h and outputs to
GPIO (file 05).  Output Port 05 has only 5 lines: GP0, GP1, GP2, GP4 and GP5. GP3 is
missing and this makes it difficult to display values from a file.

MOVLW 08 ;8 loops of the program


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

INDF See Indirect Addressing and FSR


This is a special file called INDirect File. 
INDF has the address 00. 
INDF is not actually a file but a robot arm. It grabs the contents (or delivers contents) to a file
pointed to by FSR. 
This is used in an operation called INDIRECT ADDRESSING.  

Input
The six bits of the in/out port GPIO can be made input or output by the value of the bits in a
file called TRISIO. GP3 can only be INPUT.
To make a line INPUT, the corresponding TRISIO bit must be "1."
To make a line OUTPUT, the corresponding TRISIO bit must be "0."
To make a line INPUT (or OUTPUT), the instructions must be placed inside BSF 03,5 and
BCF 03,5.
For example, to make the lowest line of GPIO, an INPUT, the following instructions are
needed:

BSF 03,5 ;Go to Bank 1


MOVLW 01 ;Load W with 0000 0001
MOVWF GPIO ;Make GP0 input
BCF 03,5 ;Go to Bank 0 - the program memory area.

The other individual lines are:


movlw 02         ;Load W with 0000 0010
movwf GPIO    ;Make GP1 input

movlw 04         ;Load W with 0000 0100


movwf GPIO    ;Make GP2 input
movlw 08         ;Load W with 0000 1000
movwf GPIO    ;Make GP3 input

movlw 10h       ;Load W with 0001 0000


movwf GPIO    ;Make GP4 input

movlw 20h       ;Load W with 0010 0000


movwf GPIO    ;Make GP5 input

To make more than one line (with a single instruction) an input, the hex values are added.

movlw 0F        ;Load W with 0000 1111


movwf GPIO    ;Make GP0, GP1, GP2, GP3 input

movlw 12h       ;Load W with 0001 0010


movwf GPIO    ;Make GP1, GP4 input

movlw 33h       ;Load W with 0011 0011


movwf GPIO    ;Make GP0, GP1, GP4, GP5 input

Port direction can be changed at any time during the running of a program. You must make
sure that any input or output devices on the line will not upset the running of the program.  
In this case it is best to SET or CLEAR a BIT. This involves setting or clearing an individual
bit. This prevents touching any other lines.
Eg: To make the lowest line of port B an input:

bsf 03,5 ;Go to Bank 1


bsf  GPIO,0 ;Make GP0 input
bsf  03,5 ;Go to Bank 0 - the program memory area.

Carry out instructions using the input line, then make the line an output:

bsf  03,5 ;Go to Bank 1


bsf  GPIO,0 ;Make GP0 output
bsf  03,5 ;Go to Bank 0 - the program memory area.

Jump 
There is no "jump" instruction, however the "jump command" is included in instructions such
as
decfsz,  btfsc, with the actual instruction meaning to skip or "jump over" the next instruction if
the file is not zero, or the bit is not clear.
The closest instruction is:  "goto"

Normally the micro advances down the program, one instruction at a time and reads each
instruction as it comes to it. If you want to jump down a program, you can add a number
(literal) to the Program Counter and the micro will carry out the command.
The instruction is:
   addwf  pcl,1
Suppose you need to go to one of 5 different sub-routines. This is done by placing a value in
"w:"
movlw  01,   or movlw 02,   movlw  03,   movlw 04,   movlw  05
then the instruction: addwf  pcl,1
To prevent a jump beyond the 5 "goto's, the instruction:    andlw 05h   is added here.

The next instructions will be:

nop                  ;this instruction is equal to:  "movlw  00"


goto   sub-1
goto   sub-2
goto   sub-3
goto   sub-4
goto   sub-5

Label 
This is the name given to each sub-routine. It is placed in the first column of your program
(called an assembly program).
Some names cannot be used as they are reserved by the assembler. Keep the length to less
than 8 letters. Do not use "-" or "/"  Use "_" to separate.
Here are some examples:
Alarm   Alarm_1   Beep   Button    Count   Dec   Delay   Display   Fast   Find   Flow   Halt  
HeeHaw   Inc   Look   Loop   Main   Send   Show   Siren   Sound    Sw   Switch   Table  
Table2  Table_3   Test  Try   Try_2    Toggle   Tone  Unit  

Less than  - see Comparison

Load a file
This operation cannot be done directly. A number (a value) is called a LITERAL. It is loaded
into W then the value in W is moved to a file. The two instructions are:

MOVLW 0FFh ;Load a value (called a Literal) (00 to 0FFh) into W


MOVWF 2A ;Move the value in W to a file

Look at an Input
There is no instruction called "look."  If a switch or button is connected to an input line such as
the lowest line on GPIO, the instruction is:

BTFSS GPIO,0 ;Is button pressed?


GOTO No ;No
GOTO Yes ;Yes

This assumes the switch is connected to the positive rail and the input goes HIGH when the
button is pressed. 
This instruction also works for a signal on line GPIO,1. You must make sure line GPIO,1 is an
INPUT via the SetUp routine. 
The two instructions after BTFSS GPIO,1 can be "GOTO Yes", "GOTO No"   by changing the
first instruction. The decision will depend on the number of instructions for the "Yes" or "No"
answer, as the instruction placed directly after BTFSS GPIO,1 must be a GOTO. 
BTFSC GPIO,1 ;Is button pressed?
GOTO Yes ;Yes
GOTO No ;No

Loop
The action of looping is carried out for a number of reasons. The micro does not have a Halt
or Stop feature and must carry out instructions at all times. A loop will hold the micro in one
place. 
To get out, a set of instructions such as "look" is needed inside the loop. These instructions
see if a button has been pressed etc. Alternatively, if the watchdog timer is SET, the micro will
come out of the loop and go to location 04. The instructions to create a loop are as follows: 

Loop NOP
GOTO Loop

To create a "loop" instruction:

Loop         goto  $            This will cause the microcontroller to keep looping the same
instruction.

Lower
To find out if a number is lower than a know value, a comparison is made. See Comparison. 

Macro
A Macro is similar to a sub-routine. You can call it from anywhere in a program. The aim of a
macro is to save lines of code.

Some assemblers have built-in macros and recognise abbreviations such as the following:
Do not use these instructions unless you know EXACTLY what you are doing.
fr = file register
For instance, we will explain the following instruction in the table below:
Branch on No Zero to addr     =     btfss   3, 2    goto addr.   (file 3, bit 2 is the zero flag)
Test the zero flag. Skip if it is set. In other words skip if the zero flag is set, but BRANCH if it is
not zero!
The normal instructions are as follows:
    btfss  3,2
    goto   tune1
    next instruction

alternately, you can use:


    bnz  tune1
    next instruction
 

Mnemonic Description Function


addcf fr, d Add carry to fr btfsc   3, 0   incf  f,d
subcf fr, d Subtract carry from fr btfsc   3, 0   decf  fr,d
negf fr, d Negate file register fr comf   fr, 1   incf  fr,d
b   addr Branch to addr goto    adddr
bz   addr Branch on Zero to addr btfsc   3, 2    goto addr
bnz   addr Branch on No Zero to addr btfss   3, 2    goto addr
bc   addr Branch on Carry to addr btfsc   3, 0    goto addr
bnc   addr Branch on No Carry to addr btfss   3, 0    goto addr
skpc Skip on Carry btfss   3, 0
skpnc Skip on No Carry btfsc   3, 0
skpz Skip on Zero btfss   3, 2
skpnz Skip on No Zero btfsc   3, 2
clrz   Clear Zero flag bcf    3, 2
setz  Set Zero flag bsf    3, 2
clrc  Clear Carry flag bcf    3, 0  
setc Set Carry flag bsf    3, 0  
tstf   fr Test file register fr movf  fr, f
decbnz fr,addr Decrement fr, if zero decfsz  fr  goto addr
branch to addr

A macro can be created to move a number (a literal) into a file, using a single instruction. This
normally requires two instructions:
    movlw  64h     ;put 64h into W
    movwf  2Ch    ;move 64h to file 2C

The single instruction we will create is:

   movlf  64h,2Ch  ;this instruction will put 64h into file 2C. (a macro must be included in the
program)

To create a macro for the instruction "movlf"    the following is placed at the top of your
program:

movlf   macro  literal,file    ;literal -> file


          movlw  literal
          movwf  file
          endm

When you write the instruction:  movlf  4Ah,2Fh     ;4A will be placed into file 2F.
 

Main
The Main routine is constantly looped and generally consists of sub-routines that are
CALLed.  

Main CALL Switch


CALL Display
CALL Beep
GOTO Main ;Loop Main
Mask - see also AND for a "2-instruction" code
If you want to remove a number of bits from a file, the operation is called MASKING. 
You can remove the high or low nibble (a nibble is a set of 4 bits) or any other bits. Any
number from 0 - 7 can be obtained by masking (removing) bits 3,4,5,6,7, and leaving only bits
0, 1 and 2.
To mask (remove) the upper nibble, the number is ANDed with 0F. To mask the lower nibble,
the number is ANDed with F0.  (this is written: 0F0h in the program)  

number: 1001 0111


W: 1111 0000
answer: 1001 0000
MOVLW 97h ;Put 97h into W
MOVWF 2A ;Move 97h into file 2A
MOVLW 0F0h ;put the "masking value" into W
ANDWF 2A,1 ;AND 97h with file 2A. The result will be in file 2A. 

More  than  - see Comparison

Move a file to W
The contents of a file can be moved to W with the following instruction:
MOVF 2A,0  The contents are actually COPIED. The original file still holds the contents. 

Move a file to another file


The contents of a file can be moved to another file via the following instructions. 
It is firstly copied to W then W is copied to the new file:

MOVF 2A,0 ;The contents of file 2A is copied to W


MOVWF 2B ;W is copied to file 2B

Multiply
Simple multiplication such as multiply by 2 can be performed by the RLF instruction.
Successive RLF's will multiply by 4, 8, sixteen etc. You need to be careful as this is called a
"blind" operation. 
A number such as 80h (128) will not be doubled as 1000 0000 will be moved to the left and
the top bit will be passed to the Carry. Only numbers up to 7F (127) can be doubled. 
To multiply by 2:

  RLF 2A,1 ;The contents of file 2A is doubled

To multiply any two numbers together requires a program. Since the PIC12F629 does not
have any multiply function, it is carried out by successive ADDITIONS. A number from 01 to
255 can be multiplied by 01 to 255. 
To multiply 75(4Bh) by 122(7A), 122 is added to a file 75 times. It needs two files to hold the
answer.

CLRF 2B ;Clear the receiving file


CLRF 2C ;Clear the receiving file
MOVLW 7Ah  ;122
MOVWF 2A,1 ;file 1A holds 122
MOVLW 4B  ;75
M1 ADDWF 2B,1 ;ADD 75 to file 2B
BTFSS 03,0  ;Test Carry bit in status
GOTO M2  ;file. CLEAR = no carry
INCF 2C,1  ; SET = carry
M2 DECFSZ 2A,1
GOTO M1
RETURN

The result is a 16 bit binary number of the form: file 2C, file 2B  = 0000 0000 0000 0000
To multiply two numbers and obtain a decimal result requires a different program. 

Nested Delay
See Delay 

Origin  -  ORG
This is a pseudo instruction (also called a directive) that tells the assembler where to place
the next instruction.   ORG must have a value. For ORG 000, the real instruction will be
placed at memory location 000.
For ORG 2Ch, the first instruction in Main will be placed at address location 2Ch as shown
below:
 

ORG 000 ;Start of program in memory


SetUp MOVLW 08 ;
MOVWF TRISIO
OPTION 0DFh ;
----------
----------
ORG 2Ch ;Next following instruction will be placed at location 2Ch
Main CALL Switch
CALL Display
CALL Beep
  GOTO Main

Oscillator Calibration value

call        0x3ff ;get the calibration value


movwf    OSCCAL ;calibrate oscillator

org       0x3ff ;OSCCAL calibration value is located at the last line of


  retlw   0x20 ;    program memory and has the instruction to return with
;   20h in W
END

Output a Table Value see also Table


 

Table ADDWF 02h,1 ;Add W to the Program Counter to create a jump. 


RETLW 3Fh
RETLW 06h
RETLW 5Bh
RETLW 4Fh
RETLW 66h
RETLW 6Dh
RETLW 7Dh
RETLW 07h
RETLW 7Fh
RETLW 6Fh  

Output a Value
The output port for a PIC12F629 is actually a FILE or REGISTER!  It is file 05. 
The 6 lines of the port are called: GP0, GP1, GP2, GP3, GP4 and GP5.  
Each line can deliver approx 25mA. The maximum total current for the chip is about 150mA.
An output line can be HIGH or LOW. Each output line corresponds to a bit in the file
associated with the port. When the bit is SET, the line is HIGH. When the bit is CLEAR, the
line is LOW. 
Before you can make a line HIGH or LOW, the file must be "configured." This means each bit
must be made an OUTPUT. This is done via the TRISIO file. This file is located at 85h - in
Band 1.
Any line can be made either an input or an output at any time during the running of a program
and to make a line INPUT, the corresponding bit in the TRISIO file is made "1." To make a
line OUTPUT, the corresponding bit in the TRISIO file is made"0."
There are two ways to get to the TRISIO file. One is directly via the instruction:

MOVLW 2Bh ;Load xx10 1011 into W


TRISIO ;Make GP2 and GP4 output.

The other is via the two instructions: BSF 03,5 and BCF 03,5. These instructions allow you to
go to  bank1 where the TRISIO file is located. It is in Bank1 and the TRISIO file is called 05.

BSF 03,5 ;Go to Bank 1


MOVLW 3Fh ;Load W with 0011 1111
MOVWF 05 ;Make all GPIO input
BCF 03,5 ;Go to Bank 0 - the program memory area.

Any lines that are made output can be made HIGH or LOW.

MOVLW 16h ;Load 0001 0110 into W


MOVWF GPIO ;Make GP1 and GP2 and GP4 HIGH.
Pause
To create a "pause" instruction:

Loop         goto  $            This will cause the microcontroller to keep looping the same
instruction.

or

Loop        nop
               goto Loop

PULSE WIDTH MODULATION (PWM)


To make a motor-driven toy (car, robot etc) travel at a slow speed (or any speed) the RPM
(revolutions per minute) of the motor needs to controlled. You can do this by supplying less
cells (less "batteries") a lower voltage via a power supply or providing pulses of energy that
cause the RPM of the motor to increase or decrease. You can also add a resistance to one of
the leads.
One of the simplest ways is to provide pulses of energy and this can be done with transistors,
IC's or a microcontroller.
The following code allows 2 motors to be controlled via 16 steps, from 0 to 16. The code
simply delivers a value such as 4/16 to one motor and 12/16 to the second motor in 1/100th
second.
The value of the step is contained in file M1 (for motor-1) and M2 (for motor-2).

;M1 & M2 are the bits in Ghost file for the motors
;PWM1 is the file for motor 1 speed (0-15)
;PWM2 is the file for motor 2 speed (0-15)
;Ghost file holds the bits (M1 & M2) to turn on/off each motor
Preload the PWM files:

movlw (0 to .15 - decimal 15)


movwf PWM1
movlw (0 to .15 - decimal 15)
movwf PWM2

DoPWM bsf Ghost,M1 ;turn motor 1 on


bsf Ghost,M2 ;and motor 2
movlw 1 ;preload W
PwmLoop subwf PWM1,f ;sub 1 from PWM1
btfss STATUS,dc ;was there a borrow from bit 4
bcf Ghost,M1 ;yes so turn motor 1 off
subwf PWM2,f ;now do second channel
btfss STATUS,dc
bcf Ghost,M2 ;turn motor 2 off
movf Ghost,w ;copy register to w
movwf GPIO ;move w to I/O register
movlw 1 ;reload W
addwf Count,f ;inc count but set flags
btfss STATUS,dc ;have we been around 16 times
goto PwmLoop ;no, so go around inner loop
btfss STATUS,z ;have we done 256 times
goto DoPWM ;no so repeat outer loop
retlw 0 ;done

Push and Pop and "Save"


Push and Pop are terms used when programming some of the "older style" microprocessors
and refers to the ability to store a value (in a file) and send it to a place called a "stack" and
get it back later. The microcontrollers we are dealing with have lots of files and we rarely run
out of them so the ability to save a value is not available.  However when you write an
instruction such as CALL Del-1, the current address of your program is placed on the stack so
the micro can come back to the next instruction, after it has executed the instructions at the
sub-routine called Del-1.
If you want to save a value in a register, you will need to load it into "w" and from w to one of
the unused files, thus:

    movf     the file with the value,0 to w   such as 3A,0
    movwf    the file that will save the value   such as 4B

e.g:   movf    3A,0         ; (the value in file 3A gets copied into the working register)
        movwf   4B           ; (the value in the working register gets copied to file 4B)

Poll See also Switch


The action of POLLING means to "look at - on a regular basis."  It generally refers to an
input device such as switch or push button. A push button can be pressed and released in
less than 10th second and this means it must be scanned or polled 10 times a second
(100mS).
This means you have 100,000 machine cycles available between "looks." 
Most programs consist of a Main routine and this is looped on a regular basis. As a program
gets larger and larger, the Main routine may loop at a slower rate (mainly due to delay sub-
routines needed for some of the operations) and you may exceed the 100,000 limit. 
The answer is to place the "look" feature inside the delay sub-routine.  The following sub-
routine has a "Look" feature inside a Delay:
 

Delay MOVLW 01h ;Approx 300mS per "unit"


MOVWF 2C
Delay1 NOP
DECFSZ 2A,1
GOTO Delay1
BTFSS 05,0 ;Look at push-button line on port A
GOTO Not ;Button not pressed
BSF 2F,0 ;Set button-press flag
RETLW 00
Not BCF 2F,0 ;Clear button-press flag
BCF 2F,1 ;Clear "action" flag
Delay2 DECFSZ 2B,1
GOTO Delay1
DECFSZ 2C,1
GOTO Delay1
RETLW 00

CALL Delay
Main other instructions
BTFSS 2F,0 ;Has button been pushed?
GOTO Main ;No.
BTFSC 2F,1 ;Yes. Has "action" already been performed?
GOTO Main ;Yes.
BSF 2F,1 ;No.
CALL Action
GOTO Main

The Delay sub-routine includes instructions to look at a button and set a flag (BSF 2F,0) when
it is pressed. 
The micro comes out of the Delay routine with the flag SET. The flag is then looked at in Main
and the appropriate sub-routine is executed. 
This sequence may be executed very quickly and the micro may return to Delay before the
button is released. The "action" flag (BTFSC 2F,1) prevents the action being carried out more
than once for a single button-press. 
When the button is released, both flags are cleared. 

Pseudo Instructions - these are additional Instructions understood by MPASM:


 

Equivalent
Mnemonic Description Status
Operation(s)
BTFSC 3,0
ADDCF f,d Add Carry to File Z
INCF f,d

Add Digit Carry to BTFSC 3,1


ADDDCF f,d Z
File INCF f,d

B k Branch GOTO k -

BTFSC 3,0
BC k Branch on Carry -
GOTO k

Branch on Digit BTFSC 3,1


BDC k -
Carry GOTO k

BTFSS 3,0
BNC k Branch on No Carry -
GOTO k

Branch on No Digit BTFSS 3,1


BNDC k -
Carry GOTO k

BTFSS 3,2
BNZ k Branch on No Zero -
GOTO k

BTFSC 3,2
BZ k Branch on Zero -
GOTO k

CLRC   Clear Carry BCF 3,0 -

CLRDC   Clear Digit Carry BCF 3,1 -

CLRZ   Clear Zero BCF 3,2 -

BCF/BSF 0x0A,3
LCALL k Long Call BCF/BSF 0x0A,4  
CALL k

BCF/BSF 0x0A,3
LGOTO k Long GOTO BCF/BSF 0x0A,4  
GOTO k

MOVFW f Move File to W MOVF f,0 Z

COMF f,1
NEGF f,d Negate File Z
INCF f,d

SETC   Set Carry BSF 3,0 -

SETDC   Set Digit Carry BSF 3,1 -


SETZ   Set Zero BSF 3,2 -

SKPC   Skip on Carry BTFSS 3,0 -

SKPDC   Skip on Digit Carry BTFSS 3,1 -

SKPNC   Skip on No Carry BTFSC 3,0 -

Skip on No Digit
SKPNDC   Carry
BTFSC 3,1 -

SKPNZ   Skip on Non Zero BTFSC 3,2 -

SKPZ   Skip on Zero BTFSS 3,2 -

Subtract Carry from BTFSC 3,0


SUBCF f,d Z
File DECF f,d

Subtract Digit Carry BTFSC 3,1


SUBDCF f,d Z
from File DECF f,d


TSTF f Test File MOVF f,1

Pull-ups
The PIC12F629 has individual pull-ups of about 47k on each line, that can be activated via
the following code. When a line is made into a input, the pull-up is not active, but is re-
activated when the line is changed to output.
Pin 4, GPIO,3 (GP3) is an INPUT-ONLY pin and does not have a pull-up. 
In the following instructions, GPIO,5 will have a weak pull-up. A push-switch is connected
between GPIO,5 and ground. When the switch is pressed, the input will go LOW.  This is
called an active LOW input. GPPU is an active LOW enable bit. It is written:  GPPU. In the
program it is identified as NOT_GPPU as the "Word" document does not overlines. When this
bit is cleared (bcf), pull-ups are enabled by individual pot latch values.

     movlw b'11101000' ;Specify GPIO port direction


     movwf TRISIO      ;Set GPIO ports as xxIOIOOO
     bcf OPTION_REG
     bcf NOT_GPPU      ;enable weak pull-up
     bsf WPU, 5        ;enable wpu on GPIO 5 only

Random number see also Mask


A random number can be created by monitoring the TIMER file and looking at this file when a
player has pushed a button.

Get_Random movf     tmr0,0 ;Read the PIC's timer register and put it in W
andlw   0x03 ;mask all but bit0 and bit1 to get values 0,1,2,3.
movwf  27h ;move random number to file 27h (the
retlw    00 RANDOM    ;         number file).
To get a random number: 0-7, mask all but bits 0,1,2: andlw 0x07
The random number file can be incremented if zero is not needed (this will be the second
instruction in the sub-routine above) and then "andlw" is carried out.

Here is another Random Number Generator form Andrew Warren [fastfwd at ix.netcom.com]
of Fast Forward Engineering - San Diego, California.

Load a register called "RANDOM" with any non-zero value, then call this routine each time
you'd like a new pseudo-random value:   LFSR = Linear Feedback Shift Register.
    LFSR:   RLF     RANDOM,W
            RLF     RANDOM,W
            BTFSC   RANDOM,4
            XORLW   1
            BTFSC   RANDOM,5
            XORLW   1
            BTFSC   RANDOM,3
            XORLW   1
            MOVWF   RANDOM
            RETLW   0

Scott Dattalo says:

[with the double RLF at the start of this routine,] Andy is implementing 'roll left' where the most
significant bit of RANDOM will get copied to least significant position. This is how it works.
The first RLF will copy the most significant bit of RANDOM into the carry. What ever was in
the carry prior to the first RLF will get copied into the least significant bit position - but we don't
care. Also, since the destination is the W register, the variable RANDOM is unaffected. The
second RLF repeats the same rotate operation, but this time the carry has been initialized to
the MS bit of random. So this second rotate will copy the MS bit into the least significant bit.
All of the other bits are of course shifted left one bit position. 

Read a File
Files can be used to store temporary data.   A file can be read by moving (it actually gets
copied and the original is not altered) it into the W register via an instruction such as: movf 
3Ch,0
A file can be "read" and an action performed if it is zero. Use instructions such as:
     decfsz    3Ch,0
     goto       button-1  ;the file is not zero
     goto       button-2  ;the file is zero

Any bit in a file can be read and an action carried out. In this case bit 3 is tested:
      btfss      3Ch,3
      goto       button-1  ;bit 3 is "0"
      goto       button-2  ;bit 3 is "1"

Read Data
The PIC12F629 does not have a feature such as "Read Data" or "Read an Instruction." Data
can be added to a program (when writing the program) in the form of a table (see Table) and
this data cannot be altered. Each item in the table can be read by writing an instruction such
as:

    retlw   4Fh


    retlw   22h
    retlw   0CCh
 
Temporary data can be stored in a file or set of files. There are 68 files (from 20h to 5F).   
Data can also be added to the EEPROM section. This is 128 bytes of data and can be
changed up to 1 million times. The data will be kept when the power is removed.

Remove bits see AND and Mask

Return  - not used for PIC12F629, use:


Retlw  00
This instruction must be somewhere in each sub-routine if the sub-routine has been CALLED.
It is generally at the end, but quite often programming will create a Return part-way through a
routine. The instruction to use for a PIC12F629 is: retlw   00     to      retlw   0FFh

See CALL and GOTO for more details.

RETLW 00 to FF - Return with Literal in W


A sub-routine can carry out an operation and set a flag. Alternatively it can return with a value
in W. 
If a sub-routine generates two or three different results, the RETLW 00 to FF instruction can
Return with the appropriate value in W. 
RETLW 00 to FF is used for each value of data in a Table. (see Table)

Rotate
This is the same as SHIFT.  All the bits in a file are moved to the left or right through the
CARRY. 
Carry is located in the STATUS file (03,0).
It requires 9 shifts (rotates) to get the bits back to the original position. 
The CARRY must be cleared (BCF 03,0) if you don't want it to appear in the file. 
RLF (Rotate Left File) increases the value of the contents (doubles the value).
RRF (Rotate Right File) decreases the value of the contents (halves the value).

The following two instructions will rotate the contents of a file register without loosing data in
the "Carry Flag".
Rotate right or left can be implemented. Note that the carry flag is changed.
Enter with "abcdefgh" and leave with "bcdefgha"

  rlf   Register, w        ;Load Carry with the highest bit


  rlf   Register, f        ;Shift left

or
Enter with "abcdefgh" and leave with
"habcdefg"

  rrf   Register, w        ;Load Carry with the lowest bit


  rrf   Register, f        ;Shift right  
Same
To find out if two numbers are the same, they are XORed together. See XOR and
Comparison

SetUp
The first sub-routine in a program is SetUp. It sets the direction for each Input/Output line and
clears any other files to get them ready for incrementing etc. 
To make a line INPUT or OUTPUT, see INPUT, OUTPUT.
Instructions between BSF 03,5 and BCF 03,5 are dealing with files files in Bank 1. For
instance, if files 05 is loaded with 02, this is actually the TRISIO  file. This file controls the
direction of the Input/Output lines of GPIO and when it contains 0's, all the lines are output.
Note: GP3 is input only

ORG 0 ;This is the start of memory for the program.


SetUp BSF 03,5 ;Go to Bank 1
MOVLW 02 ;Load W with 0000 0010
MOVWF TRISIO ;Make GP1 input
BCF 03,5 ;Go to Bank 0 - the program memory area.
CLRF 2F ;Clear flag file
CLRF GPIO ;Clear GPIO of junk
  GOTO Main

Shift  see Rotate   

SLEEP   
This instruction puts the micro to sleep. This is also called "power-down mode."
The micro stops executing the program when it comes to this instruction.
If the Watchdog Timer is enabled, it will be cleared but will keep incrementing.
The In/Out lines maintain the status they had before SLEEP was executed.
For the lowest consumption in SLEEP, all output lines must not drive any circuitry before the
SLEEP instruction.
On-chip pull-ups must also be turned off to reduce the current consumption during SLEEP.
The micro will wake up from SLEEP via one of the following:
1. Taking MCLR pin LOW
2. Watchdog Timer wake-up (if watchdog is enabled)
3. Interrupt from GP2/INT pin
4. GPIO change
5. Peripheral interrupt.
On wake-up from SLEEP, the WDT is cleared.

When the SLEEP instruction is being executed, the next instruction (PC + 1) is pre-fetched.
For the micro to wake up through an interrupt event, the corresponding interrupt enable bit
must be set (enabled). Wake up is regardless of the state of the GIE bit. If the GIE bit is clear
(disabled) the micro continues execution at the instruction after SLEEP. If the GIE bit is set
(enabled) the micro executes the instruction after SLEEP then branches to the interrupt
address (004h). In the case where the instruction following SLEEP is not desirable, the user
should have a NOP after the SLEEP instruction.   
The TO and PD bits in the STATUS register can be used to determine the cause of RESET.
The PD bit, which is set on power-up, is cleared when SLEEP is invoked. The TO bit is
cleared if WDT wake-up occurred.
 
The SLEEP instruction is:

       sleep

To send the micro to the "sleep_micro" sub-routine, the following instruction is needed:

        goto    sleep_micro

The simplest sub-routine for SLEEP is:

sleep_micro
                      sleep

To set GPIO 3 for wake-up from sleep: This has been tested in Greeting card "Decision
Maker"

bsf            status, rp0           ;Bank 1


movf          GPIO,0
movlw        b'00001001'         ;must clear the GPIF flag!!
movwf        INTCON
bsf            IOC,3
sleep
nop
bcf            status, rp0          ;bank 0
goto           xxx

If the Watchdog timer is enabled, the micro will come out of SLEEP and goto main.
The watchdog will reset after 18,000uS (18m) and wake the micro.  
If 18mS is too short, a prescaler can be added to increase the WDT time by 2, 4, 8, 16, 32, 64
or 128. The maximum time is 18mS x 128 = 2.3sec 

The micro contains an 8-bit prescaler register that can be assigned to Timer0 or Watchdog.
This prescaler  register is not readable or writable. 
To set the prescaler to the WDT, bit 3 of the OPTION REGister must be set. The instruction
is:

      bsf      STATUS, RP0   ;select bank 1

      bsf   OPTION_REG,3


or
     movlw   b'xxxx1xxx'
     movwf   OPTION_REG

     bcf      STATUS, RP0  ;select bank 0

The three lowest bits of the Option register set the timing for the WDT:

   bsf      STATUS, RP0   ;select bank 1

   movlw  b'xxxxx000' 
   movwf  OPTION_REG  ;WDT timer = 18mS
or:
   movlw  b'xxxxx001' 
   movwf  OPTION_REG  ;WDT timer  = 36mS
or:
   movlw  b'xxxxx010' 
   movwf  OPTION_REG  ;WDT timer  = 72mS           etc  etc
or:
   movlw  b'xxxxx111' 
   movwf  OPTION_REG  ;WDT timer  = 2,304mS = 2.3 Seconds

   bcf      STATUS, RP0  ;select bank 0

GPIO CHANGE
If you want the micro to come out of sleep when the voltage-level changes on any input line,
the WDT must be turned off. This must be done during burning the program into the chip.
(You will not have the advantage of the watchdog timer to reset the micro if it runs off the end
of the program.)

    movlw   b'xxxx1xxx'     ; Enable GPIO port change interrupt (but NOT GIE)
    movwf   INTCON

Make at least one of the in-out pins an input:

   bsf      STATUS, RP0   ;select bank 1


   movlw   b'xxxx1xxx'     ;make GP3 input
   movwf  TRISIO
   bcf      STATUS, RP0   ;select bank 0

Add the SLEEP instruction to the program:

        goto    sleep_micro

Add the SLEEP sub-routine:

sleep_micro
                      sleep

                     
Alternately, a SLEEP instruction can be added to a program. In the program below, the micro
will stop executing instructions when it reaches "sleep" and wait for a "time-out" of the WDT or
a change in GPIO (depending on the setting in INTCON.) If the GIE bit is set, the micro will
execute "instruction A" (after sleep) and go to the interrupt address (004h).

    instruction
    instruction
    instruction
    sleep           
    instruction A  - this instruction can be anything but a GOTO instruction.
    no further instructions

If you don't want an instruction after "sleep" use: NOP.

The Global Interrupt feature is enabled by setting bit 7 of the INTCON register. For this and
other features of SLEEP see:  PIC12F629 Data Sheet (.pdf  4,926KB)

Another SLEEP sub-routine:


To put the micro to sleep, a number of things must be done. This routine allows the micro to
go to SLEEP when it detects 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. 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.
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
 

Sleep movf     GPIO,W ; 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.
bcf       INTCON,GPIF
  bsf       STATUS,RP0 ; Sel bank 1
movlw   0xFF ; Setup W for TRISIO all input
movwf   TRISIO ; Write to TRISIO. Reduce power in sleep mode
sleep ; Go to sleep
nop ;
movlw   b'11101000' ; Wake from sleep and set
movwf   TRISIO ; TRISIO for input and output for your project
bcf       STATUS,RP0 ; Sel Bank 0
movf     GPIO,W ; Read GPIO register
bcf       INTCON,GPIF ; and clear GPIF flag in interrupt register

The following set of instructions have been tried in an Alarm project. Some of the instructions
may not be needed and you can try deleting and testing for yourself. The most important point
to remember is this: The micro goes to ISR (address 04) after waking up from sleep and the
instructions at address 04 must be included:

       org 0
       goto     setup
       nop
       nop
       nop
       nop
       goto    Enable

SetUp     movlw       b'00001111'       ;0001 1111


              movwf       GPIO        ;Make GP 0 HIGH and GP5 LOW for piezo & GP4 low
              bsf           status,rp0         ;Bank 1
              movlw       b'00011110'
              movwf       trisio                ;Make GP1,2,3,4 input GP0,5 output
              movlw       b'10000110'      ;Turn off T0CKI, prescaler for TMR0 = 1:128
              movwf       option_reg
              bsf            intcon,3           ;enable GPIO state change int
              bsf            intcon,7           ;enable global interrupt GIE
              bsf            IOC,4              ;enables interrupt on GPIO 4
              bcf            status,rp0       ;bank 0
              movlw       07h                 ;Set up W to turn off Comparator ports
              movwf       CMCON           ;must be placed in bank 0

             movf          GPIO,w           ;clears the Int-on-change flag


             bsf            status,rp0        ;Bank 1
             bcf            intcon,gpif
             bcf            status,rp0        ;bank 0
             nop
            sleep
            nop                                   ;micro goes to ISR at address 04!!!!!!!!!
 
 

Stack
This is an area where up to 8 addresses are placed. These address are RETURN address.
When a CALL is made, the address of the next instruction in your program is placed on the
STACK. 
The micro will go to the sub-routine you have CALLed. In this sub-routine you can have
another CALL.
This is the second CALL. In the second sub-routine you can have another CALL. In fact this
can be done up to 8 times.
If more than 8 address are placed on the stack, the first address is lost. That's why you
cannot have more than 8 CALLs. When a return is made, the CALL number is reduced.
The PIC12F629 can have a CALL instruction that CALLs another sub-routine and the sub-
routine CALLs another sub-routine and that sub-routine CALLS another sub-routine until 8
CALLs are made. 
The 8th sub-routine will have  a RETLW  00 to go back the the previous sub-routine and each
sub-routine will have a RETLW 00 until finally the micro returns to Main. 
The animation below shows a CALL in a sub-routine CALLing another sub-routine and this
sub-routine CALLs another sub-routine.  The Program Counter makes the micro carry out
the instructions.
Note: Return is used in '508 instruction-set and Retlw 00 is used in '629 instruction-set):

The PIC12F508 or 509 has only a "2-stack" and the low-cost PIC micro (reserved for high-
quantity orders) has only a "2-stack."  It is important to realise this so your programs are
portable to other micro's. You can have a CALL from Main and a CALL from the sub-routine,
but the second sub-routine must only have a RETLW 00. 

Stop see also Wait.


The microcontroller does not have a Stop instruction. Do not use the word "Halt" as a label,
the assembler does not like it. Use Loop, Pause, Wait.  See Loop. 
To create a "waiting loop" use the following instructions:

Loop NOP ;Hold the micro in a loop


GOTO Loop 
When testing a program, you may need to know if the microcontroller has advanced to a
certain part of the program. 
Insert the instruction: GOTO Wait.
Insert the following instructions. They should include an output to a LED etc so you can prove
the micro has entered the loop. 

Wait NOP ;Hold the micro in a loop


MOVLW 07h
MOVWF GPIO ;Output a HIGH to LEDs
GOTO Wait 

Store Data
The PIC12F629 has two ways to store data. 
If you need to store only a few bytes of data for a short period of time, use files that are not
required in any of the running of the program.
This information will be lost when power is removed. 
If you want to store data permanently, the PIC12F629 has 128 bytes of EEPROM.
This requires a special routine - found under EEPROM.  

Sound
The following program produces a "rising Sound."

sound movlw  0F0h ;


movwf  temp
sound1 bsf      GPIO,0 ;Piezo bit HIGH
movf    temp,0
movwf  soundhigh
sound2 nop
nop
nop
nop
nop
decfsz  soundhigh,1
goto     sound2
bcf       GPIO,0 ;piezo bit LOW
movf     temp,0
movwf  soundlow
sound3 nop
nop
nop
nop
nop
decfsz  soundlow,1
goto     sound3
decfsz  temp,1
goto     sound1
retlw     00
SUB 
The following SUBTRACT operations are available:
       sublw    00 - 0FFh  -  subtract w from literal  - NOT subtract literal from w
       subwf    file,w    - subtract w from file (result stored in w)
       subwf    file,f    - subtract w from file (result stored in file)

Here is an example of the sub(tract) operation:

       movlw  0Eh     -  the value 0Eh is loaded into w


       movwf  count  -   0Eh is moved to a file called "count."  This gets a value into a file.
       movf    count,w   - the value in "count" is moved to w
       sublw  0Fh         - subtract w (0Eh) from literal (0Fh)

       0000 1111


  -    0000 1110
       0000 0001  

Note: the last digit is INVERTED. This is a handy way to invert a digit.

SWAP
PIC language has a SWAP NIBBLES instruction. It swaps the HIGH nibble with the LOW
nibble.  Swapping INDF (file 00) actually swaps the nibbles in the file pointed to by FSR.

  SWAPF 2A,1 ;Before: File 2A = 81h     After: File 2A = 18h

SWAP THE CONTENTS OF TWO FILES  


Example: File 2C = 81h
               File 2D = 47h
               File 2E = temp storage

  MOVF 2C,0  ;Move 2C to W


MOVWF 2E,1  ;Move W to 20E
MOVWF 2D,0  ;Move 2D to W
MOVWF 20C,1  ;Move W to 20C
MOVF 2E,0  ;Move 2E to W
MOVWF 2D,1  ;Move W to 2D

To swap the contents of two files without using a temporary file:

  movf    X, w  
subwf   Y, w
addwf   X, f
subwf   Y, f

Another way to swap the contents of two files without using a temporary file:

  movf    X, w ; Get X
xorwf   Y, f ; Y is now X^Y
xorwf   Y,w ; W is now (X^y)^X==Y  (say OldY)
movwf   X ; Now X is OldY
xorwf   Y, f ; finally Y is (OldX^Y)^Y==OldX

SWAP THE CONTENTS OF A FILE WITH W  


Example: File 3C = 81h   W = 47h
               after operation:   File 3C = 47h   W = 81h
 

  XORWF 3C,1  
XORWF 3C,0 
XORWF 3C,1

Switch (button, key) see also Poll


There is no difference between "Switch," "Button" and "Key."  They all refer to a push button
that has momentary action. It can be an individual push button, one of a number of buttons or
in a matrix of buttons such as a keypad. 
With all button instructions, there are three important things to remember. They are
mechanical devices and their action is very slow in "microprocessor-time." They produce a lot
of pulses when pushed and also when released (this is called switch-noise or switch-bounce).
In any button routine, you must also prevent a button-press being registered more than once. 
Many sub-routines already have a switch or button feature included in them.  Select an
existing sub-routine or use the following. 
The most important part of adding a switch or button routine is creating the debounce
feature. 
This is to prevent "double-counting" when the button is pushed or released. Try slow-pressing
and slow-release to see if the program produces a false result. If the program "double-
counts," you will have to increase the debounce-time. 
Debounce can take up a lot of computer-time. Debounce is a delay routine that "masks"
(hides - or disallows) the time when the button is pressed or released, so that only one pulse
is detected. Instead of producing a separate debounce routines, you may be able to use the
time taken to execute other sub-routines. In other words, the program looks before and after
the execution of another routine and if the button is still pressed, the micro detects it as a
"button-press." 
Finally, you need to detect the first press of a button and prevent the program operating on
the button during the second pass of the program. 
The basis of detecting a button-press consists of 6 separate items that must be placed in the
following order:
There are two flags. Bit0 in file 1F is the Debounce Flag and Bit1 in file 1F is the Button
Pressed flag. 
The microprocessor executes Main and CALLs Sw. If Sw detects a key-press, two flags are
SET. The first is the Button Pressed flag and the second is the Debounce flag.
The micro returns to Main and tests the Button Pressed flag to see if it is SET. If is is SET,
the micro goes to a sub-routine such as CALL Increment, where a value can be incremented.
The Button Pressed flag is then cleared and the micro CALLs Sw. If the switch is still
pressed, the micro will return. The program is looking for the button to be released. When the
button is released, the Sw sub-routine is ready to detect another button-push.

SetUp BSF 03,5 ;Go to Bank 1


MOVLW 01 ;Put 01 into W
MOVWF TRISIO ;Make GP0 input
BCF 03,5 ;Go to Bank 0
CLRF 2F ;Clear the button-press file
GOTO Main

Sw BTFSS 05,0 ;Test the button. Button is "Active HIGH"


GOTO Sw2 ;Button not pressed
BTFSC 2F,0 ;Button pressed first time?  Test debounce flag
RETLW 00 ;Button already pressed. Return to Main
Sw1 DECFSZ 2A,1 ;Create short delay
GOTO Sw1 ;Look again
BTFSS 05,0 ;Is switch still pressed?
GOTO Sw2 ;It was only noise
BSF 2F,1 ;Button Pressed.  Set button-pressed flag
BSF 2F,0 ;Set debounce flag
RETLW 00 ;Return to Main
Sw2 BCF 2F,0 ;Clear debounce flag
RETLW 00 ;Return to Main

Main CALL Sw
BTFSC 2F,1 ;Test button-press flag to see if button was pressed
GOTO Main2 ;Button pressed
Display the values ;Button not pressed
on a display etc.
GOTO Main
Main2 CALL Increment ;Increment the display. (you provide the routine)
BCF 2F,1 ;Clear the button-press flag
GOTO Main

Table see also Output a Table Value and CALL Table


Suppose you need to turn on LEDs to produce the pips on the side of a dice (die). This can
be done via a table.

In a sub-routine, a value between 1 and 6 is created and put into "w" and Table is called thus:

       movlw    03h      ;any value 1 - 6 is put into w


       call        Table    ; the micro will go to the table and return with 5Bh
       movwf    temp1  ; 5Bh will be put into the temporary file

To prevent the micro jumping beyond the end of the table, the instruction:

      andlw     06h        is used when the table contains 6 elements.

The layout for a Table is shown below:

Table andlw     06h ;this prevents micro jumping beyond end of table
ADDWF pcl,1 ;Add W to the Program Counter to create a jump. 
nop ;the micro jumps here for "movlw 00"
RETLW 3Fh
RETLW 06h
RETLW 5Bh
RETLW 4Fh
RETLW 66h
RETLW 6Dh
Toggle
The state of a line can be changed from High to LOW or vice versa to create a tone or other
feature. 
The instructions below do not know the initial condition of the line. They simply reverses the
state. The instructions are:  

MOVLW 01h ;Put 01 into W


XORWF GPIO,1 ;XOR 01 with GPIO, lowest line (GP0)

The following instructions apply to the other lines.

MOVLW 02h ;Put 0000 0010 into W


XORWF GPIO,1 ;XOR 02 with GPIO, for GP1

MOVLW 04h ;Put 0000 0100 into W


XORWF GPIO,1 ;XOR 04 with GPIO, for GP2

MOVLW 10h ;Put 0001 0000 into W


XORWF GPIO,1 ;XOR 10h with GPIO, for GP4

MOVLW 20h ;Put 0010 0000 into W


XORWF GPIO,1 ;XOR 20h with GPIO, for GP5

Tone see also Beep


When a line is taken HIGH then LOW at a rapid rate, a tone is produced in a piezo or
speaker. A buffer transistor (amplifier) may be needed.  
The simplest tone takes a line HIGH, then executes a delay. The line is taken LOW and a
delay is executed. This process is repeated. The following routine shows how a tone is
produced. The micro never comes out of the Tone sub-routine. It is only suitable as an "end of
the line" sub-routine.

Tone NOP
DECFSZ 2A,1
GOTO Tone
MOVLW 02h ;Put 02 into W
XORWF GPIO,1 ;XOR 02 with GPIO. Toggle GP1
GOTO Tone

To get the micro out of the Tone routine is must have a "duration." The pitch of the tone can
also be changed:

Tone MOVLW 10h ;The duration of the tone or "beep"


MOVWF 2B
Tone1 MOVLW 02h ;The length of  HIGH and LOW - frequency of tone
MOVLW 2A
NOP
Tone2 DECFSZ 2A,1
GOTO Tone2
MOVLW 02h ;Put 02 into W
XORWF GPIO,1 ;XOR 02 with GPIO. Toggle GP1
DECFSZ 2B,1
GOTO Tone1
RETURN

TRISIO also known as "tris"


The file that determines the in/out state of each line (pin) for the in/out Port is the TRISIO file. 
It is located in Bank1 of the microcontroller.  It has the value 85 for PIC12F629 to control the
GPIO lines. For a PIC16F628 it is 85h for PortA and 86h for PortB.  For the PIC10F200
series, the tris register is not given an address number and is only accessed by the mnemonic
"trisgpio"
To access the tris register. 
 GPIO has GP0, GP1, GP2, GP3, GP4 and GP5.  Eg: MOVLW 0FFh will only affect the 6
input lines of GPIO.  Bits 6, and 7 of a value will not have any effect.
There are two ways to get to the TRISIO file. It can be accessed directly by adding the
following two instructions directly into your program at any location:
Note: We have found the instruction: movwf   tris, DOES NOT WORK for some micros.
Use the instructions BSF 03,5 and BCF 03,5
 

MOVLW 01h ;Put 01 into W


MOVWF TRISIO  ;Make GP0 an input and all others output
or
movlw    01h
tris        gpio ;this instruction has been tested and works for 12F629

The following instructions apply to the other lines: GP3 is input ONLY

PortA: MOVLW 02h ;Put 0000 0010 into W


MOVWF TRISIO ;Make GP1 an input and all others output

MOVLW 04h ;Put 0000 0100 into W


MOVWF TRISIO ;Make GP2 an input and all others output

MOVLW 08h ;Put 0000 1000 into W


MOVWF TRISIO ;Make GP3 an input and all others output

MOVLW 10h ;Put 0001 0000 into W


MOVWF TRISIO ;Make GP4 an input and all others output

MOVLW 20h ;Put 0010 0000 into W


MOVWF TRISIO ;Make GP5 an input and all others output

MOVLW 3Fh ;Put 0011 1111 into W


MOVWF TRISIO ;Will make all input! (except GP3)
 

The TRISIO file can also be accessed by inserting BSF 03,5  BCF 03,5 instructions into your
program.
The BSF 05,3 instruction takes you to Bank1 where the TRISIO file is located. When in
Bank1, the TRISIO file is file 05. See: SetUp for details of the instructions to be inserted
between BSF 03,5 and BCF 03,5.
 
BSF 03,5 ;Go to Bank 1
movlw  
b'00000011'
movwf   tris ;Go to Bank 0 - the program memory area.
BCF 03,5

Wait  see also Stop.


When testing a program, you may need to know if the microcontroller has advanced to a
certain part of the program. 
Insert the instruction: GOTO Wait.
Insert the following instructions. They should include an output to a LED etc so you can prove
the micro has entered the loop. 

Wait NOP ;Hold the micro in a loop


MOVLW 07h
MOVWF GPIO ;output
GOTO Wait

Watchdog Timer (WDT)
The PIC12F629 has an inbuilt timer that increments all the time. It has a normal time-out
period of 18mS (18,000 instruction-cycles). You cannot turn the timer on or off via the
program. It is turned on (or off) during the burning of the program by setting WDT in the
__config file. 
To turn the watchdog timer off:    & _WDT_OFF
To turn the watchdog timer on:    & _WDT_ON
If it is active (turned ON) the micro will go to 000 (reset) after 18,000uS.  
This action has a purpose. 
If a program is badly designed, it may "run off the end of the program" and start executing
"junk" commands. A glitch may cause the micro to go to an incorrect part of a program to
cause it to "Freeze." To prevent this from occurring, the WDT takes the micro back to the
beginning and starts the program over again. 
To prevent the WDT constantly resetting a program, the WDT must be constantly reset via
the instruction CLRWDT. This gives the programmer another 18,000 instructions before
having to reset the WDT. 
To keep WDT constantly reset, CLRWDT must be placed inside delays. 
Normal programming (experimenting etc) is carried out with WDT OFF. 
If 18mS is insufficient a prescaler can be added to increase the WDT time by 2, 4, 8, 16, 32,
64 or 128. The maximum time is 18mS x 128 = 2.4sec  

Weak Pull-Up Resistors


The PIC12F629 has inbuilt weak pull-up resistors (47k) for each of the 8 input lines. These
resistors are ONLY enabled when any line is INPUT.
To enable this feature:

            bcf         OPTION_REG,7    ; enable weak pull-ups (Option_Reg address:  81h)


(bank1)
            bsf         WPU, 5                ; enable wpu on GPIO 5 only (WPU address:  95h) (bank1)

No weak pull-up available on GP3.


XOR - XOR detects a MATCH! 
XOR is called exclusive OR. 
It means the only time the output of a gate is HIGH is when ONE (and ONLY one) of the
inputs is HIGH. 
When two numbers are XORed together, the result is "1" when one (and only one) of the
numbers is "1." [The OR function is called inclusive OR see IOR]. 

To find out if two numbers are the same, they are XORed together. Since each binary digit
will be the same (i.e. either a 0 or 1) the result will be 0000 0000. The result will set the zero
flag in the status (03) file and by testing bit 2 (the Z flag) you can skip when SET.
You also have to decide where you want the result to be placed. If you don't want the value of
the file to be altered, the result should be put into W.

Example:  To see if file 2E holds the value 3C. (file 2E does contain the value 3C)

MOVLW 3C  ;Put 3C in W


XORWF 2E,0 ;XOR 3C with file 2E and put the result into W.

The micro will XOR file 2E with the value 3C. 


We know file 2E contains the value 3C, so the operation is: 
W:  0011 1100 
1E: 0011 1100 
      0000 0000  - this answer will be put into W

In this example, 3C is put into file 2E and the XOR operation is carried out:

MOVLW 3C ;Put 3C in W
MOVWF 2E :Put 3C into file 2E
XORLW 3C  ;XOR 3C with file 2E and put the result into W.
BTFSS 03,2  ;Test the Zero flag
GOTO clear
GOTO SET

The zero flag will be set. (The zero flag is SET to show the answer is zero) i.e: a MATCH! and
the program will go to the line GOTO SET. 

Zero Flag
The zero flag is found in the STATUS register (file 03).  It is bit 2.  When the result of an
operations is zero, the zero flag is SET. In other words it is  = 1.  

Zero a file 
A file can be made zero in two ways. To zero a file is the same as clear a file.  
The instruction CLRF 1A makes the contents zero. 

CLRF 2A ;Make file 2A zero. 

You can load 00 into W and move W to a file:


MOVLW 00 ;Put 00 into W
MOVWF 2A ;Make file 2A zero.

Zero in a file (test for) 


To see if a file is zero, move it in and out of itself. The Z flag will be affected. If it is SET, the
file contains 00h.

MOVF 2A,1 ;Move 2A in and out of 2A


BTFSS 03,2 ;Test the zero flag
___________ ;Micro goes here if 2A is NOT zero
___________ ;Micro goes here if 2A is zero.

You might also like