PIC INSTRUCTIONS
This discussion explains the instructions for the
PIC12F629 and
PIC16F628.
(most of this discussion has been taken from
PCB Heaven but the English
has been corrected plus many mistakes have been corrected).
The PIC chips we are using have just 35 instructions to
carry out all the features of the chip.
All instructions have the
same format. First is the name of the instruction, such as movlw for
"move" or btfss for "bit test." Then the instruction
itself. It can define a
register (f), such as movwf test1 where test1 is register 22h or a
bit (b), such as btfss test1,2 a literal, (a literal is another
word for a "number," such as movlw d35 where 35 is put into the
"working register" of the micro. The number can also be called
a "constant" or a "piece of data." Or the instruction can define a place
to go to in a program. This place will be identified by a "label" such
as goto testB. Or the instruction can have a destination (d), such as goto
$+4 where the $ symbol identifies the present address and +4 tells the
micro to advance 4 instructions down the program. The instruction $-6
tells the micro to go UP the program 6 instructions.
File Address (f).
A
file is also known as a Register. All PICs have a number of files or
registers that can be used during the execution of a program to hold
pieces of data. The files for the PICs we are using start at 20h to 5Fh
for the PIC12F629 and 20h to 7Fh (plus 128 extra) for the PIC16F628. A file address is a field that indicates the absolute
position of a register within the RAM. This field could be filled with
either a number (e.g. 0x05h for PortA or 0x06h for PortB). Files start
at 20h.
You can work with a file by using its address, such as 20h via an instruction such as movf 20h,0 or btfss 20h,1 or
decfsz 20h,1
Or you can define each file you will using in your program, at the
start. Such as:
green equ
20h
DTMF equ
21h
test1 equ
22h
You then produce instructions such as: movf green,0
or btfss green,1 or decfsz green,1 and the compiler
will associate green with file 20h during the conversion of your .asm
(your hand-produced program in NotePad) to .hex file that will be used
to "burn" (program) the chip.
Bit Address (b)
Each byte is composed of bits. For the 8-bit PICs, each byte is composed
of 8 bits. When a field requires
a bit address, it means a number from 0 to 7 must be placed in the
instruction.
0 corresponds to the Least Significant Bit (LSB)
and it is the most right placed bit within the byte. 7 corresponds to the Most Significant Bit
(MSB) and it is the most left placed bit within the byte.
Literal, constant,
data or label (k)This field is generally a
number. This number may be from a previous-defined constant, or piece of data, or
from a label within the code. When we talk about a literal we mean a
number. This is generally between 00 and 255. A constant is also a
number. A piece of data is also a number. A label is generally the name
of a sub-routine and identifies the start of the sub-routine.
Destination (d)
After an instruction is executed, the result can be placed in the
original file or it can be placed in W (the working Register) and the
original file will not be altered.
The destination can be either 0
or 1, where 0 represents the Working register and 1 represents the file. It is used in instructions that will return a byte as a result
of an operation. The destination field will define where this byte will
be stored. If this field is 0, the byte will be stored in the
working register (W). If the destination is 1, the byte will be
stored in the register where the operation was performed. You can
also write 'w' for 0 or 'f' for the file.
Typical examples to show the destination of the result of an operation:
movf green,0
The value stored in green will be copied to the working register.
movf green,1
The value stored in green will be taken out and then moved back to the
green file.
The zero flag in the Status file will be SET if the file is EMPTY.
decfsz green,1 The green file
will be decremented and the result will be placed in the file.
The micro will jump over the next instruction if the file is EMPTY.
Loading Instructions
There is no direct way to place a
number directly into a file. It must first be loaded into w
(using the movlw instruction: movlw d55) then moved to the file
using movlw, such as movwf green.
Binary
8-bit PIC microcontrollers can load binary values up
to 8-bits. If you try to load values larger than 8-bits, only the
first 8 bits will be loaded and the rest will be omitted.
The 'b' tells the compiler that a binary number
follows. The quotes are necessary. Just like the decimal
human-orientated base, if a binary number needs less than 8-bits to be
represented, all zeros on the left side of the number can be omitted.
For example, these two are the same:
Decimal
The decimal base is human-orientated. It is easier to understand
255 than b'11111111'.
The letter 'd' before the number tells the compiler that a decimal
number follows. The quotes are necessary.
Hexadecimal
This is another useful base that you may need to know.
It is most useful because number representations such as memory
positions use this base. To represent a hexadecimal number, you use the
follow form:
Unlike before, the value does not require a letter before the number.
Instead, 0x is used and no quotes enclose the number. The 8-bit
system can handle hexadecimal numbers up to 0x0ff. Larger numbers will
act as previously mentioned.
Instruction |
Description |
movlw k |
Loads a literal value 'k' into the W register
movlw b'11011010' ;A binary value is loaded into the
W register
movlw d'218'
;The value in decimal base is loaded into the W register
movlw 0xda
;The value in hex base is loaded into the W register |
movwf |
Moves the value from the W register to the
file register 'f'
This example requires you to
declare a file register, for example:
TempReg equ 0x20
movlw d'80'
;the W register has the decimal value '80'
movwf TempReg
;the TempReg register now has the value '80'
|
movf green,d |
Loads a value from "green" to W or back into
"green." If d is 0 the result is stored in the W register, if d
is 1 the result is stored back in "green." The zero flag (in the
Status file) is affected. If "green" is empty and the
instruction:
movf green,f
is performed, the zero
flag will be SET. |
Flow InstructionsThese instructions affect the normal flow of the
program. Usually, the program flows line by line. This means that when
an instruction on line 10 is executed, the next instruction will be
executed. But some instructions change the flow. A GOTO for example may
send the program from line 10 to line 100.
Instruction |
Description |
goto k |
Send the micro to another instruction or
label. When the program flow
reaches a GOTO instruction, it goes to the program line or label
placed in the k field. The k field can be from 0 to 2047.
The micro does not remember the address where the GOTO
instruction was located and thus the program cannot "return."
Use "call" if you want to return to the original place of the
"branch." To GOTO a program line, you need to
place a LABEL at the location such as "tone1" and use the
instruction: goto tone1
or you can use: goto $+45 |
call k |
Send program flow directly to a program line
or label. The address of the CALL instruction is pushed onto the
stack. A RETURN instruction will send the program flow back to
the address
where the CALL was made.
The micros we are using have an "8-Stack" and this means you can
have up to 8 CALLS. You cannot end a sub-routine with a CALL.
The next line after a call must be "retlw 00" so the micro
eventually gets back to the original address. |
retlw k |
This instruction will send the program flow
to the last position pushed onto the stack, due to a CALL
instruction. Also, the W register will return with the value k
(00 to ff). |
retfie |
This is a RETurn From Interrupt
instruction. This instruction will send the program flow back to
the position where the last interrupt occurred and caused the
program flow to go to the interrupt vector (0x04h).
It will set the GIE bit (Global
Interrupt Enable) of the INTCON (INTerrupt
CONtrol) register and will re-enable all interrupts. |
Mathematical Instructions
Instruction |
Description |
addlw
k |
Add the content of W register with a literal
value and store the result in the W register.
The status that may be affected from
this instruction are:
- C - Carry
- DC - Digit Carry
- Z - Zero
|
addwf
file,d |
Add the content of W register with the
contents of a file. If d is 0 the result is stored in the W
register, if d is 1 the result is stored back to the file.
The status that may be
affected from this instruction are:
- C - Carry
- DC - Digit Carry
- Z - Zero
|
sublw
k |
Subtract the contents of W register from a
literal value and store the result in the W register.
The status that may be
affected from this instruction are:
- C - Carry
- DC - Digit Carry
- Z - Zero
|
subwf
file,d |
Subtract the contents of W register from a
file. If d is 0 the result is stored in the W register, if d is
1 the result is stored back to the file register 'f'.
The status that may be
affected from this instruction are:
- C - Carry
- DC - Digit Carry
- Z - Zero
TempReg
equ 0x20
movlw d'100'
;The W register has the value '100'
movwf TempReg ;The
TempReg has now the value '100'
movlw d'30'
;The W register has the value '30'
subwf TempReg,1 ;The value of W is
subtracted from TempReg
;and the result (70) is stored back in TempReg
|
comf file,d |
The contents of the file
complemented. If d is 0 the result is stored in the W register,
if d is 1 the result is stored back to the file register 'f'.
TempReg equ 0x20
movlw b'11000101' ;The W register has the value '11000101'
movwf TempReg ;The TempReg has now the value '11000101'
comf TempReg,1 ;The values of TempReg is complimented and the result (00111010) is stored to TempReg |
Logic Functions
Instruction |
Description |
andlw k |
Logic AND between the contents of W and the
literal value k. The results is stored back into W.
movlw b'10000100'
;the W register now has the binary value '10000100'
andlw d'00001111' ;the
binary value '00000011' is ANDed with the W register.
;the W register has the binary value '00000100'
|
andwf
file,d |
Logic AND between the content of W register
with the content of a file register 'f'. If d is 0 the result is
stored in the W register, if d is 1 the result is stored back to
the file register 'f'.
movlw b'10000100'
;W register has the value '10000100'
movwf TempReg
;TempReg now has the value '10000100'
movlw d'00001111'
; W register has the value '00001111'
andwf TempReg,1
; W register ANDed with the contents of TempReg. The result
('00000100')
;is stored in TempReg
|
iorlw
k |
Logic OR between the contents of W and the
literal value k. The results is stored back to W.
movlw b'10000100' ;W
register now has the binary value '10000100'
iorlw d'00001111'
;the binary value '00000011' is ORed with the W register.
;the W register has the binary value '10001111'
|
iorwf file,d |
Logic OR between the content of W register
from the content of a file. If d is 0 the result is stored in
the W register, if d is 1 the result is stored back to the file.
movlw b'10000100'
;W register has the value '10000100'
movwf TempReg
;TempReg now has the value '10000100'
movlw d'00001111'
;W register has the value '00001111'
iorwf TempReg,1
;W register ORed with the contents of TempReg
;and the result ('10001111') is stored to TempReg
|
xorlw
k |
Logic EXCLUSIVE OR between the contents of W
and the literal value k. The results is stored back to W.
movlw b'10000100' ;W
register has now the binary value '10000100'
xorlw d'00001111' ;binary
value '00000011' XORed with the W register.
;the W register has the binary value '10001011'
|
xorwf file,d |
Logic EXCLUSIVE OR between the content of W
register from the content of a file register 'f'. If d is 0 the
result is stored in the W register, if d is 1 the result is
stored back to the file register 'f'.
movlw b'10000100'
;W register has the value '10000100'
movwf TempReg
;TempReg now has the value '10000100'
movlw d'00001111'
;W register has the value '00001111'
xorwf TempReg,1
;W register ORed with the contents of TempReg
;and the result ('10001011') is stored to TempReg |
Logic Functions Table
The following table shows the result of the above
functions between two bits.
Bit 1 |
Bit 2 |
AND |
OR |
XOR |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
Bit Orientated Instructions
Instruction |
Description |
bsf
file,b |
The bit 'b' in the file is Set (1).
The right hand bit is bit0 and the left-hand bit is bit7.
bsf portA,0
;The bit in position 0 in 'portA' is SET (1).
|
bcf file,b |
The bit 'b' in the file is Cleared
(0).
bcf portB,0
;The bit in position 0 in 'portB' is CLEARED (0).
|
btfss
file,b |
If the bit 'b' in the file is 1, the micro
jumps over an instruction and executes the next. If the bit is
0, the instruction is executed normally.
btfss portA,4
;Check bit '4' in register portA
micro goes here if bit 4 is 0
micro goes here if bit 4 is 1
|
btfsc file,b |
If the bit 'b' in the file is 0,
the micro jumps over the following instruction and executes the
next instruction. If the bit is 1, the instruction is executed
normally.
|
swapf
file,d |
The upper and lower nibbles of the file are
exchanged. If d is 0 the result is stored in the W register, if
d is 1 the result is stored back to the file.
movlw b'11110000'
;W has the binary number '11110000'
movwf TempReg
;TempReg has the binary number '11110000'
swapf TempReg,1
;The nibbles in TempReg are swapped
;Now TempReg has the value '00001111' |
Byte Orientated InstructionsThe byte orientated instructions are instructions to
alter a complete byte of a file:
Instruction |
Description |
rlf file,d |
Rotate Left through carry. This instruction will shift all bits of
the file one
position left. The MSB bit will be sent to the Carry, and the Carry bit
will be sent back to the register's LSB. If d is 0 the result is stored in the W
register, if d is 1 the result is stored back to the file.
|
rrf file,d |
Rotate Right through carry.
This instruction will shift all bits of
the file one
position right. The LSB bit will be sent to the Carry, and the Carry bit
will be sent back to the register's MSB. If d is 0 the result is stored
in the W register, if d is 1 the result is stored back to the
file.
|
incf file,d |
The contents of the file are increased by 1. If d is 0
the result is stored in the W register, if d is 1 the result is
stored back to the file.
|
decf file,d |
The contents of the file are decreased by 1. If d is 0
the result is stored in the W register, if d is 1 the result is
stored back to the file.
|
incfsz
file,d |
The contents of the file are increased by 1. If d is 0
the result is stored in the W register, if d is 1 the result is
stored back to the file. If the result is '0', the next instruction
is jumped over and the following instruction is executed.
The layout of instructions are as follows:
incfsz
fileC,1
goto
$-1
goto
show
The micro will execute incfsz
fileC,1 and move to goto $-1
then go to incfsz fileC,1 and increment to goto
$-1 etc etc etc.
But when fileC contains "ff" the next increment will make it
"00" and the micro will jump to goto
show.
|
decfsz file,d |
The contents of the file are decreased by 1. If d is 0
the result is stored in the W register, if d is 1 the result is
stored back to the file. If the result is '0', the next instruction
is jumped over and the following instruction is executed.
The layout of instructions are as follows:
incfsz
fileC,1
goto
$-1
goto
show
The micro will execute incfsz fileC,1 and move to
goto $-1 then go to incfsz
fileC,1 and increment to goto $-1 etc etc etc.
But when fileC contains "ff" the next increment will make it
"00" and the micro will jump to goto
show.
|
clrf file |
The file is cleared.
The Zero Status is always SET: |
clrw |
The working register W is cleared.
The Zero Status is always SET: |
Miscellaneous Instructions
Instruction |
Description |
nop |
This is the No Operation instructions. When this is executed,
nothing will happen at all. It has no occurrence to anything on
the chip or program. This instructions is commonly used to
create time delays.
nop
;This program will do nothing at all
nop
nop
|
clrwdt |
This instructions will clear the Watchdog timer. The Watchdog
timer is a very useful independent on-chip timer that is used to
ensure the chip is operating normally. When the Watchdog
timer is enabled, it will "time out" after a certain number of
microseconds. This corresponds to a certain number of
instructions. You must reset the watchdog timer before this
occurs by making sure it gets reset throughout your whole
program by counting the number of instructions between each
reset.
This becomes very complex when you have delays nd you normally
need to add a clrwdt within a delay.
If the timer is not reset within its time period,
it will reset the PIC and the program will start over, because
it will assume the program flow is interrupted or fallen into an
infinitude loop.
|
sleep |
This instruction will put the chip into Sleep
mode. Sleep mode is a state where the PIC will draw as low as
0.1uA and it will only have some basic operations still running
for waking it up. The Sleep mode is basically for power
maintenance.
When the SLEEP instruction is executed, the Watchdog timer and
it's prescaler are cleared. The Power Down bit
(-PD) is also cleared, and the Time Out Status bit (-TO) is set.
The chip then goes into Sleep mode and the oscillator stops.
|
The Status Register
The Status register contains the arithmetic status of
the Arithmetic Logic Unit, the Reset status of the PIC and the Bank
Selection bits, direct and indirect. The bits of the Status register as
as follows:
Bit # |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Access |
R/W |
R/W |
R/W |
R |
R |
R/W |
R/W |
R/W |
Initial |
0 |
0 |
0 |
1 |
1 |
x |
x |
x |
Name |
IRP |
RP1 |
RP0 |
-TO |
-PD |
Z |
DC |
C |
Bit 0 - C: Carry/-Borrow
This bit is Readable and Writable and after a reset
it's value will be unknown. If an instruction executed has an effect
on this bit, then this bit becomes automatically and temporarily
Read Only. The Carry bit watches if a carry-out from the MSB bit
occurs. The values it can get are:
- 0: No carry-out from the MSB of the result
occurred
- 1: A carry-out from the MSB of the result
occurred
Bit 1 - DC: Digit Carry/-Borrow
This bit is Readable and Writable and after a reset
it's value will be unknown. If an instruction executed has an effect
on this bit, then this bit becomes automatically and temporarily
Read Only. The Digit Carry bit watches if a carry out from the 4th
lower order of the byte is occurred. The values it can get are:
- 0: No carry-out from 4th lower
order of the byte occurred
- 1: A carry-out from the 4th
lower order of the byte occurred
Bit 2 - Z: Zero
This bit is Readable and Writable and after a reset
it's value will be unknown. If an instruction executed has an effect
on this bit, then this bit becomes automatically and temporarily
Read Only. The Zero bit watches if the result of an arithmetic or
logic operation was zero. The values it can get are:
- 0: The result of an arithmetic or logic
operation was not zero
- 1: The result of an arithmetic or logic
operation was zero
Bit 3 - -PD: Power Down
This bit is Read Only and after a reset it will get
the value 1. The Power Down bit watches if the 'SLEEP' instruction
was executed. The values it can get are:
- 0: The 'SLEEP' instruction was executed
- 1: Power Up or the 'CLRWDT' instruction
was executed
Bit 4 - -TO: Time Out
This bit is Read Only and after a reset it will get
the value 1. The Power Down bit watches if a Watchdog timer time out
occurred. The values it can get are:
- 0: A Watchdog timer time out occurred
- 1: Power Up, 'SLEEP' or 'CLRWDT'
instruction was executed
Bit 6:5 - RP<1:0>: Register Bank Selection
Those bits are Readable and Writable and after a
reset it will all get the value 0. Their task is to select the
active Register Bank in use. The values it can get are:
- 00: Bank 0 is selected
- 01: Bank 1 is selected
- 10: Bank 2 is selected
- 11: Bank 3 is selected
Bit 7 - IRP: Register Bank Selection used with
indirect addressing
During the indeterminate pages of this book, the
indirect addressing shall be discussed and explained. The indirect
addressing is a way of accessing registers (General Purpose or
Special Function Registers) without directly accessing their memory
position, but throughout an indirect addressing register. When this
register is used, the current bank selected is different than the
indirect current bank selected. The values it can get are:
- 0: Indirect addressing current bank
selected is Bank 0 and Bank 1
- 1: Indirect addressing current bank
selected is Bank 2 and Bank 3
The Option_Reg Register
The Option_Reg register is a Readable and Writable
register that is used to control some modules of the PIC. The bits of
the Option_Reg are as follows:
Bit # |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Access |
R/W |
R/W |
R/W |
R/W |
R/W |
R/W |
R/W |
R/W |
Initial |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
Name |
-RBPU |
INTEDG |
TOCS |
TOSE |
PSA |
PS2 |
PS1 |
PS0 |
Bit <2:0> - PS<2:0>: Prescaler rate selection
Those bits are Readable and Writable and after a
reset they will get the value '1'. They are used to set the
Prescaler rate. The values it can get are:
Bit value |
TMR0 Rate |
WDT Rate |
000 |
1:2 |
1:1 |
001 |
1:4 |
1:2 |
010 |
1:8 |
1:4 |
011 |
1:16 |
1:8 |
100 |
1:32 |
1:16 |
101 |
1:64 |
1:32 |
110 |
1:128 |
1:64 |
111 |
1:256 |
1:128 |
Bit 3 - PSA: Prescaler Assignment
This bit is Readable and Writable and after a reset
it will get the value 1. This bit is used to assign the prescaler
to to the Watchdog timer or the Timer 0 module. The values it can
get are:
- 0: The prescaler is assigned to the Timer
0 module (TMR0)
- 1: The prescaler is assigned to the
Watchdog timer (WDT)
Bit 4 - TOSE: Timer 0 Source Edge Select
This bit is Readable and Writable and after a reset
it will get the value 1. It is used to select the RA4/TOCKI pin
clock edge (High to Low or Low to High) on which the Timer 0 will
count. The values it can get are:
- 0: Increment on Low to High
- 1: Increment on High to Low
Bit 5 - T0CS: Timer 0 Clock Source Select
This bit is Readable and Writable and after a reset
it will get the value 1. This bit will define the Timer 0 module
clock source. It can be either the RA4/TOCKI pin or the Internal
Instruction Cycle Clock (CLKO). The values it can get are:
- 0: Timer 0 clock source is the Internal
instruction cycle clock (CLKO)
- 1: Timer 0 clock source is the RA4/TOCKI
pin
Bit 6 - INTEDG: RB0/INT pin Interrupt Edge
Select
This bit is Readable and Writable and after a reset
it will get the value 1. By altering this bit, you can select the
RB0/INT pin pulse edge that the RB0/INT interrupt will occur. The
values it can get are:
- 0: The RB0/INT interrupt will occur on the
falling edge of the RB0/INT pin
- 1: The RB0/INT interrupt will occur on the
rising edge of the RB0/INT pin
Bit 7 - -RBPU: PORTB Pull-up Enable
This bit is Readable and Writable and after a reset
it will get the value 1. The RB ports have an internal programmable
pull-up resistor to minimize the use of external pull-up resistors
when needed. This bit will enable or disable those resistors. The
values it can get are:
- 0: The RB pull-up resistors are enabled
- 1: The RB pull-up resistors are disabled
The TRIS and PORT registers
The PIC12F629 has 8 pins with 5 I/O pins and one input-only pin.
The PIC16F628 has 18 pins with 15 I/O pins one input-only pin.
These pins are called PORT PINS.
The pins of the PIC12F629 are called General Purpose In Out pins -
abbreviated to GPIO.
And the pins of the PIC16F628 are separated into two sets of 8 pins,
called portA and portB.
Each pin can be changed to an input or an output at any time during the
running of a program and this is done by a file called TRIS. The name of
the file for the PIC12F629 is called TRISIO and for the PIC16F628, it is
called TRISA and TRISB.
When a bit in the TRIS register is "1" the corresponding bit in the
in/out file becomes an INPUT. When a bit in the TRIS file is "0" the
corresponding bit in the in/out file becomes an OUTPUT.
When a bit in the TRISIO register is "1" the corresponding bit in the
in/out file (this is called GPIO) becomes an INPUT. When a bit in the
TRISIO file is "0" the corresponding bit in the in/out file (this is
called GPIO) becomes an OUTPUT.
CONFIGURING TRISIO
For the PIC12F629 the TRIS file is called TRISIO and only the 6 lower
bits are used.
The TRISIO file is in bank1 (most of the other files are in bank0).
To get to bank1, the following instructions are needed:
|
bsf |
status,
rpo |
;Bank1 |
|
movlw |
b'xx000000' |
;(however
GP3 is input-only and will not become an output) |
|
movwf |
trisio |
;Write to TRISIO
register |
|
bcf |
status,
rpo |
;Bank0 |
CONFIGURING GPIO
GPIO is the actual port (consisting of 6 lines) in a PIC12F629, that
drive LEDs (up to 25mA per line) or can be configured as inputs.
If the lines have been configured as outputs, via TRISIO, they can now
be made either HIGH or LOW by defining the bits in GPIO, thus:
movlw b'xx110000'
movwf gpio
(however GP3 is input-only and will not become an output)
CONFIGURING TRISA
The PIC16F628 has 2 ports, PORTA and PORTB.
Suppose you
set TRISA to: b'11111111' PORTA will be all
inputs.
And if you set TRISA to: b'00000000' PORTA will be all
outputs.
The TRISA file is in bank1 (most of the other files are in bank0).
To get to bank1, the following instructions are needed:
|
bsf |
status,
rpo |
;Bank1 |
|
movlw |
b'00000000' |
;PORTA will be
all outputs. (however RA5 is input only and will not
become an output) |
|
movwf |
trisA |
;Write to TRISA
register |
|
bcf |
status,
rpo |
;Bank0 |
CONFIGURING PORTA
You can now make each line of PORTA either HIGH or LOW by defining
the bits, thus:
movlw b'11110000'
movwf portA
The 4 lower outputs will be LOW and the 4 upper lines will be HIGH.
(however RA5 is input only and will not go HIGH).
|