You are on page 1of 25

ECE230 Handout, Spring 2010 PIC16F8X

9.0 INSTRUCTION SET SUMMARY The instruction set is highly orthogonal and is grouped
into three basic categories:
Each PIC16CXX instruction is a 14-bit word divided
into an OPCODE which specifies the instruction type Byte-oriented operations
and one or more operands which further specify the Bit-oriented operations
operation of the instruction. The PIC16CXX instruction Literal and control operations
set summary in Table 9-2 lists byte-oriented, bit-ori-
All instructions are executed within one single instruc-
ented, and literal and control operations. Table 9-1
tion cycle, unless a conditional test is true or the pro-
shows the opcode field descriptions.
gram counter is changed as a result of an instruction.
For byte-oriented instructions, f represents a file reg- In this case, the execution takes two instruction cycles
ister designator and d represents a destination desig- with the second cycle executed as a NOP. One instruc-
nator. The file register designator specifies which file tion cycle consists of four oscillator periods. Thus, for
register is to be used by the instruction. an oscillator frequency of 4 MHz, the normal instruction
The destination designator specifies where the result of execution time is 1 s. If a conditional test is true or the
the operation is to be placed. If d is zero, the result is program counter is changed as a result of an instruc-
placed in the W register. If d is one, the result is placed tion, the instruction execution time is 2 s.
in the file register specified in the instruction. Table 9-2 lists the instructions recognized by the
For bit-oriented instructions, b represents a bit field MPASM assembler.
designator which selects the number of the bit affected Figure 9-1 shows the general formats that the instruc-
by the operation, while f represents the number of the tions can have.
file in which the bit is located.
Note: To maintain upward compatibility with
For literal and control operations, k represents an future PIC16CXX products, do not use the
eight or eleven bit constant or literal value. OPTION and TRIS instructions.
TABLE 9-1 OPCODE FIELD All examples use the following format to represent a
DESCRIPTIONS hexadecimal number:

Field Description 0xhh

f Register file address (0x00 to 0x7F) where h signifies a hexadecimal digit.


W Working register (accumulator)
b Bit address within an 8-bit file register FIGURE 9-1: GENERAL FORMAT FOR
k Literal field, constant data or label INSTRUCTIONS
x Dont care location (= 0 or 1) Byte-oriented file register operations
The assembler will generate code with x = 0. It is the 13 8 7 6 0
recommended form of use for compatibility with all OPCODE d f (FILE #)
Microchip software tools.
d = 0 for destination W
d Destination select; d = 0: store result in W,
d = 1 for destination f
d = 1: store result in file register f. f = 7-bit file register address
Default is d = 1
label Label name
Bit-oriented file register operations
TOS Top of Stack 13 10 9 7 6 0
PC Program Counter OPCODE b (BIT #) f (FILE #)
PCLATH Program Counter High Latch
GIE Global Interrupt Enable bit b = 3-bit bit address
f = 7-bit file register address
WDT Watchdog Timer/Counter
TO Time-out bit
Literal and control operations
PD Power-down bit
dest Destination either the W register or the specified General
register file location
13 8 7 0
[ ] Options
OPCODE k (literal)
( ) Contents
Assigned to k = 8-bit immediate value

<> Register bit field


CALL and GOTO instructions only
In the set of
13 11 10 0
italics User defined term (font is courier)
OPCODE k (literal)

k = 11-bit immediate value

1998 Microchip Technology Inc. DS30430C-page 55


PIC16F8X
TABLE 9-2 PIC16FXX INSTRUCTION SET
Mnemonic, Description Cycles 14-Bit Opcode Status Notes
Operands Affected
MSb LSb

BYTE-ORIENTED FILE REGISTER OPERATIONS


ADDWF f, d Add W and f 1 00 0111 dfff ffff C,DC,Z 1,2
ANDWF f, d AND W with f 1 00 0101 dfff ffff Z 1,2
CLRF f Clear f 1 00 0001 lfff ffff Z 2
CLRW - Clear W 1 00 0001 0xxx xxxx Z
COMF f, d Complement f 1 00 1001 dfff ffff Z 1,2
DECF f, d Decrement f 1 00 0011 dfff ffff Z 1,2
DECFSZ f, d Decrement f, Skip if 0 1(2) 00 1011 dfff ffff 1,2,3
INCF f, d Increment f 1 00 1010 dfff ffff Z 1,2
INCFSZ f, d Increment f, Skip if 0 1(2) 00 1111 dfff ffff 1,2,3
IORWF f, d Inclusive OR W with f 1 00 0100 dfff ffff Z 1,2
MOVF f, d Move f 1 00 1000 dfff ffff Z 1,2
MOVWF f Move W to f 1 00 0000 lfff ffff
NOP - No Operation 1 00 0000 0xx0 0000
RLF f, d Rotate Left f through Carry 1 00 1101 dfff ffff C 1,2
RRF f, d Rotate Right f through Carry 1 00 1100 dfff ffff C 1,2
SUBWF f, d Subtract W from f 1 00 0010 dfff ffff C,DC,Z 1,2
SWAPF f, d Swap nibbles in f 1 00 1110 dfff ffff 1,2
XORWF f, d Exclusive OR W with f 1 00 0110 dfff ffff Z 1,2
BIT-ORIENTED FILE REGISTER OPERATIONS
BCF f, b Bit Clear f 1 01 00bb bfff ffff 1,2
BSF f, b Bit Set f 1 01 01bb bfff ffff 1,2
BTFSC f, b Bit Test f, Skip if Clear 1 (2) 01 10bb bfff ffff 3
BTFSS f, b Bit Test f, Skip if Set 1 (2) 01 11bb bfff ffff 3
LITERAL AND CONTROL OPERATIONS
ADDLW k Add literal and W 1 11 111x kkkk kkkk C,DC,Z
ANDLW k AND literal with W 1 11 1001 kkkk kkkk Z
CALL k Call subroutine 2 10 0kkk kkkk kkkk
CLRWDT - Clear Watchdog Timer 1 00 0000 0110 0100 TO,PD
GOTO k Go to address 2 10 1kkk kkkk kkkk
IORLW k Inclusive OR literal with W 1 11 1000 kkkk kkkk Z
MOVLW k Move literal to W 1 11 00xx kkkk kkkk
RETFIE - Return from interrupt 2 00 0000 0000 1001
RETLW k Return with literal in W 2 11 01xx kkkk kkkk
RETURN - Return from Subroutine 2 00 0000 0000 1000
SLEEP - Go into standby mode 1 00 0000 0110 0011 TO,PD
SUBLW k Subtract W from literal 1 11 110x kkkk kkkk C,DC,Z
XORLW k Exclusive OR literal with W 1 11 1010 kkkk kkkk Z
Note 1: When an I/O register is modified as a function of itself ( e.g., MOVF PORTB, 1), the value used will be that value present
on the pins themselves. For example, if the data latch is 1 for a pin configured as input and is driven low by an external
device, the data will be written back with a 0.
2: If this instruction is executed on the TMR0 register (and, where applicable, d = 1), the prescaler will be cleared if assigned
to the Timer0 Module.
3: If Program Counter (PC) is modified or a conditional test is true, the instruction requires two cycles. The second cycle is
executed as a NOP.

DS30430C-page 56 1998 Microchip Technology Inc.


PIC16F8X
9.1 Instruction Descriptions

ADDLW Add Literal and W ANDLW AND Literal with W


Syntax: [label] ADDLW k Syntax: [label] ANDLW k
Operands: 0 k 255 Operands: 0 k 255
Operation: (W) + k (W) Operation: (W) .AND. (k) (W)
Status Affected: C, DC, Z Status Affected: Z
Encoding: 11 111x kkkk kkkk Encoding: 11 1001 kkkk kkkk

Description: The contents of the W register are Description: The contents of W register are
added to the eight bit literal k and the ANDed with the eight bit literal 'k'. The
result is placed in the W register. result is placed in the W register.
Words: 1 Words: 1
Cycles: 1 Cycles: 1
Q Cycle Activity: Q1 Q2 Q3 Q4 Q Cycle Activity: Q1 Q2 Q3 Q4
Decode Read Process Write to Decode Read Process Write to
literal k data W literal "k" data W

Example: ADDLW 0x15 Example ANDLW 0x5F

Before Instruction Before Instruction


W = 0x10 W = 0xA3
After Instruction After Instruction
W = 0x25 W = 0x03

ADDWF Add W and f ANDWF AND W with f


Syntax: [label] ADDWF f,d Syntax: [label] ANDWF f,d
Operands: 0 f 127 Operands: 0 f 127
d [0,1] d [0,1]
Operation: (W) + (f) (destination) Operation: (W) .AND. (f) (destination)
Status Affected: C, DC, Z Status Affected: Z
Encoding: 00 0111 dfff ffff Encoding: 00 0101 dfff ffff
Description: Add the contents of the W register with Description: AND the W register with register 'f'. If 'd'
register f. If d is 0 the result is stored is 0 the result is stored in the W regis-
in the W register. If d is 1 the result is ter. If 'd' is 1 the result is stored back in
stored back in register f. register 'f'.
Words: 1 Words: 1
Cycles: 1 Cycles: 1
Q Cycle Activity: Q1 Q2 Q3 Q4 Q Cycle Activity: Q1 Q2 Q3 Q4
Decode Read Process Write to Decode Read Process Write to
register data destination register data destination
f f

Example ADDWF FSR, 0 Example ANDWF FSR, 1


Before Instruction Before Instruction
W = 0x17 W = 0x17
FSR = 0xC2 FSR = 0xC2
After Instruction After Instruction
W = 0xD9 W = 0x17
FSR = 0xC2 FSR = 0x02

1998 Microchip Technology Inc. DS30430C-page 57


PIC16F8X

BCF Bit Clear f BTFSC Bit Test, Skip if Clear


Syntax: [label] BCF f,b Syntax: [label] BTFSC f,b
Operands: 0 f 127 Operands: 0 f 127
0b7 0b7
Operation: 0 (f<b>) Operation: skip if (f<b>) = 0
Status Affected: None Status Affected: None
Encoding: 01 00bb bfff ffff Encoding: 01 10bb bfff ffff
Description: Bit b in register f is cleared. Description: If bit b in register f is 1 then the next
instruction is executed.
Words: 1 If bit b, in register f, is 0 then the next
Cycles: 1 instruction is discarded, and a NOP is
executed instead, making this a 2TCY
Q Cycle Activity: Q1 Q2 Q3 Q4
instruction.
Decode Read Process Write
register data register f Words: 1
f
Cycles: 1(2)
Q Cycle Activity: Q1 Q2 Q3 Q4
Example BCF FLAG_REG, 7
Decode Read Process No-Operat
Before Instruction register f data ion
FLAG_REG = 0xC7
After Instruction If Skip: (2nd Cycle)
FLAG_REG = 0x47 Q1 Q2 Q3 Q4
No-Operati No-Opera No-Operat
No-Operat on tion ion
ion

Example HERE BTFSC FLAG,1


FALSE GOTO PROCESS_CODE
TRUE


Before Instruction
PC = address HERE
After Instruction
BSF Bit Set f if FLAG<1> = 0,
PC = address TRUE
Syntax: [label] BSF f,b if FLAG<1>=1,
Operands: 0 f 127 PC = address FALSE
0b7
Operation: 1 (f<b>)
Status Affected: None
Encoding: 01 01bb bfff ffff
Description: Bit b in register f is set.
Words: 1
Cycles: 1
Q Cycle Activity: Q1 Q2 Q3 Q4
Decode Read Process Write
register data register f
f

Example BSF FLAG_REG, 7


Before Instruction
FLAG_REG = 0x0A
After Instruction
FLAG_REG = 0x8A

DS30430C-page 58 1998 Microchip Technology Inc.


PIC16F8X

BTFSS Bit Test f, Skip if Set CALL Call Subroutine


Syntax: [label] BTFSS f,b Syntax: [ label ] CALL k
Operands: 0 f 127 Operands: 0 k 2047
0b<7
Operation: (PC)+ 1 TOS,
Operation: skip if (f<b>) = 1 k PC<10:0>,
Status Affected: None (PCLATH<4:3>) PC<12:11>

Encoding: 01 11bb bfff ffff Status Affected: None


Description: If bit b in register f is 0 then the next Encoding: 10 0kkk kkkk kkkk
instruction is executed.
If bit b is 1, then the next instruction is Description: Call Subroutine. First, return address
(PC+1) is pushed onto the stack. The
discarded and a NOP is executed eleven bit immediate address is loaded
instead, making this a 2TCY instruction.
into PC bits <10:0>. The upper bits of
Words: 1 the PC are loaded from PCLATH. CALL
is a two cycle instruction.
Cycles: 1(2)
Words: 1
Q Cycle Activity: Q1 Q2 Q3 Q4
Cycles: 2
Decode Read Process No-Operat
register f data ion Q Cycle Activity: Q1 Q2 Q3 Q4
1st Cycle Decode Read Process Write to
If Skip: (2nd Cycle) literal k, data PC
Q1 Q2 Q3 Q4 Push PC
to Stack
No-Operati No-Opera No-Operat
No-Operat on tion ion 2nd Cycle No-Opera No-Opera No-Operat
No-Opera tion tion ion
ion
tion

Example HERE BTFSC FLAG,1


Example HERE CALL THERE
FALSE GOTO PROCESS_CODE
TRUE Before Instruction
PC = Address HERE
After Instruction
Before Instruction PC = Address THERE
PC = address HERE TOS = Address HERE+1
After Instruction
if FLAG<1> = 0,
PC = address FALSE
if FLAG<1> = 1,
PC = address TRUE

1998 Microchip Technology Inc. DS30430C-page 59


PIC16F8X

CLRF Clear f CLRW Clear W


Syntax: [label] CLRF f Syntax: [ label ] CLRW
Operands: 0 f 127 Operands: None
Operation: 00h (f) Operation: 00h (W)
1Z 1Z
Status Affected: Z Status Affected: Z
Encoding: 00 0001 1fff ffff
Encoding: 00 0001 0xxx xxxx
Description: The contents of register f are cleared
Description: W register is cleared. Zero bit (Z) is
and the Z bit is set.
set.
Words: 1 Words: 1
Cycles: 1 Cycles: 1
Q Cycle Activity: Q1 Q2 Q3 Q4 Q Cycle Activity: Q1 Q2 Q3 Q4
Decode Read Process Write
Decode No-Opera Process Write to
register data register f
tion data W
f

Example CLRF FLAG_REG Example CLRW

Before Instruction Before Instruction


FLAG_REG = 0x5A W = 0x5A
After Instruction After Instruction
FLAG_REG = 0x00 W = 0x00
Z = 1
Z = 1

CLRWDT Clear Watchdog Timer


Syntax: [ label ] CLRWDT
Operands: None
Operation: 00h WDT
0 WDT prescaler,
1 TO
1 PD
Status Affected: TO, PD
Encoding: 00 0000 0110 0100
Description: CLRWDT instruction resets the Watch-
dog Timer. It also resets the prescaler
of the WDT. Status bits TO and PD are
set.
Words: 1
Cycles: 1
Q Cycle Activity: Q1 Q2 Q3 Q4
Decode No-Opera Process Clear
tion data WDT
Counter

Example CLRWDT
Before Instruction
WDT counter = ?
After Instruction
WDT counter = 0x00
WDT prescaler= 0
TO = 1
PD = 1

DS30430C-page 60 1998 Microchip Technology Inc.


PIC16F8X

COMF Complement f DECFSZ Decrement f, Skip if 0


Syntax: [ label ] COMF f,d Syntax: [ label ] DECFSZ f,d
Operands: 0 f 127 Operands: 0 f 127
d [0,1] d [0,1]
Operation: (f) (destination) Operation: (f) - 1 (destination);
Status Affected: Z skip if result = 0
Encoding: 00 1001 dfff ffff Status Affected: None
Description: The contents of register f are comple- Encoding: 00 1011 dfff ffff
mented. If d is 0 the result is stored in
W. If d is 1 the result is stored back in Description: The contents of register f are decre-
register f. mented. If d is 0 the result is placed in the
W register. If d is 1 the result is placed
Words: 1 back in register f.
If the result is 1, the next instruction, is
Cycles: 1 executed. If the result is 0, then a NOP is
executed instead making it a 2TCY instruc-
Q Cycle Activity: Q1 Q2 Q3 Q4 tion.
Decode Read Process Write to Words: 1
register data destination
f Cycles: 1(2)
Q Cycle Activity: Q1 Q2 Q3 Q4
Example COMF REG1,0 Decode Read Process Write to
register f data destination
Before Instruction
REG1 = 0x13
If Skip: (2nd Cycle)
After Instruction
REG1 = 0x13 Q1 Q2 Q3 Q4
W = 0xEC No-Opera No-Operat No-Operati
No-Operat tion ion on
ion
DECF Decrement f
Syntax: [label] DECF f,d Example HERE DECFSZ CNT, 1
Operands: 0 f 127 GOTO LOOP
d [0,1] CONTINUE

Operation: (f) - 1 (destination)

Status Affected: Z Before Instruction


PC = address HERE
Encoding: 00 0011 dfff ffff After Instruction
Description: Decrement register f. If d is 0 the CNT = CNT - 1
result is stored in the W register. If d is if CNT = 0,
1 the result is stored back in register f. PC = address CONTINUE
Words: 1 if CNT 0,
PC = address HERE+1
Cycles: 1
Q Cycle Activity: Q1 Q2 Q3 Q4
Decode Read Process Write to
register data destination
f

Example DECF CNT, 1


Before Instruction
CNT = 0x01
Z = 0
After Instruction
CNT = 0x00
Z = 1

1998 Microchip Technology Inc. DS30430C-page 61


PIC16F8X

GOTO Unconditional Branch INCF Increment f


Syntax: [ label ] GOTO k Syntax: [ label ] INCF f,d
Operands: 0 k 2047 Operands: 0 f 127
d [0,1]
Operation: k PC<10:0>
PCLATH<4:3> PC<12:11> Operation: (f) + 1 (destination)
Status Affected: None Status Affected: Z
Encoding: 10 1kkk kkkk kkkk Encoding: 00 1010 dfff ffff

Description: GOTO is an unconditional branch. The Description: The contents of register f are incre-
eleven bit immediate value is loaded mented. If d is 0 the result is placed in
into PC bits <10:0>. The upper bits of the W register. If d is 1 the result is
PC are loaded from PCLATH<4:3>.
GOTO is a two cycle instruction. placed back in register f.

Words: 1 Words: 1

Cycles: 2 Cycles: 1

Q Cycle Activity: Q1 Q2 Q3 Q4 Q Cycle Activity: Q1 Q2 Q3 Q4


Decode Read Process Write to
1st Cycle Decode Read Process Write to
register data destination
literal k data PC
f
2nd Cycle No-Operat No-Opera No-Operat
No-Operat ion tion ion
ion Example INCF CNT, 1
Before Instruction
Example GOTO THERE CNT = 0xFF
Z = 0
After Instruction
PC = Address THERE
After Instruction
CNT = 0x00
Z = 1

DS30430C-page 62 1998 Microchip Technology Inc.


PIC16F8X

INCFSZ Increment f, Skip if 0 IORLW Inclusive OR Literal with W


Syntax: [ label ] INCFSZ f,d Syntax: [ label ] IORLW k
Operands: 0 f 127 Operands: 0 k 255
d [0,1] Operation: (W) .OR. k (W)
Operation: (f) + 1 (destination), Status Affected: Z
skip if result = 0
Encoding: 11 1000 kkkk kkkk
Status Affected: None
Description: The contents of the W register is
Encoding: 00 1111 dfff ffff ORed with the eight bit literal 'k'. The
Description: The contents of register f are incre- result is placed in the W register.
mented. If d is 0 the result is placed in
the W register. If d is 1 the result is Words: 1
placed back in register f.
If the result is 1, the next instruction is Cycles: 1
executed. If the result is 0, a NOP is exe-
cuted instead making it a 2TCY instruc- Q Cycle Activity: Q1 Q2 Q3 Q4
tion. Decode Read Process Write to
Words: 1 literal k data W

Cycles: 1(2)
Example IORLW 0x35
Q Cycle Activity: Q1 Q2 Q3 Q4
Before Instruction
Decode Read Process Write to
W = 0x9A
register f data destination
After Instruction
If Skip: (2nd Cycle) W = 0xBF
Z = 1
Q1 Q2 Q3 Q4
No-Opera No-Opera No-Operati
No-Operat tion tion on
ion

Example HERE INCFSZ CNT, 1


GOTO LOOP
CONTINUE


Before Instruction
PC = address HERE
After Instruction
CNT = CNT + 1
if CNT= 0,
PC = address CONTINUE
if CNT 0,
PC = address HERE +1

1998 Microchip Technology Inc. DS30430C-page 63


PIC16F8X

IORWF Inclusive OR W with f MOVLW Move Literal to W


Syntax: [ label ] IORWF f,d Syntax: [ label ] MOVLW k
Operands: 0 f 127 Operands: 0 k 255
d [0,1]
Operation: k (W)
Operation: (W) .OR. (f) (destination)
Status Affected: None
Status Affected: Z
Encoding: 11 00xx kkkk kkkk
Encoding: 00 0100 dfff ffff
Description: The eight bit literal k is loaded into W
Description: Inclusive OR the W register with regis- register. The dont cares will assemble
ter f. If d is 0 the result is placed in the
as 0s.
W register. If d is 1 the result is placed
back in register f. Words: 1
Words: 1 Cycles: 1
Cycles: 1 Q Cycle Activity: Q1 Q2 Q3 Q4
Q Cycle Activity: Q1 Q2 Q3 Q4 Decode Read Process Write to
literal k data W
Decode Read Process Write to
register data destination
f
Example MOVLW 0x5A
After Instruction
Example IORWF RESULT, 0
W = 0x5A
Before Instruction
RESULT = 0x13
W = 0x91
After Instruction
RESULT = 0x13
W = 0x93
Z = 1

MOVWF Move W to f
MOVF Move f
Syntax: [ label ] MOVWF f
Syntax: [ label ] MOVF f,d
Operands: 0 f 127
Operands: 0 f 127
d [0,1] Operation: (W) (f)
Operation: (f) (destination) Status Affected: None
Status Affected: Z Encoding: 00 0000 1fff ffff

Encoding: 00 1000 dfff ffff Description: Move data from W register to register
'f'.
Description: The contents of register f is moved to a
destination dependant upon the status Words: 1
of d. If d = 0, destination is W register. If
Cycles: 1
d = 1, the destination is file register f
itself. d = 1 is useful to test a file regis- Q Cycle Activity: Q1 Q2 Q3 Q4
ter since status flag Z is affected. Decode Read Process Write
Words: 1 register data register f
f
Cycles: 1
Q Cycle Activity: Q1 Q2 Q3 Q4 Example MOVWF OPTION_REG
Decode Read Process Write to Before Instruction
register data destination
OPTION = 0xFF
f
W = 0x4F
After Instruction
Example MOVF FSR, 0 OPTION = 0x4F
After Instruction W = 0x4F
W = value in FSR register
Z =1

DS30430C-page 64 1998 Microchip Technology Inc.


PIC16F8X

NOP No Operation RETFIE Return from Interrupt


Syntax: [ label ] NOP Syntax: [ label ] RETFIE
Operands: None Operands: None
Operation: No operation Operation: TOS PC,
Status Affected: None 1 GIE

Encoding: 00 0000 0xx0 0000 Status Affected: None

Description: No operation. Encoding: 00 0000 0000 1001

Words: 1 Description: Return from Interrupt. Stack is POPed


and Top of Stack (TOS) is loaded in the
Cycles: 1 PC. Interrupts are enabled by setting
Global Interrupt Enable bit, GIE
Q Cycle Activity: Q1 Q2 Q3 Q4
(INTCON<7>). This is a two cycle
Decode No-Opera No-Opera No-Operat instruction.
tion tion ion
Words: 1
Example NOP Cycles: 2
Q Cycle Activity: Q1 Q2 Q3 Q4
1st Cycle Decode No-Opera Set the Pop from
tion GIE bit the Stack

2nd Cycle No-Opera No-Opera No-Operat


No-Operat tion tion ion
ion

Example RETFIE
After Interrupt
PC = TOS
GIE = 1
OPTION Load Option Register
Syntax: [ label ] OPTION
Operands: None
Operation: (W) OPTION
Status Affected: None
Encoding: 00 0000 0110 0010
Description: The contents of the W register are
loaded in the OPTION register. This
instruction is supported for code com-
patibility with PIC16C5X products.
Since OPTION is a readable/writable
register, the user can directly address
it.
Words: 1
Cycles: 1
Example
To maintain upward compatibility
with future PIC16CXX products,
do not use this instruction.

1998 Microchip Technology Inc. DS30430C-page 65


PIC16F8X

RETLW Return with Literal in W RETURN Return from Subroutine


Syntax: [ label ] RETLW k Syntax: [ label ] RETURN
Operands: 0 k 255 Operands: None
Operation: k (W); Operation: TOS PC
TOS PC Status Affected: None
Status Affected: None Encoding: 00 0000 0000 1000
Encoding: 11 01xx kkkk kkkk
Description: Return from subroutine. The stack is
Description: The W register is loaded with the eight POPed and the top of the stack (TOS)
bit literal k. The program counter is is loaded into the program counter. This
loaded from the top of the stack (the is a two cycle instruction.
return address). This is a two cycle Words: 1
instruction.
Cycles: 2
Words: 1
Q Cycle Activity: Q1 Q2 Q3 Q4
Cycles: 2
1st Cycle Decode No-Opera No-Opera Pop from
Q Cycle Activity: Q1 Q2 Q3 Q4 tion tion the Stack

1st Cycle Decode Read No-Opera Write to 2nd Cycle No-Opera No-Opera No-Opera
literal k tion W, Pop No-Operat tion tion tion
from the ion
Stack

2nd Cycle No-Opera No-Opera No-Operat


Example RETURN
No-Operat tion tion ion
ion After Interrupt
PC = TOS
Example CALL TABLE ;W contains table
;offset value
;W now has table value


TABLE ADDWF PC ;W = offset
RETLW k1 ;Begin table
RETLW k2 ;



RETLW kn ; End of table

Before Instruction
W = 0x07
After Instruction
W = value of k8

DS30430C-page 66 1998 Microchip Technology Inc.


PIC16F8X

RLF Rotate Left f through Carry RRF Rotate Right f through Carry
Syntax: [ label ] RLF f,d Syntax: [ label ] RRF f,d
Operands: 0 f 127 Operands: 0 f 127
d [0,1] d [0,1]
Operation: See description below Operation: See description below
Status Affected: C Status Affected: C
Encoding: 00 1101 dfff ffff Encoding: 00 1100 dfff ffff
Description: The contents of register f are rotated Description: The contents of register f are rotated
one bit to the left through the Carry one bit to the right through the Carry
Flag. If d is 0 the result is placed in the Flag. If d is 0 the result is placed in the
W register. If d is 1 the result is stored W register. If d is 1 the result is placed
back in register f. back in register f.
C Register f C Register f

Words: 1 Words: 1
Cycles: 1 Cycles: 1
Q Cycle Activity: Q1 Q2 Q3 Q4 Q Cycle Activity: Q1 Q2 Q3 Q4
Decode Read Process Write to Decode Read Process Write to
register data destination register data destination
f f

Example RLF REG1,0 Example RRF REG1,0


Before Instruction Before Instruction
REG1 = 1110 0110 REG1 = 1110 0110
C = 0 C = 0
After Instruction After Instruction
REG1 = 1110 0110 REG1 = 1110 0110
W = 1100 1100 W = 0111 0011
C = 1 C = 0

1998 Microchip Technology Inc. DS30430C-page 67


PIC16F8X

SLEEP SUBLW Subtract W from Literal

Syntax: [ label ] SLEEP Syntax: [ label ] SUBLW k


Operands: None Operands: 0 k 255
Operation: 00h WDT, Operation: k - (W) (W)
0 WDT prescaler, Status Affected: C, DC, Z
1 TO,
Encoding: 11 110x kkkk kkkk
0 PD
Description: The W register is subtracted (2s comple-
Status Affected: TO, PD ment method) from the eight bit literal 'k'.
Encoding: 00 0000 0110 0011 The result is placed in the W register.
Description: The power-down status bit, PD is Words: 1
cleared. Time-out status bit, TO is
Cycles: 1
set. Watchdog Timer and its pres-
caler are cleared. Q Cycle Activity: Q1 Q2 Q3 Q4
The processor is put into SLEEP Decode Read Process Write to W
mode with the oscillator stopped. See literal k data
Section 14.8 for more details.
Words: 1 Example 1: SUBLW 0x02
Cycles: 1 Before Instruction
Q Cycle Activity: Q1 Q2 Q3 Q4 W = 1
Decode No-Opera No-Opera Go to C = ?
tion tion Sleep Z = ?
After Instruction
Example: SLEEP W = 1
C = 1; result is positive
Z = 0
Example 2: Before Instruction
W = 2
C = ?
Z = ?
After Instruction
W = 0
C = 1; result is zero
Z = 1
Example 3: Before Instruction
W = 3
C = ?
Z = ?
After Instruction
W = 0xFF
C = 0; result is negative
Z = 0

DS30430C-page 68 1998 Microchip Technology Inc.


PIC16F8X

SUBWF Subtract W from f SWAPF Swap Nibbles in f


Syntax: [ label ] SUBWF f,d Syntax: [ label ] SWAPF f,d
Operands: 0 f 127 Operands: 0 f 127
d [0,1] d [0,1]
Operation: (f) - (W) (destination) Operation: (f<3:0>) (destination<7:4>),
(f<7:4>) (destination<3:0>)
Status Affected: C, DC, Z
Status Affected: None
Encoding: 00 0010 dfff ffff
Encoding: 00 1110 dfff ffff
Description: Subtract (2s complement method) W reg-
ister from register 'f'. If 'd' is 0 the result is Description: The upper and lower nibbles of register
stored in the W register. If 'd' is 1 the 'f' are exchanged. If 'd' is 0 the result is
result is stored back in register 'f'. placed in W register. If 'd' is 1 the result
is placed in register 'f'.
Words: 1
Words: 1
Cycles: 1
Cycles: 1
Q Cycle Activity: Q1 Q2 Q3 Q4
Decode Read Process Write to
Q Cycle Activity: Q1 Q2 Q3 Q4
register f data destination Decode Read Process Write to
register f data destination

Example 1: SUBWF REG1,1


Example SWAPF REG, 0
Before Instruction
REG1 = 3
Before Instruction
W = 2 REG1 = 0xA5
C = ?
Z = ?
After Instruction
REG1 = 0xA5
After Instruction
W = 0x5A
REG1 = 1
W = 2
C = 1; result is positive
Z = 0
Example 2: Before Instruction TRIS Load TRIS Register
REG1 = 2 Syntax: [label] TRIS f
W = 2
Operands: 5f7
C = ?
Z = ? Operation: (W) TRIS register f;
After Instruction Status Affected: None
REG1 = 0 Encoding: 00 0000 0110 0fff
W = 2 Description: The instruction is supported for code
C = 1; result is zero compatibility with the PIC16C5X prod-
Z = 1 ucts. Since TRIS registers are read-
Example 3: Before Instruction able and writable, the user can directly
address them.
REG1 = 1
W = 2
Words: 1
C = ? Cycles: 1
Z = ? Example
After Instruction To maintain upward compatibility
REG1 = 0xFF with future PIC16CXX products,
W = 2 do not use this instruction.
C = 0; result is negative
Z = 0

1998 Microchip Technology Inc. DS30430C-page 69


PIC16F8X

XORLW Exclusive OR Literal with W XORWF Exclusive OR W with f

Syntax: [label] XORLW k Syntax: [label] XORWF f,d

Operands: 0 k 255 Operands: 0 f 127


d [0,1]
Operation: (W) .XOR. k (W)
Operation: (W) .XOR. (f) (destination)
Status Affected: Z
Status Affected: Z
Encoding: 11 1010 kkkk kkkk
Encoding: 00 0110 dfff ffff
Description: The contents of the W register are
XORed with the eight bit literal 'k'. Description: Exclusive OR the contents of the W
The result is placed in the W regis- register with register 'f'. If 'd' is 0 the
ter. result is stored in the W register. If 'd' is
1 the result is stored back in register 'f'.
Words: 1
Words: 1
Cycles: 1
Cycles: 1
Q Cycle Activity: Q1 Q2 Q3 Q4
Q Cycle Activity: Q1 Q2 Q3 Q4
Decode Read Process Write to
literal k data W Decode Read Process Write to
register data destination
f
Example: XORLW 0xAF
Before Instruction Example XORWF REG 1
W = 0xB5 Before Instruction
After Instruction REG = 0xAF
W = 0x1A W = 0xB5
After Instruction
REG = 0x1A
W = 0xB5

DS30430C-page 70 1998 Microchip Technology Inc.


Programming the PIC16F84
(With Permission from Stan Ockers at ockers@anl.gov)

PIC MICROCONTROLLERS:

When studying the PIC series of microcontrollers, the first thing to realize is that the architecture is
completely different from anything you are probably used to. This makes understanding the PIC quite
confusing at first. You are probably familiar with the spinal cord type of computer with memory, cpu
and perpherial chips hooked in parallel to the same data and address bus. The PIC chips have two
separate 'data' busses, one for instructions and one for everything else. Instructions are essentially in
ROM and dedicate the microcontroller to doing one task. There is very little RAM, a few dozen bytes,
and this is reserved for variables operated on by the program. There is also very little 'data' storage,
again a few dozen bytes, and this is in EEPROM which is slow and clumsy to change.

TYPES OF PIC's:

There are a dozen or so I/O pins on the PIC which can be configured as inputs or outputs. When outputs,
they have to strength to drive LED's directly. A couple of the I/O pins are used to program the internal
ROM serially with an external programmer. These are the OTP, (One Time Programmable), chips.
There are also similar chips with UV erasable EPROM's used for prototyping at about three times the
price. Then there is one series that is of special interest to the hobbyist, the 16F84, (C84,83), chips
which have electrically reprogramable EEPROM memory for instructions. These can be reprogrammed
hundreds of times. There have been many programmers designed for this series, one of the simplist
appeared in the Sept. '98 issue of 'Electronic Now'.

ROM INSTRUCTION MEMORY:

In the 16F84 instructions are 14 bits wide and stored in EEPROM. There is a maximum of 1024 of
these. It is impossible to modify these instructions except through external programming. You can't have
self modifying code. When the chip is reset, a program counter is set to zero and instructions are
executed from there. The program is retained when power is removed from the chip.

RAM MEMORY:

Besides the 14 bit program bus there is another 8 bit data bus in the PIC connected to registers, ports,
timer etc. There are 80 RAM locations in the 16F84. RAM is where you put your variables. The only
way to change these RAM locations is through instructions. You don't load RAM from outside as in a
'regular' computer. The information in RAM disappears when power is removed. The first 12 RAM
locations, ($00 - $0B), have internal registers mapped to them. Changing these locations with
instructions changes the corresponding registers. Microchip calls RAM locations 'files' or 'registers' and
uses the symbol 'f' when referring to them. The remaining 68 locations can be used for your variables.
Microchip calls the first 12 locations special function registers and the remaining 68 general purpose
registers.

Programming the PIC16F84 Microcontroller by Stan Ockers Page 1


BANKED RAM MEMORY:

Five special function registers are not among the first twelve addresses, not even among the 80 .
Because of something called 'banking' you have to set a bit in the byte at RAM location 3 to reach them.
This location is called STATUS and the bit, (bit 5), is called RP0. If RP0 is zero you are in bank 0, if it
is 1 you are in bank 1. For your own variables it doesn't matter which bank is in use because they are
mapped to both banks. For some of the first 12 locations it does matter. Seven of the 12 are mapped to
both banks but five are not; so location 5 for example has two meanings depending on RP0. If RP0 is
clear, ( bank 0 ), location 5 refers to the data on PORT A. IF RP0 is set, ( bank 1 ), location 5 refers to
the direction register TRISA that tells which bits of PORTA are inputs and which are outputs.

Much of this complication can be avoided by using two instructions that Microchip indicates it might
not support in future products. The TRIS instruction can be used to set the port direction registers and
OPTION can be used to set the OPTION register which deals mainly with timer operations. If you port
your code to future Microchip processors that don't support these instructions, you will probably want to
rewrite the code for some other reason anyway.

EEPROM MEMORY:

There is a third type of memory in the 16F84, 64 bytes of electrically reprogrammable memory, ( 8 bit ).
This could be used to hold values you would like to remember when the power is turned off. There are a
couple of difficulties. First, the memory is not directly addressable; you have to work indirectly through
four of the special function registers. Secondly, it takes a few hundredths of a second to 'burn' the
information in so it isn't real fast memory like RAM. This memory can also be burned in when you burn
in program memory.

INSTRUCTIONS:

The small instruction set, (37 instructions), and the 14 bit size of instructions lead to a number of
compromises. For one thing you can't have two registers specified in a single instruction. Each register
takes 7 bits to specify its address, but you also have to specify the instruction number and what to do.
The solution is to run almost everything through 'W' or working register which is internal to the
processor and doesn't have an address. A register to register transfer would take two instructions.
Suppose you had a pattern of LED segments to be lit in the variable PATTERN and want to move it to
PORTB to light the segments:

MOVF PATTERN, W ; copy the contents of PATTERN into the working


; register
MOVWF PORTB ; copy the contents of W into Port B

The first instruction is of the form MOV f,d which moves the register 'f' to the destination 'd', ('W' in this
case). The second instruction simply moves whatever is in 'W' into the register 'f', ( MOVWF, f ).
PATTERN remains unchanged in the first instruction and W remains unchanged in the second. Maybe it
is more like a copy than a move.

Programming the PIC16F84 Microcontroller by Stan Ockers Page 2


You might think you could get away with one instruction with literals. Literals ,(k), are 8 bits (0-255).
Instructions with literals have no room to specify a register, you must use 'W'. Loading a register with a
literal also takes two instructions:

MOVLW $AA ; put the pattern 10101010 into W


MOVWF PATTERN ; put W into the register PATTERN

The same applies when literals are used in addition, subtraction and the logical functions AND, IOR
,(inclusive OR) and XOR ,(exclusive OR); all involve two instructions:

MOVLW k ; move literal into 'W'


SUBWF f,d ; put the result of subtracting W from f into d
; d could be either W or f
; if it's W then f is not changed
; if it's f then W is unaffected

Suppose we wanted to zero out the lower nibble of PATTERN:

MOVLW $F0 ; set up mask


ANDWF PATTERN, f ; result of PATTERN AND $F0 is placed in PATTERN
; note that the destination could be W if we
; want the changed pattern to end up there

IF the value to be changed is already in W and the destination is W, a single instruction will work:
ADDLW k, SUBLW k, ANDLW k, IORLW k and XORLW k.

Single operand instructions are easy to understand:

CLRF f ; set all bits in register f to zero, (clear register f)


CLRW ; set all bits in register W to zero, (clear working register)
BCF f,b ; set bit b in register f to zero, (bit clear bit b in f)
BSF f,b ; set bit b in register f to one, (bit set bit b in f)

THINGS TO WATCH:

Small errors are easy to make and can cause hours of wasted time. Here are some that can cause
problems:

Many instructions in a program are MOV instructions and involve 'W'. It is very easy to confuse loading
a register with W and loading W with a register.

MOVWF f ; W IS MOVED TO THE REGISTER f, ( f is changed )

MOVF f, W ; THE REGISTER f IS MOVED TO W, ( W is changed )

MOVF f, f ; THE REGISTER f IS MOVED TO ITSELF


; f is not changed but flags may be set

Note that MOVWF is the only 'WF' instruction that doesn't have a choice of destination. It's always 'f'.
The other 'WF' instructions are ADDWF, SUBWF, ANDWF, SWAPWF, IORWF & XORWF. In all

Programming the PIC16F84 Microcontroller by Stan Ockers Page 3


of these cases one of 'W' or 'f' will be changed and the other not according to the destination. Also
remember in SUBWF that 'W' is subtracted from 'f'. Other instructions where the destination is changed
include:

INC f,d ; put the value of register f + 1 in either W or f


DEC f,d ; put the value of register f - 1 in either W or f
COMP f,d ; put the result of toggling all bits of f in destination d
SWAP f,d ; put the result of swapping nibbles in f into d
RLF f,d ; the result of rotating f left thru carry goes into d
RRF f,d ; the result of rotating f right thru carry goes into d

If the destination is 'W' then only 'W' is affected; the original register remains the same.

IN SUBLW k, 'W' is subtracted from the literal 'k'.

It is easy to code GOTO when you meant to code CALL and vice-versa. You might think that this would
cause your program to lock up but many times it just makes it act strangely instead.

Beware of using the same registers in two different routines, especially if one calls the other. For
example if you use TEMP in a timing loop and then use TEMP in a subroutine that calls the timing loop,
you might overlook the fact that the timing loop is changing TEMP.

The rotate instructions, ( RLF,RRF ), are rotates through carry so carry has to be set up prior to the
instruction and rotates into the low or high order bit. Likewise the hi or low order bit rotates into carry.

FLOW CONTROL:

Normally a program will start with instruction 0 and skip to the next as each is executed. Instructions
which change this involve a program counter. 'GOTO 666' would set the program counter to 666 and the
instruction at location 666 would be executed next. 'CALL 666' on the other hand would first push the
next location on the stack and then set the program counter to 666. Instructions after 666 would be
executed until a RETURN ,RETLW k or RETIE instruction is encountered:

RETURN - return from call, location of next instruction is


popped from the stack and put into the program counter
RETLW k - as RETURN but literal k is also placed into W
RETIE - as RETURN but interrupts are also enabled

The stack consists of eight words and is circular, after the eighth word it rolls over to the first. Calls can
be nested only eight deep. There is no push or pop instruction to access the stack directly.

There are four other flow instructions ,( beside CALL and GOTO ), which might be called 'skip it'
instructions:

INCFSZ f,d - put f + 1 into either W or f. skips over the next


instruction if the result of the increment is zero
DECFSZ f,d - put f - 1 into either W or f. skips over the next
instruction if the result of the decrement is zero
BTFSC f,b - tests bit b of register f, skip next instruction if

Programming the PIC16F84 Microcontroller by Stan Ockers Page 4


the bit is zero (bit test skip clear). doesn't
change bit
BTFSS f,b - tests bit b of register f, skip next instruction if
the bit is one (bit test skip set). doesn't change bit

INPUT/OUTPUT PORTS:

The 16F84 has 13 pins that can be individually configured as either inputs or outputs. They a divided
into PORTA, (5 bits), and PORTB, (8 bits). The direction of each bit is determined by the bits in the
corresponding direction registers TRISA and TRISB. A zero means the bit will be an output, a 1 means
input. To set up PORTB with alternating inputs and outputs:

MOVLW $AA ; port pattern '10101010'


TRIS TRISB ; W is placed into register TRISB

Certain port pins are also hooked to other functions of the processor. The high 4 bits of PORTB can be
used as interrupt pins when they are programmed as inputs. The high bit of PORTA is also used as an
external clock input for the counter/timer. Bit 0 of PORTB (RB0/INT) can be used for an external
interrupt.

TIMING:

Often you wish to simply sit in a loop and wait for a specified period of time. Each instruction takes four
clock cycles or 1 microsecond for a 4 Mhz crystal unless the program counter has to be changed, (flow
control instruction). 2 microseconds are required for program branches. Here is a delay subroutine which
will give a 1 millisecond delay for a 4 Mhz clock:

MSEC1 MOVLW $F9 ; allow for 4 microsec overhead..


NOP ; (2 for CALL)
MICRO4 ADDLW $FF ; subtract 1 from W
BTFSS STATUS,Z ; skip when you reach zero
GOTO MICRO4 ; more loops
RETURN

Some comments about the code:

Each loop takes 4 microseconds; ADDLW takes 1, BTFSS takes 1 and GOTO takes 2
microseconds. When the skip is taken it is also 4.
SUBLW 1 subtracts W from one, not the reverse. To subract one from W you add the two's
compliment of 1 which is $FF.
You are testing the zero bit, (Z) in the STATUS register which will be set when the subtraction
results in zero.
The bit test takes 1 microcsecond unless the skip is taken, in which case it takes 2 microseconds.
You could call MICRO4 directly with the number of 4 microsec loops in W for delays in
multiples of 4 microseconds. Remember that the call itself is 2 microseconds. Don't enter with 0
in W or you get a 256 microsec delay.
Notice that the subroutine does not use a register, just 'W'.

Programming the PIC16F84 Microcontroller by Stan Ockers Page 5


For longer time periods, you are going to have to use a register. The following routine is entered with
the number of milliseconds delay in 'W'. Up to a quarter of a second delays are possible (1 - 255 msec):

NMSEC MOVWF CNTMSEC ; W to msec count register


MSECLOOP MOVLW $F8 ; allow for 8 microsec overhead
CALL MICRO4 ; 248 * 4 + 2 = 994 here
NOP ; make rest of loop ...
NOP ; add up to 6 microseconds
DECFSZ CNTMSEC, f ; decrement count, skip when zero
GOTO MSECLOOP ; more loops
RETURN

COUNTER/TIMER:

There is a internal 8 bit counter/timer that sets a flag when it rolls over from 255 to zero. This can be
used as a counter or timer. As a timer, it is connected to the internal clock and increments at the clock
frequency divided by four. A flag can be polled to tell when time is up. The timer can also be set up to
generate an interrupt when this happens. It wouldn't take long to count all the way up at 1 Mhz so a
programmable 'prescaler' can be used. The prescaler can be set to give output pulses at ratios of
1:2,1:4,1:8 etc. up to 1:256, extending the timeout up to the tens of milliseconds range for a 4 Mhz
clock.

In counter mode, input comes from pulses applied externally at the high bit of Port A. The prescaler can
be inserted to count every second, forth, eighth etc. pulse. The input pin can also be set to count on
either rising or falling transitions.

Various bits in the OPTION register are used to set up the counter/timer. The low three bits, (0-2), set
the prescaler ratio. Bit 3 determines whether the prescaler is assigned to timer 0 or the watchdog timer.
Only one can use the prescaler at any one time. Bit 5 decides if TMR0 register is used as a timer or is
used as a counter of pulses from Port A bit 4, (RA4).

INTERRUPTS:

Sometimes you can't afford to just sit and wait for a flag to go high. The solution is to set up the timer to
generate an interrupt. When the timer rolls over a flag is set, the address of the next operation is pushed
on the stack and the program goes to location 4 and continues from there. This is usually a GOTO to the
interrupt routine.

The interrupt routine does whatever you want to happen each time the interrupt occurs. Further
interrupts are disabled when the interrupt starts. You are responsible for clearing the flag and re-enabling
interrupts. RETIE pulls the saved instruction address off the stack and enables interrupts.

Three other situations can be set up to cause interrupts:

1. PORTB, bit 0 ,(RB0/INT), can be used as an external interrupt pin. A rising or falling edge can
be used.
2. A change of state of any of the high 4 bits of PORTB.

Programming the PIC16F84 Microcontroller by Stan Ockers Page 6


3. A write to data EEPROM completion.

The enable and flag bits are the key to interrupts on the PIC. Each of these four situations has an
associated flag bit and an enable bit. The flag bit set means the situation has happened. You have to reset
these. The enable bit set means the setting of this particular flag can cause an interrupt. If in addition you
want the interrupt to cause a jump to location 4, a Global Interrupt Enable, (GIE), flag must be set before
the individual flag bit goes high. GIE is cleared at the interrupt condition and prevents further interrupts.
RETIE resets GIE.

SLEEP MODE:

Sleep mode is a low current mode used to save battery life. The pic can draw as little as 50 microamps in
sleep mode. The mode is started with the SLEEP instruction and can be ended by one of the following:

1. external reset on MCLR pin.


2. Watchdog timeout ( if enabled ).
3. Interrupt from:
1. register B port change.
2. RB0/INT pin.
3. EEPROM write completion.

While in sleep mode instruction execution is suspended. In particular, timer 0 is not incrementing. Upon
wakeup from sleep instruction exection continues from the stopped point or if GIE is set, instruction
continues from location 4.

WATCHDOG TIMER:

The watchdog timer is independent of the PIC's internal clock. It times out from a CLRWDT ,(Clear
Watchdog Timer), instruction in roughly 18 milliseconds. It is not very accurate. The prescaler can be
assigned to the WDT, giving time out periods of up to a couple of seconds. The purpose of the WDT in
normal use is to keep the PIC from going off into never-never land without the ability to recover. At
timeout, a flag is cleared, (TO), the program counter is reset to 0000 and the program starts again. To
prevent the reset, you to build a CLRWDT, (Clear Watch Dog Timer), instructions into your program
before the timeout occurs.

EEPROM:

Reading or writing to data memory, (EEPROM) requires using magic series of instructions involving the
registers EEADR, EEDATA, EECON1 and EECON2. EECON1 and EECO2 are in bank 1 so you have
to do some bank switching.

ASCII MESSAGES:

Suppose you had the message "Hello World!" and wanted send it out as ASCII characters to a PC COM
port. Data memory is scarce and hard to use so we put the message in program memory. How do we

Programming the PIC16F84 Microcontroller by Stan Ockers Page 7


access it? We use a table. You load 'W' with the offset of the character you want and call MSGTXT. A 0
will return 'H', a 1 will return 'e' etc:

MSGTXT ADDWF PCL, f ; offset added to PCL


RETLW $48 ; 'H'
RETLW $65 ; 'e'
RETLW $6C ; 'l'
RETLW $6C ; 'l'
RETLW $6F ; 'o'
RETLW $20 ; ' '
RETLW $57 ; 'W'
RETLW $6F ; 'o'
RETLW $72 ; 'r'
RETLW $6C ; 'l'
RETLW $64 ; 'd'
RETLW $21 ; '!'
RETLW $0D ; carriage return
RETLW $0A ; line feed
RETLW $00 ; indicates end

To output a character string you set up a register to point to the initial character, (MSGPTR), and
repeatedly call MSGTXT, incrementing the pointer each time. We have reached the end of the string
when a zero is returned. The routine is entered with the offset of the first character in 'W':

OUTMSG MOVWF MSGPTR ; put 'W' into message pointer


MSGLOOP MOVF MSGPTR, W ; put the offset in 'W'
CALL MSGTXT ; returns ASCII character in 'W'
ADDLW 0 ; sets the zero flag if W = 0
BTFSC STATUS, Z ; skip if zero bit not set
RETURN ; finished if W = 0
CALL OUTCH ; output the character
INCF MSGPTR, f ; point at next
GOTO MSGLOOP ; more characters

OUTPUT ASCII CHARACTERS:

Serial output of characters is just a matter of making an output go high or low at the proper times. It is
normally high, and going low signals a start bit. At 4800 baud the bit time would be 1/4800 = 208
microseconds. Eight data bits, each one bit period, follow the start bit. A high level for longer than one
bit period signifies stop bit/s. The bits are sent Least Significant Bit first. Sampling occurs midway in
the bit period to determine if the bit is a 1 or 0.

RS232 high is -3V or lower, low is +3V or greater. You can actually get away with +5V for the low and
0V for the high if you keep the line short. Notice that this is flipped from what you might expect. We
can use MICRO4 and 52 X 4 microsec loops for 1 bit time at 4800 baud. Actually 12 microseconds are
used in overhead so we use 49 as the count. The subroutine is entered with the character to be output in
'W'. Port A bit 2, (pin 1), is use as output:

OUTCH MOVWF TXREG ; put W into transmit register


MOVLW 8 ; eight bits of data
MOVWF BITS ; a counter for bits

Programming the PIC16F84 Microcontroller by Stan Ockers Page 8


BSF PORTA, 2 ; start bit (flipped remember), RA2
TXLOOP MOVLW $31 ; 49 decimal, delay time
CALL MICRO4 ; wait 49 x 4 = 196 microseconds
RRF TXREG, f ; roll rightmost bit into carry
BTFSC STATUS, C ; if carry 0 want to set bit, ( a low )
GOTO CLRBIT ; else clear bit, ( a high )
BSF PORTA, 2 ; +5V on pin 1 ( RA2 )
GOTO TESTDONE ; are we finished?
CLRBIT BCF PORTA, 2 ; 0V on pin 1 ( RA2 )
NOP ; to make both options 12 micosec
TESTDONE DECFSZ BITS, f ; 1 less data bit, skip when zero
GOTO TXLOOP ; more bits left, delay for this one
MOVLW $34 ; full 208 microsec this time
CALL MICRO4 ; delay for last data bit
BCF PORTA, 2 ; 0V, ( a high ) for stop bits
MOVLW $68 ; decimal 104 delay for 2 stop bits
CALL MICRO4
RETURN

A PIC TRANSMITTER:

We now have almost all the code necessary to program a PIC to transmit the message 'Hello Word'. The
MAIN routine might look like this:

MAIN MOVLW 0 ; all port bit outputs


TRIS TRISA ; on port A
TRIS TRISB ; and port B
CLRF PORTA ; RA2 is 0 ( RS232 high )
MOVLW $32 ; delay for 50 msec
CALL NMSEC ; so no glitches interfere
MOVLW 0 ; this is offset of message
CALL OUTMSG ; output the message
ENDLESS GOTO ENDLESS ; go into an endless loop

Some comments about the code:

All bits of all ports are set to outputs. Unconnected port bits should never be set up as inputs.
When floating, CMOS inputs can flip rapidly between states and cause excessive current draw,
heating and even damaging the PIC.
The offset of the message is the address of the first character minus the address of MSGTXT
minus 1. Other messages could be added to the table, everything has to stay in the first 256
addresses though to be reached by PCL, (program counter low).
The order of subroutines doesn't matter; the main routine has to be the first thing reached from
address 0000 though. Either it comes first or you have a 'GOTO MAIN' instruction at 0000.
The GOTO at 0000 is a good idea because it can skip over location 4 which could be reserved
for a GOTO to an interrupt subroutine.

THANKS

I would like to thank all people that have posted PIC information on the Internet. After all, that is where
I got all the material I learned from. I would especially like to thank:

Programming the PIC16F84 Microcontroller by Stan Ockers Page 9

You might also like