Vi điều khiển
Vi điều khiển
Chapter 1
Introduction to PIC18
No.1-1
The PIC18 Microcontroller
What is a computer?
Software
Hardware
Computer Hardware Organization
Processor
Control Unit
Datapath
Arithmetic
Logic Unit Memory
Output Input
Program Data
Units Units
Registers Storage Storage
No.1-2
The PIC18 Microcontroller
The processor
Registers -- storage locations in the processor
Arithmetic logic unit
Control unit
No.1-3
The PIC18 Microcontroller
The microprocessor
A processor implemented on a very large
scale integration (VLSI) chip
Peripheral chips are needed to construct a
product
The Microcontroller
The processor and peripheral functions
implemented on one VLSI chip
No.1-4
The PIC18 Microcontroller
No.1-5
The PIC18 Microcontroller
No.1-6
The PIC18 Microcontroller
Embedded Systems
A product that uses one or more microcontrollers
as controller (s).
End users are only interested in the functionality
of the product but not on the microcontroller itself.
Cell phones, home security system, automobiles,
and many other products are examples of embedded
products.
No.1-7
The PIC18 Microcontroller
Semiconductor memory
Random-access memory
No.1-8
The PIC18 Microcontroller
Read-only memory
Mask-programmed read-only memory (MROM):
programmed when being manufactured
Programmable read-only memory (PROM): can be
programmed by the end user
Erasable programmable ROM (EPROM)
1. Electrically programmable many times
2. Erased by ultraviolet light (through a window)
3. Erasable in bulk (whole chip in one erasure operation)
No.1-9
The PIC18 Microcontroller
Flash memory
1. Electrically programmable many times
2. Electrically erasable many times
3. Can only be erased in bulk (either a block or the
whole chip)
No.1-10
The PIC18 Microcontroller
Computer software
Computer programs are known as software
A program is a sequence of instructions
No.1-11
The PIC18 Microcontroller
No.1-12
The PIC18 Microcontroller
High-level language
Syntax of a high-level language is similar to English
A translator is required to translate the program written in a
high-level language -- done by a compiler
Allows the user to work on the program logic at higher level.
Source code
A program written in assembly or high-level language
Object code
The output of an assembler or compiler
No.1-13
The PIC18 Microcontroller
No.1-14
The PIC18 Microcontroller
Radix Specification
Hexadecimal (or hex) number is specified by adding the
prefix 0x or by enclosing the number with single quotes
and preceding it by an H.
0x02, 0x1234, H`2040’ are hex numbers
Decimal numbers are enclosed by single quotes and
preceded by letter D.
D`10’ and D`123’ are decimal numbers
Octal and Binary numbers are similarly specified.
O`234’ is an octal number; B’01011100’ is a binary
number.
No.1-15
The PIC18 Microcontroller
Memory Addressing
Address Contents
No.1-16
The PIC18 Microcontroller
No.1-17
The PIC18 Microcontroller
Program
21-bit progam address 12-bit register address Data
Memory Memory
Space Space
(a portion
PIC18 (Special
of this function
space is on CPU
registers and
the c general
16-bit instruction bus 8-bit data bus
chip) purpose
RAM)
No.1-18
The PIC18 Microcontroller
No.1-19
The PIC18 Microcontroller
No.1-20
The PIC18 Microcontroller
BSR<3:0>
000h
= 0000 Access RAM 05Fh
Bank 0 060h
GPRs
0FFh
100h
= 0001
Bank 1 GPRs
1FFh
200h
= 0010
Bank 2 GPRs
2FFh
300h
= 0011 Access Bank
Bank 3 GPRs 000h
Access RAM low
3FFh 05Fh
400h Access RAM high 060h
SFRs 0FFh
Bank 4
to GPRs
Bank 13
DFFh
E00h
= 1110
Bank 14 GPRs
EFFh
Unused F00h
= 1111 F5Fh
Bank 15 F60h
SFRs
FFFh
Note. 1. BSR is the 4-bit bank select register.
Figure 1.4 Data memory map for PIC18 devices (redraw with permission of Microchip)
No.1-21
The PIC18 Microcontroller
No.1-22
The PIC18 Microcontroller
No.1-23
The PIC18 Microcontroller
PC<20:0>
21
stack level 1
.
.
.
stack level 31
000000
Reset Vector
h
yxxxxxh
Unimplemented
program memory
Read '0'
1FFFFFh
Note. y can be 0 or 1 whereas x can be 0-F
Figure 1.5 PIC18 Program memory Organization (redraw with permission of
Microchip)
No.1-24
The PIC18 Microcontroller
No.1-25
The PIC18 Microcontroller
26 No.1-26
The PIC18 Microcontroller
27 No.1-27
The PIC18 Microcontroller
No.1-28
The PIC18 Microcontroller
No.1-29
The PIC18 Microcontroller
No.1-30
The PIC18 Microcontroller
31 No.1-31
The PIC18 Microcontroller
Instruction Format
Format for byte oriented instructions
15 10 9 8 7 0
opcode d a f
No.1-32
The PIC18 Microcontroller
Byte-to-byte Operations
15 12 11 0
opcode f (source file register)
15 12 11 0
1111 f (destination file register)
Figure 1.9 Byte to byte move operations (2 words) (redraw with permission of Microchip)
No.1-33
The PIC18 Microcontroller
15 12 11 9 8 7 0
opcode b a f
No.1-34
The PIC18 Microcontroller
Literal operations
A literal is a number to be operated on directly by the CPU
15 8 7 0
opcode k
Control operations
No.1-35
The PIC18 Microcontroller
15 8 7 0
opcode n<7:0> (literal)
15 8 7 0 GOTO label
1111 n<19:8> (literal)
n = 20-bit immediate value
15 8 7 0
opcode S n<7:0> (literal)
15 8 7 0 CALL funct_name
1111 n<19:8> (literal)
S = fast bit
15 11 10 0
opcode n<10:0> (literal) BRA label
15 8 7 0
opcode n<7:0> (literal) BC label
No.1-36
The PIC18 Microcontroller
Access Bank
In Figures 1.8 to 1.12, PIC18 uses 8 bits to specify a data
register (f field).
Eight bits can specify only 256 registers.
This limitation forces the PIC18 to divide data registers (up
to 4096 bytes) into banks.
Only one bank is active at a time.
When operating on a data register in a different bank, bank
switching is needed.
No.1-37
The PIC18 Microcontroller
No.1-38
The PIC18 Microcontroller
2. subwf 0x30,F,BANKED ; subtract the value of WREG from the data register
; 0x30 in the bank specified by the current contents
; of the BSR register. The difference is stored in
; data register 0x30.
3. addwf 0x40,W,A ; add the WREG register with data register at 0x40 in
; access bank and leaves the sum in WREG.
No.1-39
The PIC18 Microcontroller
No.1-40
The PIC18 Microcontroller
No.1-41
The PIC18 Microcontroller
No.1-42
The PIC18 Microcontroller
Add Instructions
addwf 0x20,F,A ; add data register and WREG and place sum in WREG
addwfc PRODL,W,A ; add WREG, PRODL, and carry and leave sum
; in WREG
Subtract Instructions
No.1-43
The PIC18 Microcontroller
RISC CISC
(Reduced Instruction Set Computer) (Complex Instruction Set Computer)
Separated data and program memory Combined data and program memory
Most operations are register to register Most operations can be register to memory
Take shorter time to design and debug Take longer time to design and debug
Provide large number of CPU registers Provide smaller number of CPU registers
No.1-44
The PIC18 Microcontroller
No.1-45
The PIC18 Microcontroller
Chapter 2
No.2-1
The PIC18 Microcontroller
- Assembler directives
- Comments
No.2-2
The PIC18 Microcontroller
- Label
- Mnemonics
- Operands
- Comment
No.2-3
The PIC18 Microcontroller
Label Field
No.2-4
The PIC18 Microcontroller
Mnemonic Field
- Can be an assembly instruction mnemonic or
assembly directive
- Must begin in column two or greater
- Must be separated from the label by a colon, one or
more spaces or tabs
addlw 0x10 ; addlw is the mnemonic field
loop incf 0x30,W,A ; incf is a mnemonic
false equ 0 ; equ is the mnemonic field
No.2-5
The PIC18 Microcontroller
No.2-6
The PIC18 Microcontroller
Comment field
- Is optional
No.2-7
The PIC18 Microcontroller
“too_high” is a label
“decf” is a mnemonic
No.2-8
The PIC18 Microcontroller
Assembler Directives
- Control directives
- Data directives
- Listing directives
- Macro directives
No.2-9
The PIC18 Microcontroller
Control Directives
Example.
if version == 100
movlw D‟10‟
movwf io_1,A
else
movlw D‟26‟
movwf io_2,A
endif
No.2-10
The PIC18 Microcontroller
#define loop_cnt 30
#define sum3(x,y,z) (x + y + z)
#define seed 103
No.2-11
The PIC18 Microcontroller
radix <default_radix>
- sets the default radix for data expression
- the default radix values are: hex, dec, or oct
No.2-12
The PIC18 Microcontroller
while <expr>
endw
- The lines between while and endw are assembled as long as <expr> is true.
Data Directives
db <expr>,…,<expr> ; define 1 or multiple byte values
db “text_string” ; define a string
dw <expr>,…,<expr> ; define 1 or multiple word constants
dw “text_string” ; define a string
dt <expr>, …, <expr> ; generates a series of retlw instructions
<label> set <expr> ; assign a value (<expr>) to label
<label> equ <expr> ; defines a constant
No.2-13
The PIC18 Microcontroller
led_pat db 0x30,0x80,0x6D,9x40,0x79,0x20,0x33,0x10,0x5B,0x08
array dw 0x1234,0x2300,0x40,0x33
results dt 1,2,3,4,5
TH equ 200
TL equ 30
No.2-14
The PIC18 Microcontroller
What is a macro?
Macro Directives
macro
endm
exitm
No.2-15
The PIC18 Microcontroller
No.2-16
The PIC18 Microcontroller
No.2-17
The PIC18 Microcontroller
banksel <label>
- generate the instruction sequence to set active data bank to the one where
<label> is located
- <label> must have been defined before the banksel directive is invoked.
No.2-18
The PIC18 Microcontroller
- sets the program origin for subsequent code at the address defined in <expr>.
- <label> will be assigned the value of <expr>.
No.2-19
The PIC18 Microcontroller
No.2-20
The PIC18 Microcontroller
Algorithm Representation
Step 1
…
Step 2
…
Step 3
…
No.2-21
The PIC18 Microcontroller
Flowchart Symbols
Terminal A
Process Subroutine
Input or
output B
off-page connector
yes
Decision A
on-page connector
no
No.2-22
The PIC18 Microcontroller
No.2-23
The PIC18 Microcontroller
No.2-24
The PIC18 Microcontroller
Case Issue
- The PIC18 instructions can be written in either uppercase or lowercase.
- MPASM allows the user to include “p18Fxxxx.inc” file to provide register
definitions for the specific processor.
- All special function registers and bits are defined in uppercase.
- The convention followed in this text is: using lowercase for instructions and
directives, using uppercase for special function registers.
No.2-25
The PIC18 Microcontroller
No.2-26
The PIC18 Microcontroller
Example 2.4 Write a program that adds the three numbers stored in data
registers at 0x20, 0x30, and 0x40 and places the sum in data register at 0x50.
Solution:
Algorithm:
Step 1
Load the number stored at 0x20 into the WREG register.
Step 2
Add the number stored at 0x30 and the number in the WREG register and
leave the sum in the WREG register.
Step 3
Add the number stored at 0x40 and the number in the WREG register and
leave the sum in the WREG register.
Step 4
Store the contents of the WREG register in the memory location at 0x50.
No.2-27
The PIC18 Microcontroller
No.2-28
The PIC18 Microcontroller
Example 2.5 Write a program to add two 24-bit numbers stored at 0x10~0x12 and
0x13~0x15 and leave the sum at 0x20..0x22.
Solution:
#include <p18F8720.inc>
org 0x00
goto start
org 0x08
retfie
org 0x18
retfie
start movf 0x10,W,A ; WREG [0x10]
addwf 0x13,W,A ; WREG [0x13] + [0x10]
movwf 0x20,A ; 0x20 [0x10] + [0x13]
movf 0x11,W,A ; WREG [0x11]
addwfc 0x14,W,A ; WREG [0x11] + [0x14] + C flag
movwf 0x21,A ; 0x21 [WREG]
movf 0x12,W,A ; WREG [0x12]
addwfc 0x15,W,A ; WREG [0x12] + [0x15] + C flag
movwf 0x22,A ; 0x22 [WREG]
end
No.2-29
The PIC18 Microcontroller
No.2-30
The PIC18 Microcontroller
#include <p18F8720.inc>
org 0x00
goto start
org 0x08
retfie
org 0x18
retfie
start movlw 0x05 ; WREG 0x05
subwf 0x10,F,A ; 0x10 [0x10] – 0x05
subwf 0x11,F,A ; 0x11 [0x11] – 0x05
subwf 0x12,F,A ; 0x12 [0x12] – 0x05
subwf 0x13,F,A ; 0x13 [0x13] – 0x05
end
No.2-31
The PIC18 Microcontroller
Example 2.7 Write a program that subtracts the number stored at 0x20..0x23
from the number stored at 0x10..0x13 and leaves the difference at 0x30..0x33.
Solution:
Start
WREG [0x20]
WREG [0x21]
Three-operand
0x31 [0x11] - [WREG] - B
subtraction
WREG [0x22]
Three-operand
0x32 [0x12] - [WREG] - B subtraction
WREG [0x23]
Three-operand
0x33 [0x13] - [WREG] - B subtraction
Stop
No.2-32
The PIC18 Microcontroller
No.2-33
The PIC18 Microcontroller
No.2-34
The PIC18 Microcontroller
Example 2.9 Write an instruction sequence that adds the decimal numbers stored at
0x10...0x13 and 0x14...0x17 and stores the sum in 0x20..0x23.
Solution:
#include <p18F8720.inc>
…
start movf 0x10,W ; add the least significant byte
addwf 0x14,W ; “
daw ; adjust for valid BCD
movwf 0x20 ; save in the destination
movf 0x11 ; add the second to least significant byte
addwfc 0x15,W ; “
daw ; “
movwf 0x21 ; “
movf 0x12 ; add the second to most significant byte
addwfc 0x16 ; “
daw ; “
movwf 0x22 ; “
movf 0x13 ; add the most significant byte
addwfc 0x17 ; “
daw ; “
movwf 0x23 ; “
end
No.2-35
The PIC18 Microcontroller
Multiplication
- PIC18 has two instructions for 8-bit multiplication: mulwf f and mullw k.
- The products are stored in the PRODH:PRODL register pair.
- The multiplication of numbers larger than 8 bits must be synthesized.
- The following instruction sequence performs 8-bit multiplication operation:
movf 0x10,W,A
mulwf 0x11,A
movff PRODH,0x21 ; upper byte of the product
movff PRODL,0x20 ; lower byte of the product
- To perform multiplication operation on numbers longer than 8 bits, the operand must be
broken down into 8-bit chunks. Multiple 8-bit multiplications are performed and the
resultant partial products are aligned properly and added together.
- Two 16-bit numbers P and Q can be broken down into as follows:
P = PHPL
Q = QHQL
No.2-36
The PIC18 Microcontroller
Note: msb stands for most significant byte and lsb stands for least significant byte
No.2-37
The PIC18 Microcontroller
Instruction sequence to multiply two numbers that are stored at N:N+1 and M:M+1:
movf M+1,W,A
mulwf N+1,A ; compute MH NH
movff PRODL,PR+2
movff PRODH,PR+3
movf M,W,A ; compute ML NL
mulwf N,A
movff PRODL,PR
movff PRODH,PR+1
movf M,W,A
mulwf N+1,A ; compute ML NH
movf PRODL,W,A ; add ML NH to PR
addwf PR+1,F,A ; "
movf PRODH,W,A ; "
addwfc PR+2,F,A ; "
movlw 0 ; "
addwfc PR+3,F,A ; add carry
movf M+1,W,A
mulwf N,A ; compute MH NL
movf PRODL,W,A ; add MH NL to PR
No.2-38
The PIC18 Microcontroller
MNxPQS3S2S1S0
No.2-39
The PIC18 Microcontroller
Program Loops
1. Do S forever
No.2-40
The PIC18 Microcontroller
i i1 i i2
no no
i i2 ? i i1 ?
yes yes
S S
ii+1 i i- 1
No.2-41
The PIC18 Microcontroller
3. while C do S
true
C S
false
4. repeat S until C
initialize C
true
C
fals
e
Figure 2.8 The Repeat ... Until looping construct
No.2-42
The PIC18 Microcontroller
- PIC18 has a 21-bit program counter (PC) which is divided into three
- PCL can be accessed directly. However, PCH and PCU are not directly
accessible.
- One can accessed the values of PCH and PCU indirectly by accessing
No.2-43
The PIC18 Microcontroller
- Reading the PCL will cause the values of PCH and PCU to be
- Writing the PCL will cause the values of PCLATCH and PCLATU
2 or 4.
No.2-44
The PIC18 Microcontroller
BCC n: jump to the instruction with address equals to PC+2+n if the condition code
CC is true.
CC can be any one of the following:
C: C flag is set to 1
NC: C flag is 0
N: N flag is set to 1 which indicates that the previous operation result was negative
NN: N flag is 0 which indicates non-negative condition
NOV: V flag is 0 which indicates there is no overflow condition
NZ: Z flag is 0 which indicates the previous operation result was not zero
OV: V flag is 1 which indicates the previous operation caused an overflow
Z: Z flag is 1 which indicates the previous operation result was zero
No.2-45
The PIC18 Microcontroller
incf f,d,a
decf f,d,a
No.2-46
The PIC18 Microcontroller
Example 1
No.2-47
The PIC18 Microcontroller
Example 2
No.2-48
The PIC18 Microcontroller
Example 2.12 Write a program to compute 1 + 2 + 3 + … + n and save the sum at 0x00
and 0x01.
Solution:
1. Program logic
Start
i1
sum 0
yes
i > n?
no
sum sum + i
i i+ 1
Stop
No.2-49
The PIC18 Microcontroller
#include <p18F8720.inc>
radix dec
n equ D'50'
sum_hi set 0x01 ; high byte of sum
sum_lo set 0x00 ; low byte of sum
i set 0x02 ; loop index i
org 0x00 ; reset vector
goto start
org 0x08
retfie
org 0x18
retfie
start clrf sum_hi,A ; initialize sum to 0
clrf sum_lo,A ; "
clrf i,A ; initialize i to 0
incf i,F,A ; i starts from 1
sum_lp movlw n ; place n in WREG
cpfsgt i,A ; compare i with n and skip if i > n
bra add_lp ; perform addition when i 50
bra exit_sum ; it is done when i > 50
No.2-50
The PIC18 Microcontroller
No.2-51
The PIC18 Microcontroller
Start
Example 2.13
Write a program
arr_max arr[0]
to find the i1
largest element
stored in the no
array that is i n?
yes
stored in data
memory no
arr[i] > arr_max?
locations from
0x10 to 0x5F. yes
arr_max arr[i]
i i+ 1
Stop
No.2-52
The PIC18 Microcontroller
No.2-53
The PIC18 Microcontroller
No.2-54
The PIC18 Microcontroller
Program memory
Table pointer
Table latch
TBLPTRU TBLPTRH TBLPTRL
TABLAT
No.2-55
The PIC18 Microcontroller
Program memory
Table pointer
Table latch
TBLPTRU TBLPTRH TBLPTRL
TABLAT
• TBLPTRU (6 bits)
• TBLPTRH (8 bits)
• TBLPTRL (8 bits)
No.2-56
The PIC18 Microcontroller
No.2-57
The PIC18 Microcontroller
tblrd
No.2-58
The PIC18 Microcontroller
Logic Instructions
No.2-59
The PIC18 Microcontroller
movlw B‟11000001‟
iorwf PORTA,F,A
movlw B‟11101001
andwf PORTB,F,A
movlw B‟10101010‟
xorwf PORTC
No.2-60
The PIC18 Microcontroller
Example 2.16 Write a program to find out the number of elements in an array of 8-bit
elements that are a multiple of 8. The array is in the program memory.
Solution:
Start
yes
count count + 1
ii-1
no
i = 0?
yes
Stop
No.2-61
The PIC18 Microcontroller
#include <p18F8720.inc>
ilimit equ 0x20 ; loop index limit
count set 0x00
ii set 0x01 ; loop index
mask equ 0x07 ; used to masked upper five bits
org 0x00
goto start
… ; interrupt service routines
start clrf count,A
movlw ilimit
movwf ii ; initialize ii to ilimit
movlw upper array
movwf TBLPTRU,A
movlw high array
movwf TBLPTRH,A
movlw low array
movwf TBLPTRL,A
movlw mask
i_loop tblrd*+ ; read an array element into TABLAT
andwf TABLAT,F,A
bnz next ; branch if not a multiple of 8
No.2-62
The PIC18 Microcontroller
No.2-63
The PIC18 Microcontroller
- The PIC18 uses a crystal oscillator or a RC circuit to generate the clock signal
needed to control its operation.
- The instruction execution time is measured by using the instruction cycle
clock.
- One instruction cycle is equal to four times the crystal oscillator clock period.
- Select an appropriate instruction that will take a multiple of 10 or 20
instruction cycles to execute.
- A desirable time delay is created by repeating the chosen instruction sequence
for certain number of times.
No.2-64
The PIC18 Microcontroller
radix dec
loop_cnt equ PRODL
movlw 250
movwf loop_cnt,A
again dup_nop 17 ; insert 17 nop instructions
decfsz loop_cnt,F,A ; 1 instruction cycle
bra again ; 2 instruction cycles
No.2-65
The PIC18 Microcontroller
Example 2.18 Write a program to create a time delay of 100 ms for the demo
board that uses a 40 MHz crystal oscillator to operate.
Solution: Repeat the previous instruction sequence for 200 times can create a
100 ms time delay.
radix dec
lp_cnt1 equ 0x21
lp_cnt2 equ 0x22
movlw 200
movwf lp_cnt1,A
loop1 movlw 250
movwf lp_cnt2,A
loop2 dup_nop 17 ; 17 instruction cycles
decfsz lp_cnt2,F,A ; 1 instruction cycle (2 when [lp_cnt1] = 0)
bra loop2 ; 2 instruction cycles
decfsz lp_cnt1,F,A
bra loop1
No.2-66
The PIC18 Microcontroller
Rotate Instructions
7 6 5 4 3 2 1 0 C
7 6 5 4 3 2 1 0
No.2-67
The PIC18 Microcontroller
C 7 6 5 4 3 2 1 0
7 6 5 4 3 2 1 0
No.2-68
The PIC18 Microcontroller
Example 2.19 Compute the new values of the data register 0x10 and the C flag after the
execution of the rlcf 0x10,F,A instruction. [0x10] = 0xA9, C = 1
Solution:
The result is
0 1 0 1 0 1 0 0 1
Original value New value
[0x10] = 1010 1001 [0x10] = 01010010
1 0 1 0 1 0 0 1 0 C=0 C=1
Example 2.20 Compute the new values of the data register 0x10 and the C flag after the
execution of the rrcf 0x10,F,A instruction. [0x10] = 0xC7, C = 1
Solution:
The result is
1 1 0 0 0 1 1 1 1
Original value New value
[0x10] = 1100 0111 [0x10] = 1110 0011
1 1 1 0 0 0 1 1 1 C=1 C=1
No.2-69
The PIC18 Microcontroller
Example 2.21 Compute the new values of the data memory location 0x10 after the
execution of the rrncf 0x10,F,A instruction and the rlncf 0x10,F,A instruction,
respectively. [0x10] = 0x6E
Solution:
The result is
0 1 1 0 1 1 1 0
original value new value
[0x10] = 0110 1110 [0x10] = 0011 0111
0 0 1 1 0 1 1 1
The result is
0 1 1 0 1 1 1 0
Before After
[0x10] = 0110 1110 [0x10] = 1101 1100
1 1 0 1 1 1 0 0
No.2-70
The PIC18 Microcontroller
Examples
No.2-71
The PIC18 Microcontroller
No.2-72
The PIC18 Microcontroller
No.2-73
The PIC18 Microcontroller
Chapter 5
No.5-1
The PIC18 Microcontroller
Introduction to C Language
#include <stdio.h>
main (void)
{
int a, b, c;
a = 3;
b = 5;
c = a + b;
printf(― a + b = %d \n‖, c);
return 0;
}
No.5-2
The PIC18 Microcontroller
- The PIC18 C compiler also supports the 24-bit short long integer data type.
- Several modifiers can be applied to integer type including short, long, and unsigned.
- Int and char types are signed by default.
No.5-3
The PIC18 Microcontroller
Variable Declarations
A declaration specifies a type and contains a list of one or more variables of that type.
int i, j, k;
char cx, cy;
int i = 0;
char echo = ‗y‘; /* ASCII of letter y is assigned */
Constants
1. integer
2. character
3. floating-point:
4. character: enclosed by single quotes
5. string: enclosed by double quotes
No.5-4
The PIC18 Microcontroller
Radix of Numbers
Arithmetic Operators
+, -, *, /, %, ++, --
Bitwise Operators
No.5-5
The PIC18 Microcontroller
Arithmetic and logic operators are often used together with the = operator.
For example,
No.5-6
The PIC18 Microcontroller
In C language,
If statement
if (expression) if (a > b)
statement; PORTA |= 0x48;
If-else Statement
if (expression) if (ax == 0)
statement1; abc = 3;
else else
statement2; abc = 5;
No.5-7
The PIC18 Microcontroller
Switch Statement
switch (expression) { switch (i) {
case const_expr1: case 1: set_temp (50);
statement1; break;
break; case 2: set_pressure (30);
case const_expr2: break;
statement2; …
break; default:
… set_temp (20);
default: set_pressure(28);
statementn; break;
} }
No.5-8
The PIC18 Microcontroller
for-loop Statement
Examples
count1 = 0;
for (i = 0; i < 30; i++)
if (arr[i] & 0x03) /* is arr[i] dividable by 4? */
count1 ++;
count2 = 0;
for (j = 30; j > 0; j--)
if ((arr[i] > 5) && (arr[j] < 20))
count2++;
No.5-9
The PIC18 Microcontroller
while statement
while (!(ADCON1 & 0x80)); /* null statement */
while (expression)
statement; while (1) { /* infinite loop */
…
}
do-while statement
i = sum = 0;
do do
statementx sum = sum + i;
while (expressiony) i++;
while (i < 50);
goto statement
if (temperature > 100)
goto label;
goto alarm;
…
The use of goto statement
is not considered a good
alarm:
programming style.
set_alarm(); /* call a function to
turn on alarm; */
No.5-10
The PIC18 Microcontroller
The getchar ( ) function returns a character when it is called. The character is received
from the serial communication port.
The puts (const char *s) function outputs the string pointed to by s to the standard
output device.
The printf (formatting string, arg1, arg2, …, argn) function outputs the arguments to
the standard output device using the supplied formatting string).
The Microchip PIC18 C compiler does not support the printf() function.
No.5-11
The PIC18 Microcontroller
No.5-12
The PIC18 Microcontroller
Example 5.1 Write a C function to compute the average of an array of integers. Both the
starting address of the array and the array count are passed to this function.
Solution:
No.5-13
The PIC18 Microcontroller
Example 5.2 Write a function to compute the square root of a 32-bit number using the
successive approximation method.
Solution:
unsigned sq_root (unsigned long int xz)
{
unsigned int sar, guess_mask, rest_mask;
unsigned int i;
sar = 0; /* successive approximation register is initialized to 0 */
guess_mask = 0x8000; /* this mask is used to guess the ith bit to be 1 */
i = 16;
do {
rest_mask = ~guess_mask; /* rest_mask is used to cancel the incorrect guess */
sar |= guess_mask; /* guess the ith bit to be 1 */
if (sar * sar > xz)
sar &= rest_mask; // change the bit to 0
guess_mask >> 1;
i--;
} while (i > 0);
if ((xy - sar * sar) < ((sar + 1)*(sar + 1) – xy))
return sar;
else return (sar + 1);
}
No.5-14
The PIC18 Microcontroller
No.5-15
The PIC18 Microcontroller
Example 5.4 Write a program to find out the number of prime numbers between 1000 and
10000.
Solution:
#include <stdio.h>
char test_prime (unsigned int a); /* prototype declaration of test_prime () */
unsigned sq_root (unsigned long int xz); /* prototype of sq_root () */
main ( )
{
unsigned int i, prime_count;
prime_count = 0;
for (i = 1000; i <= 10000; i++) {
if (test_prime(i))
prime_count ++;
}
printf(―\n The total prime numbers between 1000 and 10000 is %d\n‖, prime_count);
}
/* include the functions sq_root () and test_prime () here */
No.5-16
The PIC18 Microcontroller
type_name *pointer_name;
- One can use the & operator to assign the address of a variable to a pointer variable.
- One can use the * operator to access the value pointed to by a pointer variable.
For example,
int *ax;
char *cp;
int x, y;
No.5-17
The PIC18 Microcontroller
Example 5.5 Write the bubble sort function to sort an array of integers.
Solution: A swap function is needed by the bubble sort.
No.5-18
The PIC18 Microcontroller
Arrays
- An array holds one or multiple data items of common characteristics.
- Each array element is referred to by specifying the array name followed by one or
more subscripts, with each subscript enclosed in brackets.
- Each subscript must be a nonnegative number.
- The number of subscripts determines the dimensionality of the array.
- High dimensional arrays are not used very often in 8- and 16-bit microcontroller
applications.
- A one-dimensional array can be expressed as
data_type array_name [expression];
No.5-19
The PIC18 Microcontroller
No.5-20
The PIC18 Microcontroller
Structures
- A structure is a group of related variables that can be accessed through a common name.
- Each item within a structure has its own data type.
- The syntax of a structure declaration:
struct struct_name { /* struct_name is optional */
type1 member1;
type2 member2;
…
}
- The struct_name is optional, if it exists, defines a structure tag.
- A struct declaration defines a type.
- The right brace terminates the list of members and may be followed by a list of variables.
- A structure definition not followed by a list of variables does not reserve any space.
- An example,
struct catalog_tag {
char author [40];
char title [40];
char pub [40];
unsigned int date;
unsigned char rev;
} card;
No.5-21
The PIC18 Microcontroller
Union
- May hold objects of different types and sizes with the compiler keeping track of size
and alignment requirements.
- Allow one to manipulate different kinds of data in a single area of storage without
embedding any machine dependent information in the program.
- Syntax of the union is
union union_name {
type-name1 element1;
type-name2 element2;
…
type-namen elementn;
};
No.5-23
The PIC18 Microcontroller
An example of union
union u_tag {
int i;
char c[4];
} temp;
1. union-name.member
2. union-pointermember
No.5-24
The PIC18 Microcontroller
Automatic/External/Static/Volatile
No.5-25
The PIC18 Microcontroller
No.5-26
The PIC18 Microcontroller
source legend
input.asm input1.c input2.c file
files
program
mpasm.exe mcc18.exe mcc18.exe
cpp18.exe cpp18.exe
mplib.exe
mplink.exe
_mplink.exe mp2cod.exe mp2hex.exe
output
output.map output.out output.hex
files
output.lst output.cod
No.5-27
The PIC18 Microcontroller
A linker file (with a suffix .lkr to the file name) must be added to the project to provide
the above function.
The linker file without debug support for the PIC18F8720 is shown in Figure 5.3a. The
linker file with debug support for the PIC18F8720 is shown in Figure 5.3b.
No.5-28
The PIC18 Microcontroller
// Sample linker command file for 18F8720
// $Id: 18f8720.lkr,v 1.4 2002/08/22 20:53:50 sealep Exp $
LIBPATH .
FILES c018i.o
FILES clib.lib
FILES p18f8720.lib
No.5-29
The PIC18 Microcontroller
// Sample linker command file for 18F8720i for MPLAB ICD2
// $Id: 18f8720i.lkr,v 1.3 2002/11/07 23:23:51 sealep Exp $
LIBPATH .
FILES c018i.o
FILES clib.lib
FILES p18f8720.lib
CODEPAGE NAME=vectors START=0x0 END=0x29 PROTECTED
CODEPAGE NAME=page START=0x2A END=0x1FDBF
CODEPAGE NAME=debug START=0x1FDC0 END=0x1FFFF PROTECTED
CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED
CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED
CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED
CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED
ACCESSBANK NAME=accessram START=0x0 END=0x5F
DATABANK NAME=gpr0 START=0x60 END=0xFF
DATABANK NAME=gpr1 START=0x100 END=0x1FF
DATABANK NAME=gpr2 START=0x200 END=0x2FF
DATABANK NAME=gpr3 START=0x300 END=0x3FF
DATABANK NAME=gpr4 START=0x400 END=0x4FF
DATABANK NAME=gpr5 START=0x500 END=0x5FF
DATABANK NAME=gpr6 START=0x600 END=0x6FF
DATABANK NAME=gpr7 START=0x700 END=0x7FF
DATABANK NAME=gpr8 START=0x800 END=0x8FF
DATABANK NAME=gpr9 START=0x900 END=0x9FF
DATABANK NAME=gpr10 START=0xA00 END=0xAFF
DATABANK NAME=gpr11 START=0xB00 END=0xBFF
DATABANK NAME=gpr12 START=0xC00 END=0xCFF
DATABANK NAME=gpr13 START=0xD00 END=0xDFF
DATABANK NAME=gpr14 START=0xE00 END=0xEF3
DATABANK NAME=dbgspr START=0xEF4 END=0xEFF PROTECTED
ACCESSBANK NAME=accesssfr START=0xF60 END=0xFFF PROTECTED
SECTION NAME=CONFIG ROM=config
STACK RAM=gpr13
SIZE=0x100
Figure 5.3b P18F8720 linker file with debugging support (reprint with permission
of Microchip)
No.5-30
The PIC18 Microcontroller
Inline Assembly
- The MPLAB C compiler provides an internal assembler that allows the user to enter
a block of assembly instructions into the C program.
- The block of instructions must begin with _asm and end with _endasm.
- Some restrictions to inline assembly apply:
1. No directive support
2. Comments must be C or C++ notation
3. Full text mnemonics must be used for table reads/writes, that is
No.5-31
The PIC18 Microcontroller
_asm
clrf count,0
loop:
movlw 0x20 // check loop count
cpfseq count,0 // ―
goto doit
goto done
doit:
movf sum_lo,0,0 // move sum_lo to WREG
addwf count,0,0 // add count to sum_lo
movwf sum_lo,0 // update sum_lo
movlw 0 // add carry to high byte of sum
addwf sum_hi,1,0 // ―
incf count,1,0
goto loop
done:
nop
_endasm
No.5-32
The PIC18 Microcontroller
The processor-specific header file includes a structure definition that allows the user to
access individual bits of a register by
1. appending bits to the register name
2. appending a period to the symbol resulted in step 1
3. specifying the bit name after the period
For example,
No.5-33
The PIC18 Microcontroller
Table 5.7 PIC18 instructions provided as C macros (reprint with permission of Microchip)
Instruction macro Action
Nop () Executes a no operation (NOP)
ClrWdt () Clears the watchdog timer (CLRWDT)
Sleep () Executes a SLEEP instruction
Reset () Executes a RESET instruction
Rlcf (var, dest, access) Rotate var to the left through the carry bit
Rlncf (var, dest, access) Rotate var to the left without going through the carry bit
Rrcf (var, dest, access) Rotate var to the right through the carry bit
Rrncf (var, dest, access) Rotate var to the right without going through the carry bit
Swap (var, dest, access) Swaps the upper and lower nibbles of var
Note. 1. var must be an 8-bit quantity (i.e., char) and not located on the stack.
2. If dest is 0, the result is stored in WREG, and if dest is 1, the result is located in
var. If access is 0, the access bank will be selected, overriding the BSR value. If
access is 1, then the bank will be selected as per the BSR value.
3. Each of the macros affects MPLAB C18's ability to perform optimization on the
functions using these macros.
No.5-34
The PIC18 Microcontroller
No.5-35
The PIC18 Microcontroller
Processor-Specific Libraries
- Files contain definitions that may vary across different members of the PIC18
family.
- These libraries include all the peripheral routines and the special-function
definitions.
- The processor-specific libraries are named pprocessor.lib. For example, the library
for the PIC18F8720 is named p18F8720.lib.
Processor-Independent Libraries
- General functions and math functions are in this category.
- These functions are contained in clib.lib.
No.5-36
The PIC18 Microcontroller
These library functions are listed in Table 5.10a, 5.10b, 5.11a, 5.11b, 5.12a, and 5.12b.
The prototype definitions of delay functions are listed in Table 5.12b.
No.5-37
The PIC18 Microcontroller
Creating time delay can easily be done by calling the appropriate delay functions. For
example, with fOSC = 32 MHz, instruction cycle time = 1/8 ms,
The following two statements can create 100 ms and 1 ms delays, respectively:
Delay100TCYx(8);
Delay1KTCYx(8);
No.5-38
The PIC18 Microcontroller
Chapter 6
No.6-1
The PIC18 Microcontroller
Interrupts
- Without interrupts, the processor will execute programs by following
the program logic flow.
- Interrupt is an event that will cause the CPU to stop the normal
program execution and provide some service to the event.
No.6-2
The PIC18 Microcontroller
Interrupts (cont’)
- An internal interrupt can be generated by the hardware circuitry
inside the chip and caused by software errors.
- A good analogy for interrupt is how one will act when there is a
incoming phone call.
No.6-3
The PIC18 Microcontroller
Applications of Interrupts
- Coordinate I/O activities and prevent CPU from being tied up during
the data transfer process.
No.6-4
The PIC18 Microcontroller
Interrupt Maskability
- Some interrupts are not desirable under some situations and should be
ignored by the CPU. These interrupts are called maskable interrupt.
- Other interrupts represent events that the CPU shouldn’t ignore and
must take immediate action. These interrupts are called nonmaskable
interrupts.
No.6-5
The PIC18 Microcontroller
Interrupt Priority
- More than one interrupt source can be pending at the same time.
- The CPU needs to decide which one of the pending interrupts to service.
- The interrupt at the higher priority will be attended before the interrupt at
the lower priority.
- The PIC18 supports two-level interrupt priority only and let the software
to decide which pending interrupt to service.
No.6-6
The PIC18 Microcontroller
Interrupt service
No.6-7
The PIC18 Microcontroller
- For some maskable interrupts, the CPU may provide service to the
interrupt without completing the current instruction.
No.6-8
The PIC18 Microcontroller
Interrupt Vector
1. Predefined.
2. Stored in a predefined memory location
3. Execute an interrupt vector acknowledge cycle to fetch a vector
number to locate the interrupt vector.
- The PIC18 uses the first method to identify the interrupt vector.
No.6-9
The PIC18 Microcontroller
Interrupt Programming
Step 1. Write the service routine
org ox08
… ; interrupt service for high priority interrupts
retfie
org 0x18
… ; interrupt service for low priority interrupts
retfie
No.6-10
The PIC18 Microcontroller
No.6-11
The PIC18 Microcontroller
RCON register
7 6 5 4 3 2 1 0
IPEN - - RI TO PD POR BOR
IPEN: Interrupt priority enable bit
0: Disable priority levels on interrupts
1: Enable priority levels on interrupts
RI: RESET instruction flag bit
0: The reset instruction was executed causing a device reset
1: The reset instructionwas not executed
TO: Watchdog timeout flag bit
0: A watchdog timeout occurred
1: After power-up, CLRWDT instruction, or SLEEP instruction
PD: Power-down detection flag bit
0: By execution of the SLEEP instruction
1: After power up or by the CLRWDT instruction
POR: Power-on reset status bit
0: A power-on reset has occurred
1: A power-on reset has not occurred
BOR: Brown-out reset status bit (PIC18CX01 does not have this bit)
0: A brown-out reset has occurred
1: A brown-out reset has not occurred
No.6-12
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
GIE/GIEH PEIE/GIEL TMR0IE INT0IE RBIE TMR0IF INT0IF RBIF
No.6-13
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
RBPU INTEDG0 INTEDG1 INTEDG2 INTEDG3 TMR0IP INT3IP RBIP
No.6-14
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
INT2IP INT1IP INT3IE INT2IE INT1IE INT3IF INT2IF INT1IF
No.6-15
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
PSPIF(1) ADIF RC1IF TX1IF SSPIF CCP1IF TMR2IF TMR1IF
PSPIF: Parallel slave port Read/Write interrupt flag bit (1)
0: no read or write has occurred
1: a read or write operation has taken place (must be cleared in software)
ADIF: A/D converter interrupt flag bit
0: the A/D conversion is not completed
1: an A/D conversion completed (must be cleared in software)
RCIF: USART receive interrupt flag bit
0 = the USART receive buffer is empty
1 = the USART receive buffer is full (cleared by reading RCREG)
TXIF: USART transmit tnterrupt flag bit
0 = the USART transmit buffer is full
1 = the USART transmit buffer is empty
SSPIF: Synchronous serial port interrupt flag bit
0 = waiting to transmit/receive
1 = the transmission/reception is complete (must be cleared in software)
CCP1IF: CCP1 interrupt flag bit
Capture mode
1 = a TMR1 register capture occurred (must be cleared in software)
0 = no TMR1 register capture occurred
Compare mode
0 = no TMR1 register compare match occurred
1 = a TMR1 register compare match occurred (must be cleared in software)
PWM mode
Unused in this mode
TMR2IF: TMR2 to PR2 match interrupt flag bit
0 = No TMR2 to PR2 match occurred
1 = TMR2 to PR2 match occurred (must be cleared in software)
TMR1IF: TMR1 overflow interrupt flag bit
0 = TMR1 register did not overflow
1 = TMR1 register overflowed (must be cleared in software)
Note 1. Enabled only in Microcontroller mode for the PIC18F8X20 devices
2. PIC18CX01 device does not have PSPIF flag bit
Figure 6.3a The PIC18 PIR1 register (reprint with permission of Microchip)
No.6-16
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
- CMIF - EEIF BCLI LVDIF TMR3IF CCP2IF
F
CMIF: Comparator interrupt flag bit
0: the comparator input has not changed
1: the comparator input has changed (must clear in software)
EEIF: Data EEPROM/FLASH write operation interrupt flag bit
0: the write operation is not complete
1: the write operation is complete (must cleared in software)
BCLIF: Bus collision interrupt flag bit
0: no bus collision
1: a bus collision occurred while SSP module was transmission (I2C mode)
(must be cleared in software)
LVDIF: low voltage detect interrupt flag bit
0: the device voltage is above the low voltage detect trip point
1: a low voltage condition occurred (must be cleared in software)
TMR3IF: TMR3 overflow interrupt flag bit
0: TMR3 register did not overflow
1: TMR3 register overflowed
CCP2IF: CCP2 interrupt flag bit
Capture mode
0: no TMR1 or TMR3 register capture occurred
1: a TMR1 or TMR3 register capture occurred (must be cleared in software)
Compare mode
0: no TMR1 or TMR3 register compare match occurred
1: TMR1 or TMR3 register compare match occurred (must be cleared in software)
PWM mode:
unused in this mode
Figure 6.3b The PIC18 PIR2 register (reprint with permission of Microchip)
No.6-17
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
- - RC2IF TX2IF TMR4IF CCP5IF CCP4IF CCP3IF
RC2IF: USART2 receive interrupt flag bit
0 = the USART receive buffer is empty
1 = the USART receive buffer is full (cleared when RCREG is read)
TX2IF: USART2 transmit interrupt flag bit
0 = the write operation is not complete
1 = the USART transmit buffer is empty (cleared when TXREG is written)
TMR4IF: TMR4 overflow interrupt flag bit
0 = TMR4 did not overflow
1 = TMR4 register overflowed (must be cleared in software)
CCPxIF: CCPx interrupt flag bit (x = 3, 4, 5)
Capture mode:
0 = No TMR1 or TMR3 register capture occurred
1 = A TMR1 or TMR3 register capture occured (must be cleared in software)
Compare mode:
0 = No TMR1 or TMR3 register compare match occurred
1 = A TMR1 or TMR3 register compare match occurred (must cleared in software)
PWM mode: (not used)
Figure 6.3c The PIR3 register (PIC18FXX20) (reprint with permission of Microchip)
No.6-18
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
TXB2IF/ RXB1IF/
IRXIF WAKIF ERRIF TXBnIF TXB1IF TXB0IF RXBnIF RXB0IF
IRXIF: Invalid message received interrupt flag bit
0: an invalid message has not occurred on the CAN bus
1: an invalid message has occurred on the CAN bus
WAKIF: Bus activity wakeup interrupt flag bit
0: activity on the CAN bus has not occurred
1: activity on the CAN bus has occurred
ERRIF: CAN bus error interrupt flag big
0: an error has not occurred in the CAN module
1: an error has occurred in the CAN module (multiple sources)
When CAN is in mode 0
TXB2IF..TXB0IF: Transmit buffer 2..0 interrupt flag bit
0: transmit buffer 2..0 has not completed transmission of a message
1: transmit buffer 2..0 has completed transmission of a message and may be reloaded
When CAN is in mode 1 or mode 2
TXBnIF: Any transmit buffer interrupt flag bit
0: No message was transmitted
1: One or more transmit buffer has completed transmission of a message and may
reloaded
TXB1IF and TXB0IF are forced to 0 in mode 1 and mode 2
When CAN is in mode 0
RXB1IF..RXB0IF: Receive buffer 1..0 interrupt flag bit
0: receive buffer 1 (or 0) has not received a new message
1: receive buffer 1 (or 0) has received a new message
When CAN is in mode 1 or mdoe 2
RXBnIF: CAN receive buffer interupt flag big
0: No receive buffer has received a new message
1: One or more receive buffer has received a new message
RXB0IF is forced to 0 when in mode 1 or mode 2
Figure 6.3d The PIC18 PIR3 register (PIC18FXX8 or other devices with CAN)
(reprint with permission of Microchip)
No.6-19
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
PSPIE(1 ADIE RC1IE TX1IE SSPIE CCP1IE TMR2IE TMR1IE
)
PSPIE: Parallel slave port Read/Write interrupt enable bit (1)
0: disables the PSP read/write interrupt
1: eables the PSP read/write interrupt
ADIE: A/D converter interrupt enable bit
0: disables the A/D interrupt
1: enables the A/D interrupt
RC1IE: USART1 receive interrupt enable bit
0 = disable the USART1 receive interrupt
1 = enable the USART1 receive interrupt
TX1IE: USART1 transmit interrupt enable bit
0 = disable the USART1 transmit interrupt
1 = enable the USART1 transmit interrupt
SSPIE: Synchronous serial port interrupt enable bit
0 = disables the MSSP interrupt
1 = enables the MSSP interrupt
CCP1IE: CCP1 interrupt enable bit
0 = disables the CCP1 interrupt
1 = enables the CCP1 interrupt
TMR2IE: TMR2 to PR2 match interrupt enable bit
0 = disables the TMR2 to PR2 match interrupt
1 = enables the TMR2 to PR2 match interrupt
TMR1IE: TMR1 overflow interrupt enable bit
0 = disables TMR1 register overflow interrupt
1 = enables TMR1 register overflow interrupt
No.6-20
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
- CMIE - EEIE BCLIE LVDIE TMR3IE CCP2IE
CMIE: Comparator interrupt enable bit
0: disables the comparator interrupt
1: enables the comparator interrupt
EEIE: Data EEPROM/FLASH write operation interrupt enable bit
0: disables the write operation interrupt
1: enables the write operation interrupt
BCLIE: Bus collision interrupt enable bit
0: disables the bus collision interrupt
1: enables the bus collision interrupt
LVDIE: low voltage detect interrupt enable bit
0: disables the device voltage detect interrupt
1: enables the device voltage detect interrupt
TMR3IE: TMR3 overflow interrupt enable bit
0: disables the TMR3 overflow interrupt
1: enables the TMR3 overflow interrupt
CCP2IE: CCP2 interrupt enable bit
0: disables the CCP2 interrupt
1: enables the CCP2 interrupt
Note 1. The PIC18C601/801 has only the lower four bits of this register.
2. The PIC18FXX2 does not have the CMIF bit
No.6-21
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
- - RC2IE TX2IE TMR4IECCP5IE CCP4IE CCP3IE
RC2IE: USART2 receive interrupt enable bit
0: the comparator input has not changed
1: the comparator input has changed (must clear in software)
TX2IE: USART2 transmit interrupt enable bit
0: disables the USART2 transmit enable bit
1: enables the USART2 transmit enable bit
CCPxIE: CCPx interrupt enable bit (x = 3, 4, or 5)
0: disables the CCPx interrupt
1: enables the CCPx interrupt
No.6-22
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
TXB2IE/ RXB1IE/
IRXIE WAKIE ERRIE TXBnIE TXB1IE TXB0IE RXBnIE RXB0IE
IRXIE: Invalid message received interrupt enable bit
0: disables the invalid CAN message received interrupt
1: enables the invalid CAN message received interrupt
WAKIE: Bus activity wakeup interrupt enable bit
0: disables the bus activity wakeup interrupt
1: enables the bus activity wakeup interrupt
ERRIE: CAN bus error interrupt enable big
0: disables the CAN bus error interrupt
1: enables the CAN bus error interrupt
When CAN is in mode 0:
TXB2IE..TXB0IE: Transmit buffer 2..0 interrupt enable bit
0: disables transmit buffer 2..0 interrupt
1: enables transmit buffer 2..0 interrupt
When CAN is in mode 1 or mode 2:
TXBnIE: CAN transmit buffer interrupt enable bit
0: disable all transmit buffer interrupts
1: enable transmit buffer interrupt; individual interrupt is enabled by TXBIE abd BIE0
When CAN is in mode 0:
TXB1IE and TXB0IE are forced to 0 in mode 1 and mode 2.
RXB1IE..RXB0IE: Receive buffer 1..0 interrupt enable bit
0: disables receive buffer 1 (or 0) interrupt
1: enables receive buffer 1 (or 0) interrupt
When CAN is in mode 1 or mdoe 2:
RXBnIE: CAN receive buffer interrupt enable bit
0: disable all receive buffer interrupts
1: enable receive buffer interrupts; individual interrupts is enabled by BIE0
RXB0IE is forced to 0 when in mode 1 and mode 2.
Figure 6.4d Contents of the PIC18 PIE3 register (PIC18FXX8 and other devices with CAN)
(reprint with permission of Microchip)
No.6-23
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
- CMIP - EEIP BCLIP LVDIP TMR3IP CCP2IP
CMIP: Comparator interrupt priority bit
0: low priority
1: high priority
EEIP: Data EEPROM/FLASH write operation interrupt priority bit
0: low priority
1: high priority
BCLIP: Bus collision interrupt priority bit
0: low priority
1: high priority
LVDIP: low voltage detect interrupt priority bit
0: low priority
1: high priority
TMR3IP: TMR3 overflow interrupt priority bit
0: low priority
1: high priority
CCP2IP: CCP2 interrupt priority bit
0: low priority
1: high priority
Note 1. The PIC18C601/801 has only the lower four bits of this register.
2. The PIC18FXX2 does not have the CMIP bit
No.6-25
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
- - RC2IP TX2IP TMR4IP CCP5IP CCP4IP CCP3IP
RC2IP: USART2 receive interrupt priority bit
0: low priority
1: high priority
TX2IP: USART2 transmit interrupt priority bit
0: low priority
1: high priority
CCPxIP: CCPx interrupt priority bit (CCP modules 3, 4, and 5)
0: low priority
1: high priority
Figure 6.5c The IPR3 register (PIC18FXX20) (reprint with permission
of Microchip)
No.6-26
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
TXB2IP/ RXB1IP/
IRXIP WAKI ERRIP TXBnIP TXB1IP TXB0IP RXBnIP RXB0IP
P
IRXIP: Invalid message received interrupt priority bit
0: low priority
1: high priority
WAKIP: Bus activity wakeup interrupt enable bit
0: low priority
1: high priority
ERRIP: CAN bus error interrupt enable big
0: low priority
1: high priority
TXB2IP..TXB0IP: Transmit buffer 2..0 interrupt enable bit
In mode 0
0: low priority
1: high priority
In mode 1 and mode 2
TXBnIP is used as the priority bit for all CAN transmit buffers
0: low priority
1: high priority
Bit 3 and 2 are forced to 0 in CAN mode 1 and mode 2.
RXB1IP..RXB0IP: Receive buffer 1..0 interrupt enable bit
In mode 0
0: low priority
1: high priority
In mode 1 and 2
RXBnIP is used to enable the priority of all receive buffer
0: low priority
1: high priority
Bit 0 is forced to 0 in CAN mode 1 and mode 2.
Figure 6.5d The IPR3 register (Devices with CAN) (reprint with
permission of Microchip)
No.6-27
The PIC18 Microcontroller
No.6-28
The PIC18 Microcontroller
- All interrupts are divided into core group and peripheral group.
- The priority bits of the interrupts sources in the core group are contained in
one of the interrupt control registers.
- When the priority scheme is enabled, all high-priority interrupts are under
the control of a two-level interrupt enabling mechanism.
No.6-29
The PIC18 Microcontroller
- When the priority scheme is disabled, all interrupts in the core group are under
the control of a two-level interrupt enabling scheme.
- All interrupts in the peripheral group are under the control of a three-level
enabling scheme.
- When an interrupt is responded to, the GIE bit is cleared to disable further
interrupt the return address is pushed onto return address stack and the PC is
loaded with the interrupt vector.
No.6-30
The PIC18 Microcontroller
- The priority scheme is disabled by clearing the bit 7 of the RCON register.
- In order to identify the cause of interrupt, one need to check each individual
interrupt flag bit.
- The interrupt sources in the core group can be enabled by setting the GIE bit
and the corresponding enable bit of the interrupt source.
- To enable TMR0 interrupt, for example, one must set both the GIE and the
TMR0IE bits to 1.
- The interrupts in the peripheral group can be enabled by setting the GIE, PEIE,
and the associated interrupt enable bits.
- To enable A/D interrupt, one needs to set the GIE, PEIE, and the ADIE bits
No.6-31
The PIC18 Microcontroller
- The PEIE bit of the INTCON register is used as the low-priority interrupt
enable bit.
- A high-priority interrupt is enabled when the GIEH bit and its interrupt enable
bit are set to 1.
- A low-priority interrupt is enabled when the GIEH, GIEL, and its associated
interrupt enable bits are all set to 1.
- The pending interrupts in the high-priority group will always be served before
the interrupts in the low-priority group.
No.6-33
The PIC18 Microcontroller
Example 6.1 Write an assembly program to handle the INT0 interrupt for the circuit
shown in Figure 6.6b.
No.6-34
The PIC18 Microcontroller
5V
PIC18F8680
470 470
RD7
1 Hz RD6
RD5
INT0
RD4
RD3
RD2
RD1
RD0
No.6-35
The PIC18 Microcontroller
#include <p18F8680.inc>
count equ 0x00
org 0x00
goto start
org 0x08
goto ISR_hi
org 0x18
retfie
start setf count ; count down from 255
clrf TRISD ; configure port D for output
movff count,PORTD ; output count to LEDs
bsf RCON,IPEN ; enable priority interrupt
movlw 0x90 ; enable INT0 interrupt
movwf INTCON ; and clear INT0IF flag
forever nop
bra nop
No.6-36
The PIC18 Microcontroller
No.6-37
The PIC18 Microcontroller
No.6-38
The PIC18 Microcontroller
Example 6.2 Write a C language version of the program for example 6.1.
#include <p18Fxxx.h>
void low_ISR(void);
void high_ISR(void);
unsigned char count;
#pragma code high_vector = 0x08 // force the following statement to start at
void high_interrupt (void) // 0x08
{
_asm
goto high_ISR;
_endasm
}
#pragma code //return to the default code section
#pragma interrupt high_ISR
void high_ISR (void)
{
if (INTCONbits.INT0IF){ //handle high-priority interrupts
count++;
PORTD = count;
}
}
No.6-39
The PIC18 Microcontroller
No.6-40
The PIC18 Microcontroller
No.6-41
The PIC18 Microcontroller
- When an interrupt occurs, the PIC18 MCU saves WREG, BSR, and STATUS in the
fast register stack.
- The user can use the retfie fast instruction to retrieve these registers before
returning from the interrupt service routine.
- One can save additional registers in the stack if the interrupt service needs to modify
these registers. These registers must be restored before returning from the service
routine.
- In C language, one can add a save clause to the #pragma statement to inform the C
compiler to generate appropriate instructions for saving additional registers.
No.6-42
The PIC18 Microcontroller
Resets
- Resets can establish the initial values for the CPU registers, flip-flops, and control
registers of the interface chips so that the computer can function properly.
- The reset service routine will be executed after the CPU leaves the reset state.
- The reset service routine has a fixed starting address and is stored in the read only
memory.
- The PIC18 can differentiate the following types of reset:
1. Power-on reset (POR)
2. MCLR pin reset during normal operation
3. MCLR pin reset during sleep mode
4. Watchdog timer (WDT) reset (during normal operation)
5. Programmable brown-out reset (BOR)
6. RESET instruction
7. Stack full reset
8. Stack underflow reset
No.6-43
The PIC18 Microcontroller
No.6-44
The PIC18 Microcontroller
Chapter 6
Parallel Ports
No.6-1
The PIC18 Microcontroller
Introduction
- Embedded products are designed to allow the user to provide input and receive
results.
- The speed and characteristics of I/O devices are quite different from the CPU.
- Peripheral chips are used to resolve the difference between the I/O devices and
the CPU.
- The major function of the interface chip is to synchronize the data transfer
between the CPU and I/O devices.
- Resistors may be needed to limit the current flow, whereas buffer chips may be
needed to increase the current flow required by the I/O devices.
- An interface chip consists of control registers, data registers, status registers,
data direction register, and control circuitry.
No.6-2
The PIC18 Microcontroller
No.6-3
The PIC18 Microcontroller
Address from to
Decoder input output
device I/O pins device
CE CE
Interface Interface
chip 1 chip 1
Microprocessor
Data Bus
- The address decoder in Figure 7.1 allows one and only one interface chip to exchange
data with the microprocessor at a time.
- Data transfer can be proceeded in parallel or bit by bit (serial method).
- Serial method is meant to be used with slower I/O devices
- Parallel method is meant to be used with high-speed devices.
- This chapter focuses on parallel I/O.
No.6-4
The PIC18 Microcontroller
I/O Addressing
- The processor needs to access the registers of the interface chip to perform
No.6-5
The PIC18 Microcontroller
I/O Synchronization
- The role of the interface chip is shown in Figure 7.2.
- For input, the CPU needs to make sure it reads when the data is valid and reads only
once.
- For output, the CPU needs to make sure that the output device is ready to accept new
data.
- There are two aspects in the I/O synchronization: the synchronization between the
CPU and interface chip and the synchronization between the interface chip and the I/O
device.
handshake or
Control signals strobe signal I/O device
Microprocessor Interface chip electronics
(such as R/W or
interrupt)
Data Bus
No.6-6
The PIC18 Microcontroller
2. Interrupt-driven method. Use the interrupt signal to inform the CPU that new data
is available or output device is ready for more data.
No.6-7
The PIC18 Microcontroller
1. No method
- Input: The interface returns the current value of the input pins.
- Output: The interface drives the data written by the CPU directly on output pins.
2. Strobe method
- A strobe signal is used to synchronize data transfer.
- Input: The input device places data on input pins, wait until data is stable, and then
asserts the strobe signal to inform the interface chip to latch the data.
- Output: The interface chip drives data to be output on the output pins, wait until
data is stable, and then asserts the strobe signal to inform the output device
to latch the data.
- PIC18 does not support this method.
No.6-8
The PIC18 Microcontroller
3. Handshake method
- Two handshake signals are used to synchronize the data transfer between the
interface chip and I/O device. H1 is driven by interface chip and H2 is driven
by I/O device.
- There are two versions of handshaking: pulse mode and interlock mode.
- Handshaking signals transactions for input and output are shown in Figure 7.3
and 7.4, respectively.
No.6-9
The PIC18 Microcontroller
H1
H2
(a) Interlocked
H1
H2
No.6-10
The PIC18 Microcontroller
H1
H2
(a) Interlocked
H1
H2
(b) Pulse Mode
Figure 7.4 Output Handshaking
No.6-11
The PIC18 Microcontroller
- Data to be output is written into the latch, which in turn drives the output
pins.
- When a peripheral function is enabled, the I/O pins cannot be used for
general-purpose I/O.
No.6-12
The PIC18 Microcontroller
- Devices with 18 pins and 20 pins have two I/O ports: A and B.
- Devices with 40 pins (DIP package) and 44 pins (PLCC package) have five
- Devices with 64 pins (TQFP package) and 68 pins (PLCC package) have seven
ports: A, B, C, D, E, F, and G.
- Most 80-pin (TQFP package) and 84-pin devices (PLCC package) have nine
ports but some 84-pin devices (e.g., PIC18F858 in PLCC package) have 10 ports.
No.6-13
The PIC18 Microcontroller
No.6-14
The PIC18 Microcontroller
Example 7.1 Write an instruction sequence to output the hex value 0x33 to port D.
Solution:
The port D should be configured for output before data is written to it.
Example 7.2 Write an instruction sequence to read the current value of port D into
WREG.
Solution:
setf TRISD,A ; configure port D for input
movf PORTD,W,A ; read port D pin value into WREG
No.6-15
The PIC18 Microcontroller
- Part of an I/O port pins can be configured for input whereas others are configured for
output.
Example 7.3 Configure the upper four pins of port D for input and the lower four pins
for output.
Solution:
movlw 0xF0
movwf TRISD,A
No.6-16
The PIC18 Microcontroller
Output Pin
possible.
- Method (a, b) is used to drive (a) low voltage on output pin lights LED
Output Pin
LED directly.
300~500
5V
Output Pin
300~500
No.6-17
The PIC18 Microcontroller
g
RD3 d
RD2 e e c
RD1 f
RD0 g
d
common cathode
No.6-18
The PIC18 Microcontroller
#5 #4 #0
300 a a . . . a
. b . b . . . b
. .
300 . .
g g
74HC244 . . . g
RD6 RD5 RD0 common common common
cathode cathode cathode
R
RB5 2N2222
IMAX = 70 mA
R 2N2222
RB4 .
PIC18 MCU .
. R
RB0 2N2222
Figure 7.17 Port B and Port D together drive six seven-segment displays
No.6-19
The PIC18 Microcontroller
No.6-20
The PIC18 Microcontroller
In C language,
TRISB = 0x00;
TRISD = 0x00;
PORTD = 0x5B;
PORTB = 0x10;
No.6-21
The PIC18 Microcontroller
- Light each digit in turn briefly (say, 1 ms a time) and then turned off.
- When one display is lighted, all other displays are turned off.
- Because of the persistence of vision, all displays will appear lighted simultaneously.
Example 7.5 Write a program to display 654321 on the six seven-segment displays in
Figure 7.17 assuming that the PIC18 is running with a 32-MHz crystal oscillator.
Solution: The values to be output to port B and port D are listed in Table 7.5.
No.6-22
The PIC18 Microcontroller
#include <p18F8680.inc>
radix dec
dup_nop macro kk ; this macro will duplicate the “nop” instruction
variable i ; kk times
i=0 ; need to be at a separate line
while i < kk
nop
i += 1 ; need to be at separate line
endw
endm
lp_cnt set 0x00 ; use data memory 0 as loop count
lp_cnt1 set 0x01 ; another loop count
org 0x00
goto start
org 0x08
retfie
org 0x18
retfie
start clrf TRISB,A ; configure Port B for output
clrf TRISD,A ; configure Port D for output
forever movlw 0x06 ; there are six digits to be displayed
movwf lp_cnt ; "
No.6-23
The PIC18 Microcontroller
No.6-24
The PIC18 Microcontroller
#include <delays.h>
#include <p18F8680.h>
char display[6][2] = {{0x5F,0x20},{0x5BD,0x10},{0x33,0x08},{0x79,0x04},
{0x6D,0x02}, {0x30,0x01}};
void main ()
{
int i;
TRISB = 0x00; /* configure Port B for output */
TRISD = 0x00; /* configure Port D for output */
while (1) {
for (i = 0; i < 6; i++) {
PORTD = display[i][0]; /* output display pattern */
PORTB = display[i][1]; /* turn on one display */
Delay1KTCYx(8); /* wait for 1 ms */
}
}
}
No.6-26
The PIC18 Microcontroller
DB7 COM 16
LCDP (FRD7069)
DB0
E CONTROLLER SEG 40
LSI SEG 160
R/W
HD44780
RS
VEE
VCC 4
SEGMENT DRIVER x 4
VSS
No.6-27
The PIC18 Microcontroller
Table 7.4 Pin assignment for displays with less than 80 characters
Pin No. symbol I/O Function
1 VSS - Power supply (GND)
2 VCC - Power supply (+5V)
3 VEE - Contrast adjust
4 RS I 0 = instruction input, 1 = data input
5 R/W I 0 = write to LCD, 1 = read from LCD
6 E I enable signal
7 DB0 I/O data bus line 0
8 DB1 I/O data bus line 1
9 DB2 I/O data bus line 2
10 DB3 I/O data bus line 3
11 DB4 I/O data bus line 4
12 DB5 I/O data bus line 5
13 DB6 I/O data bus line 6
14 DB7 I/O data bus line 7
- The DB7..DB0 pins are used to exchange data with the microcontroller.
- The R/W pin determines the data transfer direction.
- The E pin enables the data exchange with the LCD kit.
- The HD44780 has an instruction register and a data register.
- The RS signal selects the instruction register when it is low and selects the data
register when it is 1.
- The VEE signal is used to adjust the brightness of the LCD and is often connected to
a potentiometer.
No.6-28
The PIC18 Microcontroller
- The HD44780 can be configured to control 1-line, 2-line, and 4-line displays.
- The HD44780 controller has character generator ROM that can generate 208 5 8 dot
characters and 32 5 10 dot characters.
- Character generator RAM is available for defining 8 5 8 character patterns and 4
5 10 character patterns.
- A set of instructions (Table 7.6) is available for users to configure the LCD operations.
- The HD44780 controller has display data memory (DDRAM) to store the display
data.
- The address of a display data memory location determines where the next character
will appear on the LCD screen.
- The mapping from display data memory to the LCD screen position is not sequential
and is shown in Table 7.8a, 7.8b, and 7.8c.
Table 7.8a DDRAM address usage for a 1-line LCD
Visible
Display size character positions DDRAM addresses
1*8 00..07 0x00..0x07
1 * 16 00..15 0x00..0x0F
1 * 20 00..19 0x00..0x13
1 * 24 00..23 0x00..0x17
1 * 32 00..31 0x00..0x1F
1 * 40 00..39 0x00..0x27
No.6-29
The PIC18 Microcontroller
No.6-30
The PIC18 Microcontroller
No.6-31
The PIC18 Microcontroller
The IR Register
- The microcontroller writes command (or instruction) into this register to configure
the LCD operation parameters.
- The LCD instruction set is listed in Table 7.6.
No.6-32
The PIC18 Microcontroller
The DR Register
- The data to be written into the DDRAM or CGRAM is written into this register.
- To read data from DDRAM or CGRAM, the microcontroller reads from this register.
No.6-33
The PIC18 Microcontroller
HD44780 Commands
1. Clear display (0x01). This command clears the LCD screen, sets the address
counter to 0, sets the cursor to the upper left corner of the LCD screen, and also sets
the I/D bit to 1 in entry mode.
2. Return Home (0x02). Sets DDRAM address 0 into address counter, move cursor to
the upper left corner of the display but does not change the contents of the DDRAM.
3. Entry Mode Set. The I/D bit of this command controls the incrementing or
decrementing of the DDRAM address. The display will shift if the S bit is 1 when the
DDRAM is being written into.
4. Display On/Off Control. This command can turn on the display (D = 1), turn on the
cursor (C = 1), and turn on the cursor blinking (B = 1).
5. Cursor or Display Shift. This command determines to shift the cursor (S/C = 0 bit)
or display (S/C bit = 1) to the right (R/L bit = 1) or to the left (R/L bit = 0).
No.6-34
The PIC18 Microcontroller
6. Function Set. This command allows the user to set the interface data length, select
the number of lines, and the font size:
DL bit. When set to 1, data is exchanged in 8-bit length. Otherwise, data is exchanged
in 4-bit length.
N bit. When set to 1, two-line display is selected. Otherwise, 1-line display is
selected.
F bit. When set to 0, the 5 7 font is selected. Otherwise, 5 10 font is selected.
7. Set CGRAM Address. This command contains the CGRAM address to be set into
the address counter.
8. Set DDRAM Address. This command allows to set the DDRAM address into the
address counter.
9. Read Busy Flag and Address. This instruction reads the busy flag (BF) and the
address counter. The BF flag indicates whether the LCD controller is still executing
the previously received command.
No.6-35
The PIC18 Microcontroller
- There are two methods to interface the LCD kit to the PIC18.
- The first method is treating the LCD kit as an I/O device. One of the available
I/O port is used to connect to the DB7…DB0 pins. Other port pins are used to connect
to the R/W, E, and S inputs of the LCD kit and generate the required timing sequence
on these three pins.
- The second method is to treat the LCD kit as a memory device and use the address
decoder to generate a select signal to select the LCD kit. This method allows the user
to use the table read and table write instructions to access the LCD kit.
- The second method cannot be used by those PIC18 members that do not support the
external memory.
- Only the first method will be used to interface the LCD kit with the PIC18 in this text.
- The circuit for the first approach is shown in Figure 7.21.
No.6-36
The PIC18 Microcontroller
HD44780-based LCD
PIC18 MCU Module
5V
RH7 E
RH6 R/W VCC
RH5 RS 5V
VEE
RE7...RE0 DB7..DB0
GND
No.6-37
The PIC18 Microcontroller
HD44780-based LCD
PIC18 MCU Module
5V
RH7 RS
RH6 R/W VCC
RH5 E 5V
VEE
RE7...RE4 DB7..DB4
GND
No.6-38
The PIC18 Microcontroller
- Certain timing parameters must be satisfied in order to successfully access the LCD.
- The read and write timing diagrams are shown in Figure 7.22 and 7.23.
- The HD44780 can operate at either 1 MHz or 2 MHz. The values of timing parameters
for 2-MHz operation are shown in Table 7.12.
RS
tAS tAH
R/W
PWEH tEf
E
tEr tDDR tDHR
DB0-DB7 Valid data
tCYCLE
No.6-39
The PIC18 Microcontroller
RS
tAS tAH
R/W
PWEH tEf
E
tEr tDSW
tH
DB0-DB7 Valid data
tCYCLE
No.6-40
The PIC18 Microcontroller
LCD Programming
1. LCD_rdy: make sure the LCD is not busy with internal operation
4. send2LCD: generate a timing sequence to output the contents of WREG to the LCD
6. LCD_putstr: output the string in program memory pointed to by TBLPTR to the LCD
7. LCD_putsr: output the string in data memory pointed to by FSR0 to the LCD
No.6-41
The PIC18 Microcontroller
The following signals are defined to simplify the access of signals for the SSE8680 and
SSE8720 demo boards:
No.6-42
The PIC18 Microcontroller
Step 1
Pull the RS and the E signals to low.
Step 2
Pull the R/W signal to low.
Step 3
Pull the E signal to high.
Step 4
Output data to the output port attached to the LCD data bus. (Need to configure port E
for output).
Step 5
Pull the E signal to low.
No.6-43
The PIC18 Microcontroller
Step 1
Pull the RS and the E signals to low.
Step 2
Pull the R/W signal to high.
Step 3
Pull the E signal to high.
Step 4
Read the value of the LCD data bus. (need to configure port E for input)
Step 5
Pull the E signal to low.
No.6-44
The PIC18 Microcontroller
Step 1
Pull the RS signal to high and pull the E signals to low.
Step 2
Pull the R/W signal to low.
Step 3
Pull the E signal to high.
Step 4
Output data to the I/O port attached to the LCD data bus.
Step 5
Pull the E signal to low.
No.6-45
The PIC18 Microcontroller
No.6-46
The PIC18 Microcontroller
No.6-47
The PIC18 Microcontroller
LCD_init clrf LCD_ctl_port ; make sure the LCD control port is low
bcf LCD_E_DIR ; configure control lines
bcf LCD_RW_DIR ; directions to output
bcf LCD_RS_DIR ; "
movlw 0x3C ; configure display to 2 x 20
call LCD_cmd ; send command to LCD
movlw 0x0F ; turn on display and cursor
call LCD_cmd ; "
movlw 0x14 ; shift cursor right
call LCD_cmd ; "
movlw 0x01 ; clear cursor and return to home position
call LCD_cmd ; "
return
No.6-48
The PIC18 Microcontroller
get_DDRAM_addr
setf LCD_D_DIR ; configure LCD data port for input
bcf LCD_RS ; select IR register
bsf LCD_RW ; setup to read busy flag
bsf LCD_E ; pull LCD E-line to high
nop ; add a small delay
movf LCD_DATA,W ; read busy flag and DDRAM address
nop ; small delay to length E pulse
bcf LCD_E ; pull LCD E-line to low
movwf PRODL,A
return
No.6-49
The PIC18 Microcontroller
No.6-51
The PIC18 Microcontroller
No.6-52
The PIC18 Microcontroller
In C language,
No.6-53
The PIC18 Microcontroller
/******************************************************************/
/* the following function waits until the LCD is not busy. */
/******************************************************************/
void LCD_rdy(void)
{
char test;
LCD_D_DIR = 0xFF; /* configure LCD data bus for input */
test = 0x80;
while (test) {
LCD_RS = 0; /* select IR register */
LCD_RW = 1; /* Set read mode */
LCD_E = 1; /* Setup to clock data */
test = LCD_DATA;
Nop();
LCD_E = 0; /* complete a read cycle */
test &= 0x80; /* check bit 7 */
}
LCD_D_DIR = 0x00; /* configure LCD data bus for output */
}
No.6-54
The PIC18 Microcontroller
/******************************************************************/
/* The following function sends a command to the LCD. */
/******************************************************************/
void LCD_cmd(char cx)
{
LCD_rdy(); /* wait until LCD is ready */
LCD_RS = 0; /* select IR register */
LCD_RW = 0; /* Set write mode */
LCD_E = 1; /* Setup to clock data */
Nop();
LCD_DATA = cx; /* send out the command */
Nop(); /* small delay to lengthen E pulse */
LCD_E = 0; /* complete an external write cycle */
}
No.6-55
The PIC18 Microcontroller
/*******************************************************************/
/* The following function initializes the LCD kit properly. */
/*******************************************************************/
void LCD_init(void)
{
PORTH = 0; /* make sure LCD control port is low */
LCD_E_DIR = 0; /* configure LCD control port for output */
LCD_RS_DIR = 0; /* “ */
LCD_RW_DIR = 0; /* “ */
LCD_cmd(0x3C); /* configure display to 2 rows */
LCD_cmd(0x0F); /* turn on display, cursor, and blinking */
LCD_cmd(0x14); /* shift cursor right */
LCD_cmd(0x01); /* clear display and move cursor to home */
}
No.6-56
The PIC18 Microcontroller
/*******************************************************************/
/* The following function obtains the LCD cursor address. */
/*******************************************************************/
char get_DDRAM_addr (void)
{
char temp;
LCD_D_DIR = 0xFF; /* configure LCD data port for input */
LCD_RS = 0; /* select IR register */
LCD_RW = 1; /* setup to read busy flag */
LCD_E = 1; /* pull LCD E-line to high */
Nop(); /* small delay */
temp = LCD_DATA & 0x7F; /* read DDRAM address */
Nop(); /* small delay to length E pulse */
LCD_E = 0; /* pull LCD E-line to low */
return temp;
}
No.6-57
The PIC18 Microcontroller
/*********************************************************************/
/* The following function sends a character to the LCD kit. */
/*********************************************************************/
void LCD_putc (char dx)
{
char addr;
LCD_rdy(); /* wait until LCD internal operation is complete */
send2LCD(dx);
LCD_rdy(); /* wait until LCD internal operation is complete */
addr = get_DDRAM_addr();
if (addr == 0x13) {
LCD_cmd(0xC0); /* set address to 0x40 (1st column of the 2nd row) */
LCD_rdy();
send2LCD(dx);
}
else if(addr == 0x53) {
LCD_cmd(0x94); /* set address to 0x14 (1st column of the 3rd row) */
LCD_rdy();
send2LCD(dx);
}
No.6-58
The PIC18 Microcontroller
/**************************************************************/
/* The following function outputs a string to the LCD. */
/**************************************************************/
void LCD_putstr(rom char *ptr)
{
while (*ptr) {
LCD_putc (*ptr);
ptr++;
}
}
No.6-59
The PIC18 Microcontroller
/**************************************************************/
/* The following function outputs a string to the LCD. */
/**************************************************************/
void LCD_putsr(char *ptr)
{
while (*ptr) {
LCD_putc (*ptr);
ptr++;
}
}
/****************************************************************/
/* The following function writes a character to the LCD. */
/****************************************************************/
void send2LCD(char xy)
{
LCD_RS = 1;
LCD_RW = 0;
LCD_E = 1;
LCD_DATA = xy;
Nop();
Nop();
LCD_E = 0;
}
No.6-60
The PIC18 Microcontroller
SW DIP-8 PIC18F8680
RF0
RF1
RF2
RF3
RF4
RF5
RF6
RF7
Figure 7.24b Connecting a set of eight DIP switches to port F of the PIC18F8680
No.6-61
The PIC18 Microcontroller
2. Capacitive: Two parallel plates. Pressing the plates changes the distance between
No.6-62
The PIC18 Microcontroller
3. Hall effect: The motion of the magnetic flux lines of a permanent magnet perpendicular
to a crystal is detected as voltage appearing between the two faces of the crystal
4. Mechanical: Two metal contacts are brought together to complete an electrical circuit
No.6-63
The PIC18 Microcontroller
- Most popular
- Pressing the key switch generates a series of pulses instead of a single clean
output
No.6-64
The PIC18 Microcontroller
1. Keypad scanning
2. Key switch debouncing
3. Table lookup
Keypad Scanning
No.6-65
The PIC18 Microcontroller
PIC18 MCU
RJ7
RJ6
RJ5
RJ4
RJ3 3 7 B F
RJ2 2 6 A E
RJ1 1 5 9 D
RJ0 0 4 8 C
4.7K 5V
No.6-66
The PIC18 Microcontroller
Keypad Debouncing
- When a key is pressed, the voltage of the key switch falls and rises a few times within
a period of about 5 ms as a contact bounces.
- A debouncer will recognize that the switch is closed after the voltage is low for about
10 ms and will recognize that the switch is open after the voltage is high for about 10
ms.
- Both hardware and software debouncing solutions are available.
- The simplest and most popular software solution is wait-and-see. The program
simply waits for 10 ms after detecting a key switch is closed and re-examines the
same key.
- Three hardware debouncing techniques are shown in Figure 7.27.
- The keypad input subroutine returns the ASCII code to the caller.
- This step can be embedded in the debouncing procedure.
No.6-67
The PIC18 Microcontroller
VDD
Set
R Q Q
VDD
R
4050 Vout
VDD
R
H
Vout
Threshold level
C
L
Switch closed
(c) Integrating RC circuit debouncer
No.6-68
The PIC18 Microcontroller
Example 7.10 Write a program to perform keypad scanning, debouncing, and returns
the ASCII code of the pressed key to the caller.
Solution:
The instruction sequence for the first row is as follows:
keypad_dir equ TRISJ ; keypad direction control register
keypad equ PORTJ ; keypad port
No.6-69
The PIC18 Microcontroller
No.6-70
The PIC18 Microcontroller
; *******************************************************************
; This subroutine creates a 10 ms delay using timer 0 with fOSC = 32 MHz.
; *******************************************************************
wait10ms bcf INTCON,INT0IE,A ; disable TMR0 interrupt
bcf INTCON,INT0IF,A ; clear TMR0IF flag
movlw 0x03 ; configure TMR0 with 1:16 prescaler
movwf T0CON,A ; configure TMR0
movlw 0x3C
movwf TMR0H,A
movlw 0xBB
movwf TMR0L,A ; load (50000 - 12) into TMR0
bsf T0CON,TMR0ON,A ; enable TMR0
dlyloop btfss INTCON,INT0IF,A ; is 10 ms over yet?
goto dlyloop
return
end
No.6-71
The PIC18 Microcontroller
#include <p18F8680.h>
#define keypad_dir TRISJ
#define keypad PORTJ
void wait_10ms(void);
…
unsigned char get_key (void)
{
keypad_dir = 0x0F; /* configure RJ7..RJ4 for output */
keypad |= 0xF0; /* RJ3..RJ0 for input */
while (1) {
keypad &= 0xEF; /* set RJ4 to low to scan the first row */
if (!(keypadbits.RB0)) {
wait_10ms( );
if (!(keypadbits.RB0))
return 0x30; /* return the ASCII code of 0 */
}
if (!(keypadbits.RB1)) {
wait_10ms( );
if (!(keypadbits.RB1))
return 0x31; /* return the ASCII code of 1 */
…
}
No.6-72
The PIC18 Microcontroller
VDD 1 16 OUTA
input -
REF 2 15 OUTB D7 DAC A OUTA
latch A +
.
SHDN 3 14 GND
.
input -
WR 4 MAXIM 13 A0 D0 OUTB
DAC B +
MAX5102 latch B
D7 5 12 D0
D6 6 11 D1
Control
D5 7 10 D2 A0
logic
D4 8 9 D3 MAX5102
WR REF SHDN
Figure 7.28 MAX5102 Pin configuration Figure 7.29 MAX5102 Pin configuration
No.6-73
The PIC18 Microcontroller
Pin Functions
Voltage Output
No.6-74
The PIC18 Microcontroller
5V
PIC18 MAX5102
VDD 0.1F
RD7..RD0 D7..D0 REF
OUTA
RB1 WR
OUTB
RB0 A0 SHDN
GND
No.6-75
The PIC18 Microcontroller
Example 7.11 Write a program to generate a 1KHz square wave from OUTA pin
assuming the instruction cycle time is 200 ns (correspond to 20 MHz crystal oscillator).
Solution: The procedure is as follows:
Step 1
Configure the pins RD7..RD0, RB1..RB0 for output.
Step 2
Clear the RB0 pin to low to select OUTA channel.
Step 3
Pull the RB1 pin to low.
Step 4
Output 255 to Port D.
Step 5
Pull the RB1 pin to high.
Step 6
Wait for 0.5 ms.
Step 7
Pull the RB1 pin to low.
Step 8
Output 0 to Port D.
Step 9
Pull the RB1 pin to high.
No.6-76
The PIC18 Microcontroller
Step 10
Wait for 0.5 ms.
Step 11
Go to Step 3.
No.6-77
The PIC18 Microcontroller
while (1) {
DAC_WR = low;
DAC_data = 255; /* output a high voltage */
DAC_WR = high;
Delay100TCYx(25); /* wait for 0.5 ms */
DAC_WR = low;
DAC_data = 0; /* output a low voltage */
DAC_WR = high;
Delay100TCYx(25); /* wait for 0.5 ms */
}
}
No.6-78
The PIC18 Microcontroller
Chapter 8
No.8-1
The PIC18 Microcontroller
Introduction
No.8-2
The PIC18 Microcontroller
No.8-3
The PIC18 Microcontroller
Timer0
- Can be configured as an 8-bit or 16-bit timer or counter.
- Can select the internal instruction cycle clock or the T0CKI signal as the clock signal.
- The user can choose to divide the clock signal by a prescaler before connecting it to
the clock input to Timer0.
- The T0CON register controls the operation of Timer0.
Set interrupt
flag bit TMR0IF
on overflow
FOSC/4 0
1 Sync with TMR0
1 internal TMR0L
Programmable high byte
T0CKI pin 0 clocks
Prescaler 8
T0CS (2 Tcy delay) Read TMR0L
T0SE 3
PSA 8 8
Write TMR0L
T0PS2,T0PS1,T0PS0
TMR0H
8
Data bus <7:0>
Figure 8.1b Timer0 block diagram in 16-bit mode (redraw with permission of Microchip)
No.8-4
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
value after TMR0ON T08BIT T0CS T0SE PSA T0PS2 T0PS1 T0PS0
reset 1 1 1 1 1 1 1 1
TMR0ON: Timer0 on/off control bit
0 = stops Timer0
1 = Enables Timer0
T08BIT: Timer0 8-bit/16-bit control bit
0 = Timer0 is configured as a 16-bit timer
1 = Timer0 is configured as an 8-bit timer
T0CS: Timer0 clock source select
0 = Instruction cycle clock
1 = Transition on T0CKI pin
T0SE: Timer0 source edge select bit
0 = Increment on falling edge transition on T0CKI pin
1 = Increment on rising edge transition on T0CKI pin
PSA: Timer0 prescaler assignment bit
0 = Timer0 prescaler is assigned . Timer0 clock input comes from prescaler output.
1 = Timer0 prescaler is not assigned. Timer0 clock input bypasses prescaler.
T0PS2:T0PS0: Timer0 prescaler select bits
000 = 1:2 prescaler value
001 = 1:4 prescaler value
010 = 1:8 prescaler value
011 = 1:16 prescaler value
100 = 1:32 prescaler value
101 = 1:64 prescaler value
110 = 1:128 prescaler value
111 = 1:256 prescaler value
No.8-5
The PIC18 Microcontroller
Example 8.2 Write a subroutine to create a time delay that is equal to 100 ms times the
contents of the PRODL register assuming that the crystal oscillator is running at 32
MHz.
Solution: The 100 ms delay can be created as follows:
1. Place the value 15535 into the TMR0 high byte and the TMR0L register so that
Timer0 will overflow in 50000 clock cycles.
2. Choose instruction cycle clock as the clock source and set the prescaler to 16
so that Timer0 will roll over in 100 ms.
3. Enable Timer0.
4. Wait until Timer0 to overflow.
No.8-6
The PIC18 Microcontroller
No.8-7
The PIC18 Microcontroller
In C language,
No.8-8
The PIC18 Microcontroller
Timer1
No.8-9
The PIC18 Microcontroller
Data bus
<7:0>
8
TMR1ON T1SYNC
on/off
T1OSC
T13CKI/T1OSC 1 Synchronize
Prescaler
T1OSCEN de
FOSC/4 1, 2, 4, 8
Enable 0
internal t
T1OSI Oscillator
clock
2 SLEEP input
TMR1CS
T1CKPS1:T1CKPS0
Figure 8.3 Timer1 block diagram: 16-bit mode (redraw with permission of Microchip)
No.8-10
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
No.8-11
The PIC18 Microcontroller
Example 8.3 Use Timer0 as a timer to create a one-second delay and use Timer1 as a
counter to count the rising (or falling) edges of an unknown signal (at the T1CKI pin)
arrived in one second which would measure the frequency of the unknown signal. Write
a program to implement this idea assuming that the PIC18 MCU is running with a 32
MHz crystal oscillator.
Solution:
A one-second delay can be created by placing 10 in PRODL and calling the delay
function in Example 8.2.
• 16-bit mode
• prescaler value set to 1
• disable oscillator
• do not synchronize external clock input
• select external T1CKI pin signal as the clock source
No.8-12
The PIC18 Microcontroller
No.8-13
The PIC18 Microcontroller
#include <p18F8680.inc>
t1ov_cnt set 0x00 ; Timer1 rollover interrupt count
freq set 0x01 ; to save the contents of Timer1 at the end
org 0x00
goto start
; high priority interrupt service routine
org 0x08
btfss PIR1,TMR1IF,A ; skip if Timer1 roll-over interrupt
retfie ; return if not Timer1 interrupt
bcf PIR1,TMR1IF,A ; clear the interrupt flag
incf t1ov_cnt,F,A ; increment Timer1 roll-over count
retfie
; dummy low priority interrupt service routine
org 0x18
retfie
start clrf t1ov_cnt,A ; initialize Timer1 overflow cnt to 0
clrf freq,A ; initialize frequency to 0
clrf freq+1,A ; "
clrf TMR1H ; initialize Timer1 to 0
clrf TMR1L ; "
clrf PIR1 ; clear all interrupt flags
bsf RCON,IPEN,A ; enable priority interrupt
No.8-14
The PIC18 Microcontroller
No.8-15
The PIC18 Microcontroller
#include <p18F8680.h>
unsigned int t1ov_cnt;
unsigned short long freq;
void high_ISR(void);
void low_ISR(void);
#pragma code high_vector = 0x08 // force the following statement to
void high_interrupt (void) // start at 0x08
{
_asm
goto high_ISR
_endasm
}
#pragma code //return to the default code section
#pragma interrupt high_ISR
void high_ISR (void)
{
if(PIR1bits.TMR1IF){
PIR1bits.TMR1IF = 0;
t1ov_cnt ++;
}
}
No.8-16
The PIC18 Microcontroller
No.8-17
The PIC18 Microcontroller
Timer2
- 8-bit timer TMR2 and 8-bit period register PR2.
Prescaler Reset
FOSC/4 TMR2
1:1, 1:4, 1:16
2 Postcaler
Comparator
T2CKPS1:T2CKPS0 EQ 1:1 to 1:16
4
PR2
T2OUTPS3:T2OUTPS0
No.8-18
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
No.8-19
The PIC18 Microcontroller
Example 8.4 Assume that the PIC18F8680 is running with a 32 MHz crystal oscillator.
Write an instruction sequence to generate periodic interrupts every 8 ms with high
priority using Timer2.
Solution: By setting the prescaler and postscaler to 16 and loading 249 into the PR2
register, Timer2 will generate periodic interrupt every 8 ms:
No.8-20
The PIC18 Microcontroller
Timer3
- Timer3 consists of two 8-bit registers TMR3H and TMR3L.
- Timer3 can choose to use either the internal (instruction cycle clock) or
external signal as the clock source.
- The block diagram of Timer3 is quite similar to that of Timer1.
- Reading TMR3L will load the high byte of Timer3 into the TMR3H
register.
- Timer3 operation is controlled by the T3CON register.
No.8-21
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
value after RD16 T3CCP2 T3CKPS1 T3CKPS0 T3CCP1 T3SYNC TMR3CS TMR3ON
reset 0 0 0 0 0 0 0 0
RD16: 16-bit read/write mode enable bit
0 = Enables read/write of Timer3 in two 8-bit operations
1 = Enables read/write of Timer3 in 16-bit operation
T3CCP2:T3CCP1: Timer3 and Timer1 to CCPx enable bits
00 = Timer1 and Timer2 are the clock sources for CCP1 through CCP5
01 = Timer3 and Timer4 are the clock sources for CCP2 through CCP5;
Timer1 and Timer2 are the clock sources for CCP1
10 = Timer3 and Timer4 are the clock sources for CCP3 through CCP5;
Timer1 and Timer2 are the clock sources for CCP1 and CCP2
11 = Timer3 and Timer4 are the clock sources for CCP1 through CCP5
T3CKPS1:T3CKPS0: Timer3 input clock prescale select bits
00 = 1:1 prescale value
01 = 1:2 prescale value
10 = 1:4 prescale value
11 = 1:8 prescale value
T3SYNC: Timer3 external clock input synchronization select bit
When TMR3CS = 1
0 = Synchronizes external clock input
1 = Do not synchronize external clock input
When TMR3CS = 0
This bit is ignored.
TMR3CS: Timer3 clock source select bit
0 = Instruction cycle clock (FOSC/4)
1 = External clock from pin RC0/T1OSO/T13CKI
TMR3ON: Timer3 on bit
0 = Stops Timer3
1 = Enables Timer3
Figure 8.8. T3CON contents (redraw with permission of Microchip)
No.8-23
The PIC18 Microcontroller
Timer4
- Only available to the PIC18F8X2X and PIC18F6X2X devices.
- The block diagram of Timer4 is shown in Figure 8.9.
- The value of TMR4 is compared to PR4 in each clock cycle.
- When the value of TMR4 equals that of PR4, TMR4 is reset to 0.
- The contents of T4CON are identical to those of T2CON.
Prescaler Reset
FOSC/4 TMR4
1:1, 1:4, 1:16
2 Postcaler
Comparator
T4CKPS1:T4CKPS0 EQ 1:1 to 1:16
4
PR4
T4OUTPS3:T4OUTPS0
No.8-24
The PIC18 Microcontroller
The arguments to these functions are a bit mask that is created by ANDing the values
from each category.
No.8-25
The PIC18 Microcontroller
Example
No.8-26
The PIC18 Microcontroller
writeTimer0 (15535);
No.8-27
The PIC18 Microcontroller
- In capture or compare mode, the CCP module may use either Timer1 or Timer3 to
operate.
- The operations of all CCP modules are identical, with the exception of the special
No.8-28
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
-- -- DCxB1 DCxB0 CCPxM3 CCPxM2 CCPxM1 CCPxM0
value after
reset 0 0 0 0 0 0 0 0
DCxB1:DCxB0: PWM duty cycle bit 1 and bit 0 for CCP module x
capture mode:
unused
compare mode:
unused
PWM mode:
These two bits are the lsbs (bit 1 and bit 0) of the 10-bit PWM duty cycle.
CCPxM3:CCPxM0: CCP module x mode select bits
0000 = capture/compare/PWM disabled (resets CCPx module)
0001 = reserved
0010 = compare mode, toggle output on match (CCPxIF bit is set)
0100 = capture mode, every falling edge
0101 = capture mode, every rising edge
0110 = capture mode, every 4th rising edge
0111 = capture mode, every 16th rising edge
1000 = compare mode, initialize CCP pin low, on compare match force CCP pin high
(CCPxIF bit is set)
1001 = compare mode, initialize CCP pin high, on compare match force CCP pin low
(CCPxIF bit is set)
1010 = compare mode, generate software interrupt on compare match (CCP pin
unaffected, CCPxIF bit is set).
1011 = compare mode, trigger special event (CCPxIF bit is set)
For CCP1 and CCP2: Timer1 or Timer3 is reset on event
For all other modules: CCPx pin is unaffected and is configured as an I/O port.
11xx = PWM mode
Figure 8.10 CCPxCON register (x = 1,..,5) (redraw with permission of Microchip)
No.8-29
The PIC18 Microcontroller
- Each module is associated with a control register (CCPxCON) and a data register
(CCPRx).
- The data register in turn consists of two 8-bit register: CCPRxL and CCPRxH.
- The assignment of a particular timer to a module is determined by the bit 6 and bit 3
No.8-30
The PIC18 Microcontroller
Figure 8.11 CCP and Timer interconnect configurations (redraw with permission of Microchip)
No.8-31
The PIC18 Microcontroller
and TMR1
edge detect T3CCP2 enable
TMR1H TMR1L
Q's CCPxCON<3:0>
Figure 8.13 Capture mode operation block diagram (redraw with permission of Microchip)
No.8-32
The PIC18 Microcontroller
Capture Operation
No.8-33
The PIC18 Microcontroller
There are two values for the parameter config: interrupt enabling and the edge to
capture.
Interrupt enabling
Edge to capture
No.8-34
The PIC18 Microcontroller
No.8-35
The PIC18 Microcontroller
Example 8.5 Period measurement. Use the CCP channel 1 in capture mode to
measure the period of an unknown signal assuming that the PIC18 MCU is running
with a 16 MHz crystal oscillator. Use the number of clock cycles as the unit of period.
The period of the unknown signal is shorter than 65536 clock cycles.
Solution:
Either two consecutive rising edges or two falling edges must be captured.
The difference of these two edges becomes the period of the signal.
The required timers settings are
No.8-36
The PIC18 Microcontroller
#include <p18F8720.inc>
org 0x00
goto start
org 0x08
retfie
org 0x18
retfie
start bsf TRISC,CCP1,A ; configure CCP1 pin for input
movlw 0x81 ; use Timer1 as the time base
movwf T3CON,A ; of CCP1 capture
bcf PIE1,CCP1IE,A ; disable CCP1 capture interrupt
movlw 0x81 ; enable Timer1, prescaler set to 1,
movwf T1CON,A ; 16-bit, use instruction cycle clock
movlw 0x05 ; set CCP1 to capture on every rising edge
movwf CCP1CON,A ; "
bcf PIR1,CCP1IF,A ; clear the CCP1IF flag
edge1 btfss PIR1,CCP1IF,A ; wait for the first edge to arrive
bra edge1 ; "
movff CCPR1H,PRODH ; save the first edge
movff CCPR1L,PRODL ; "
No.8-37
The PIC18 Microcontroller
No.8-38
The PIC18 Microcontroller
#include <p18F8720.h>
void main (void)
{
unsigned int period;
No.8-39
The PIC18 Microcontroller
- The clock period of an unknown signal could be much longer than 2 16 clock cycles.
- One will need to keep track of the number of times that the timer overflows.
- Each timer overflow adds 216 clock cycles to the period.
Let
ovcnt = timer overflow count
diff = the difference of two edges
edge1 = the captured time of the first edge
edge2 = the captured time of the second edge
- The Timer1 overflow interrupt should be enabled after the first signal edge is
captured.
- Timer1 interrupt service routine simply increments ovcnt by 1 and returns.
No.8-40
The PIC18 Microcontroller
Example 8.6 Write a program to measure the period of a signal connected to the
CCP1 pin assuming that the instruction clock is running at 5 MHz. Make the program
more general so that it can also measure the period of a signal with very low frequency.
Solution:
#include <p18F8720.inc>
ov_cnt set 0x00 ; timer overflow count
per_hi set 0x01 ; high byte of edge difference
per_lo set 0x02 ; low byte of edge difference
org 0x00
goto start
org 0x08
goto hi_pri_ISR ; go to the high-priority service routine
org 0x18
retfie
No.8-41
The PIC18 Microcontroller
No.8-42
The PIC18 Microcontroller
#include <p18F8720.h>
#include <timers.h>
#include <capture.h>
unsigned int ov_cnt, temp;
unsigned short long period; /* 24-bit period value */
void high_ISR(void);
void low_ISR(void);
#pragma code high_vector = 0x08 // force the following statement to
void high_interrupt (void) // start at 0x08
{
_asm
goto high_ISR
_endasm
}
#pragma interrupt high_ISR
void high_ISR (void)
{
if (PIR1bits.TMR1IF) {
PIRbits.TMR1IF = 0;
ov_cnt ++;
}
No.8-44
The PIC18 Microcontroller
No.8-45
The PIC18 Microcontroller
No.8-46
The PIC18 Microcontroller
- The 16-bit CCPRx register is compared against the TMR1 (or TMR3).
- When they match, one of the following actions may occur on the associated CCPx pin:
1. driven high
2. driven low
3. toggle output
4. remains unchanged
- The CCP1 and CCP2 modules can also generate this event to reset TMR1 or TMR3
depending on which timer is the base timer.
No.8-47
The PIC18 Microcontroller
special event
trigger
CCPRxH CCPRxL
set flag bit
CCPxIF
Q S Output
Logic comparator
CCPx pin R match
output
enable
CCPxCON<3:0> T3CCP2 0 1
mode select
Figure 8.19 Circuit for CCP in compare mode (redraw with permission of Microchip)
- The CCP compare mode can be used to generate waveforms and create delays.
No.8-48
The PIC18 Microcontroller
Example 8.7 Use CCP1 to generate a periodic waveform with 40% duty cycle and 1
KHz frequency assuming that the instruction cycle clock frequency is 4 MHz.
Solution: The waveform of 1 KHz waveform is shown in Figure 8.20.
400 s
600 s
No.8-49
The PIC18 Microcontroller
Start
no
CCP1IF = 1?
yes
set CCP1 pin low initially and then
pull high on match
no
CCP1IF = 1?
yes
set CCP1 pin high initially and then
pull low on match
Figure 8.21b Logic flow for generating a 1-KHz waveform with 40% duty cycle
No.8-50
The PIC18 Microcontroller
#include <p18F8720.inc>
hi_hi equ 0x06 ; number (1600) of clock cycles that signal
hi_lo equ 0x40 ; is high
lo_hi equ 0x09 ; number (2400) of clock cycles that signal
lo_lo equ 0x60 ; is low
org 0x00
goto start
…
start bcf TRISC,CCP1 ; configure CCP1 pin for output
movlw 0xC9 ; enable 16-bit Timer3, prescaler 1:1
movwf T3CON ; “
bcf PIR1,CCP1IF
movlw 0x09 ; CCP1 pin set high initially and
movwf CCP1CON ; pull low on match
; CCPR1 TMR3 + 1600 ; start a new compare operation
movlw hi_lo ; “
addwf TMR3L,W ; “
movwf CCPR1L ; “
movlw hi_hi ; “
addwfc TMR3H,W ; “
addwfc TMR3H,W ; “
No.8-51
The PIC18 Microcontroller
bcf PIR1,CCP1IF
hi_time btfss PIR1,CCP1IF ; wait until CCPR1 matches TMR3
bra hi_time ; “
bcf PIR1,CCP1IF
movlw 0x08 ; CCP1 pin set low initially and
movwf CCP1CON ; pull high on match
; CCPR1 CCPR1 + 2400 ; start another compare operation
movlw lo_lo ; “
addwf CCPR1L,F ; “
movlw lo_hi ; “
addwfc CCPR1H,F ; “
lo_time btfss PIR1,CCP1IF ; wait until CCPR1 matches TMR3
bra lo_time ; “
bcf PIR1,CCP1IF
movlw 0x09 ; CCP1 pin set high initially and
movwf CCP1CON ; pull low on match
movlw hi_lo ; start another new compare operation
addwf CCPR1L,F ; “
movlw hi_hi ; “
addwfc CCPR1H,F ; “
bra hi_time
end
No.8-52
The PIC18 Microcontroller
#include <p18F8720.h>
void main (void)
{
TRISCbits.TRISC2 = 0; /* configure CCP1 pin for output */
T3CON = 0xC9; /* turn on TMR3 in 16-bit mode, TMR3 & TMR4 as
base timer for all CCP modules */
CCP1CON = 0x09; /* configure CCP1 pin set high initially and pull low
on match */
CCPR1 = TMR3 + 1600; /* start CCP1 compare operation with 1600 cycles
delay */
PIR1bits.CCP1IF = 0;
while (1) {
while (!(PIR1bits.CCP1IF));
PIR1bits.CCP1IF = 0;
CCP1CON = 0x08; /* set CCP1 pin low initially, pull high on match */
CCPR1 += 2400; /* start CCP1 compare with 2400 as delay */
while (!(PIR1bits.CCP1IF));
PIR1bits.CCP1IF = 0;
CCP1CON = 0x09; /* change CCP1 setting */
CCPR1 += 1600;
}
}
No.8-53
The PIC18 Microcontroller
#include <p18F8720.inc>
hi_hi equ 0x06 ; number (1600) of clock cycles that signal
hi_lo equ 0x40 ; is high
lo_hi equ 0x09 ; number (2400) of clock cycles that signal
lo_lo equ 0x60 ; is low
flag equ 0x00 ; select 1600 (=0) or 2400 (=1) as delay
org 0x00
goto start
org 0x08
goto hi_ISR
org 0x18
retfie
start bcf TRISC,CCP1 ; configure CCP1 pin for output
movlw 0xC9 ; choose TMR3 as the base timer for
movwf T3CON ; CCP1
movlw 0x09 ; configure CCP1 pin to set high initially
No.8-54
The PIC18 Microcontroller
No.8-55
The PIC18 Microcontroller
bsf PIE1,CCP1IE ; “
forever nop ; wait for interrupt to occur
bra forever
No.8-56
The PIC18 Microcontroller
Example 8.9 Assume that there is a PIC18 demo board (e.g., SSE8720) running with a
16-MHz crystal oscillator. Write a function that uses CCP1 in compare mode to create
a time delay that is equal to 10 ms multiplied by the contents of PRODL.
Solution:
- Set the Timer3 prescaler to 1
- Use 40000 as the delay count of the compare operation
No.8-57
The PIC18 Microcontroller
5V
10
8
PIC18F452
74HC04
1K
CCP1 2N2222
No.8-59
The PIC18 Microcontroller
Example 8.10 Use the circuit in Figure 8.22 to generate a siren that oscillates between
440 Hz and 880 Hz assuming the PIC18 is running with a 4 MHz crystal oscillator.
Solution: The procedure is as follows:
Step 1. Configure the CCP channel to operate in the compare mode and toggle output on
match.
Step 2. Start a compare operation and enable its interrupt with a delay equals to half of
the period of the sound of the siren.
Step 3. Wait for certain amount of time (say half of a second). During the waiting period,
interrupts will be requested by the CCP compare match many times. The interrupt
service routine simply clears the CCP flag and starts the next compare operation and
then return.
Step 4. At the end of the delay choose different delay time for the compare operation so
the siren sound with different frequency can be generated.
Step 5. Wait for the same amount of time as in Step 3. Again, interrupt caused by CCP
compare match will be requested many times.
Step 6. Go to Step 2.
No.8-60
The PIC18 Microcontroller
#include <p18F452.inc>
hi_hi equ 0x02 ; delay count to create 880 Hz sound
hi_lo equ 0x38 ; "
lo_hi equ 0x04 ; delay count to create 440 Hz sound
lo_lo equ 0x70 ; "
org 0x00
goto start
org 0x08
goto hi_ISR
org 0x18
retfie
start bcf TRISC,CCP1,A ; configure CCP1 pin for output
movlw 0x81 ; Enable Timer3 for 16-bit mode, use
movwf T3CON,A ; Timer1 as the base timer of CCP1
movwf T1CON,A ; enables Timer1 for 16-bit, prescaler set to 1:1
movlw 0x02 ; CCP1 pin toggle on match
movwf CCP1CON,A ; "
bsf RCON,IPEN ; enable priority interrupt
bsf IPR1,CCP1IP ; configure CCP1 interrupt to high priority
movlw hi_hi ; load delay count for compare operation
No.8-61
The PIC18 Microcontroller
No.8-62
The PIC18 Microcontroller
No.8-63
The PIC18 Microcontroller
Example 8.11 For the circuit in Figure 8.22, write a program to generate a simple song
assuming that fOSC = 4MHz.
Solution:
- The example song to be played is a German folk song. Two tables are used by the
program:
1. Table of numbers to be added to CCPR1 register to generate the waveform with the
desired frequency.
2. Table of numbers that select the duration of each note.
#include <p18F452.h>
#define base 3125 /* counter count to create 0.1 s delay */
#define NOTES 38 /* total notes in the song to be played */
#define C4 0x777
#define F4 0x598
#define G4 0x4FC
#define A4 0x470
#define B4 0x3F4
#define C5 0x3BC
#define D5 0x353
#define F5 0x2CC
No.8-64
The PIC18 Microcontroller
No.8-65
The PIC18 Microcontroller
No.8-66
The PIC18 Microcontroller
No.8-67
The PIC18 Microcontroller
}
/* ---------------------------------------------------------------------------------------------------- */
/* The following function runs on a PIC18 demo board running with a 4 MHz crystal */
/* oscillator. The parameter xc specifies the amount of delay to be created */
/* ---------------------------------------------------------------------------------------------------- */
void delay (unsigned char xc)
{
switch (xc){
case 1: /* create 0.1 second delay (sixteenth note) */
T0CON = 0x84; /* enable TMR0 with prescaler set to 32 */
TMR0 = 0xFFFF - base; /* set TMR0 to this value so it overflows in
0.1 second */
INTCONbits.TMR0IF = 0;
while (!INTCONbits.TMR0IF);
break;
No.8-68
The PIC18 Microcontroller
No.8-69
The PIC18 Microcontroller
INTCONbits.TMR0IF = 0;
while (!INTCONbits.TMR0IF);
break;
case 6: /* create 1.2 second delay (3 quarter note) */
T0CON = 0x84; /* set prescaler to Timer0 to 32 */
TMR0 = 0xFFFF - 12*base; /* set TMR0 to this value so it overflows
in 1.2 second */
INTCONbits.TMR0IF = 0;
while (!INTCONbits.TMR0IF);
break;
case 7: /* create 1.6 second delay (full note) */
T0CON = 0x84; /* set prescaler to Timer0 to 32 */
TMR0 = 0xFFFF - 16*base; /* set TMR0 to this value so it overflows
in 1.6 second */
INTCONbits.TMR0IF = 0;
while (!INTCONbits.TMR0IF);
break;
default:
break;
}
}
No.8-70
The PIC18 Microcontroller
CCPRxH (slave)
Comparator R Q
CCPx
TRISz<k>
TMRy (y = 2 or 4) z = C or B or G
S
Comparator
Clear timer,
CCPx pin and
latch D.C
PRy (y=2 or 4)
Figure 8.24 Simplified PWM block diagram (redraw with permission of Microchip)
No.8-71
The PIC18 Microcontroller
Step 1
Set the PWM period by writing to the PRy (y = 2 or 4) register.
Step 2
Set the PWM duty cycle by writing to the CCPRxL register and CCPxCON<5:4> bits.
Step 3
Configure the CCPx pin for output
Step 4
Set the TMRy prescale value and enable Timery by writing to TyCON register
Step 5
Configure CCPx module for PWM operation
No.8-72
The PIC18 Microcontroller
Example 8.12 Configure CCP1 in PWM mode to generate a digital waveform with
40% duty cycle and 10 KHz frequency assuming that the PIC18 MCU is running with
a 32 MHz crystal oscillator.
Solution:
Timer setting
1. Use Timer2 as the base timer of CCP1 through CCP5 for PWM mode
2. Enable Timer3 in 16-bit mode with 1:1 prescaler
3. Set Prescaler to Timer2 to 1:4
No.8-73
The PIC18 Microcontroller
No.8-74
The PIC18 Microcontroller
No.8-75
The PIC18 Microcontroller
No.8-76
The PIC18 Microcontroller
No.8-77
The PIC18 Microcontroller
Example 8.14 Write a program to dim the lamp in Figure 8.25 to 10% of its brightness
in 5 seconds assuming that the PIC18 is running with a 32 MHz crystal oscillator.
Solution:
- Set duty cycle to 100% initially. Load 99 and 400 as the initial period and duty
cycle register values.
- Dim the lamp by 10% in the first second by reducing the brightness in 10 steps.
- Dim the lamp down to 10% brightness in the next 4 seconds in 40 steps.
#include <p18F452.inc>
org 0x00
goto start
org 0x08
retfie
org 0x18
retfie
start bcf TRISC,CCP1,A ; configure CCP1 pin for output
movlw 0x81 ; Use Timer2 as the base timer for PWM1
movwf T3CON ; and enable Timer3 in 16-bit mode
movlw 0x63 ; set 100 as the period of the digital
movwf PR2,A ; waveform
No.8-78
The PIC18 Microcontroller
No.8-79
The PIC18 Microcontroller
#include <p18F452.h>
#include <pwm.h>
#include <timers.h>
void delay (void);
void main (void)
{
int i;
TRISCbits.TRISC2 = 0; /* configure CCP1 pin for output */
T3CON = 0x81; /* use Timer2 as base timer for CCP1 */
OpenTimer2 (TIMER_INT_OFF & T2_PS_1_4 & T2_POST_1_1);
SetDCPWM1 (400); /* set duty cycle to 100% */
OpenPWM1 (99); /* enable PWM1 with period equals 100 */
for(i = 0; i < 10; i++) {
delay();
CCPR1L --; /* decrement duty cycle value by 1 */
}
for(i = 0; i < 40; i++) {
delay();
CCPR1L -= 2; /* decrement duty cycle value by 2 */
}
}
No.8-80
The PIC18 Microcontroller
DC Motor Control
- DC motor speed is regulated by controlling its average driving voltage. The higher
the voltage, the faster the motor rotates.
- Changing motor direction can be achieved by reversing the driving voltage.
- Motor braking can be performed by reversing the driving voltage for certain length
of time.
- Most PIC18 devices have PWM functions that can be used to drive DC motors.
- Many DC motors operate with 5 V supply.
- DC motors require large amount of current to operate. Special driver circuits are
needed for this purpose.
- A simplified DC motor control circuit is shown in Figure 8.26.
PIC18 MCU
direction
RB4
speed
CCP1 on/off Driver DC motor
feedback
CCP2
No.8-81
The PIC18 Microcontroller
Figure 8.27 Motor driver L293 pin assignment and motor connection
No.8-82
The PIC18 Microcontroller
FeedBack
- DC motor needs the speed information to adjust the voltage output to the motor
driver circuit.
- A sensing device such as Hall-effect transistor can be used to measure the motor
speed.
- The Hall-effect transistor can be mounted on the shaft (rotor) of a DC motor and
magnets are mounted on the armature (stator).
- The attachment of the Hall-effect transistors is shown in Figure 8.28.
- Each time the magnet passes by the Hall-effect transistor, a pulse is generated.
- CCP capture mode can be used to measure the motor speed.
- The schematic of a motor-control system is illustrated in Figure 8.29.
No.8-83
The PIC18 Microcontroller
Magnets
Hall-effect
transistor
T/2
T is the time for one revolution
Figure 8.28 The output waveform of the Hall-effect transistor
No.8-84
The PIC18 Microcontroller
VCC VCC
PIC18F452
1 16
8 3
15
CCP1 2 6.8F
13
RB4 7
12
0.33 F
4 L293
5
9 M
10 6
NC
11 14 VCC
VCC 6.8F
CCP2 1
30137
10K 3 2
All diodes are the same and could be any one of the 1N4000 series Hall-effect
switch
Figure 8.29 Schematic of a PIC18-based motor-control system
No.8-85
The PIC18 Microcontroller
L293
PWM (CCP1)
A When A = B, torque
applied to motor = 0
A
No.8-86
The PIC18 Microcontroller
Electrical Braking
- Once a DC motor is running, it picks up speed.
- Turning off the voltage to the motor does not stop the motor immediately.
- The momentum of the DC motor will keep the motor running after the voltage it
turned off.
- An abrupt stop may be achieved by reversing the voltage applied to the motor .
No.8-87
The PIC18 Microcontroller
Example 8.15 For the circuit shown in Figure 8.29, write a function in C language to
measure the motor speed (in RPM) assuming that the PIC18 MCU is running with a 20
MHz crystal oscillator.
Solution:
- Motor speed can be measured by capturing two consecutive rising or falling edges.
- Let diff and f are the difference of two captured edges and the Timer1 frequency.
Speed = 60 f ( 2 diff)
No.8-88
The PIC18 Microcontroller
T3CON = 0x81; /* enables Timer3 in 16-bit mode and use Timer1 and Timer2 for
CCP1 thru CCP2 operations */
OpenTimer1(TIMER_INT_OFF & T1_16BIT_RW & T1_SOURCE_INT &
T1_PS_1_4); /* set Timer1 prescaler to 1:4 */
PIR2bits.CCP2IF = 0;
OpenCapture2(CAPTURE_INT_OFF & C2_EVERY_RISE_EDGE);
while (!PIR2bits.CCP2IF);
edge1 = CCPR2; /* save the first rising edge */
PIR2bits.CCP2IF = 0;
while (!PIR2bits.CCP2IF);
CloseCapture2();
diff = CCPR2 - edge1; /* compute the difference of two rising consecutive edges */
temp = 1250000ul/(2 * diff);
rpm = temp * 60;
return rpm;
}
No.8-89
The PIC18 Microcontroller
No.8-90
The PIC18 Microcontroller
Chapter 9
No.9-1
The PIC18 Microcontroller
No.9-2
The PIC18 Microcontroller
1. Electrical specifications
2. Functional aspects—the function of each signal
3. Mechanical specifications
4. Procedural specifications
No.9-3
The PIC18 Microcontroller
Electrical Specifications
- Data rates: EIA232 is applicable to data rate no more than 20 Kbps. The most
commonly used data rates are 300, 1200, 2400, 9600, and 19200 baud
No.9-4
The PIC18 Microcontroller
Functional Specifications
No.9-5
The PIC18 Microcontroller
No.9-6
The PIC18 Microcontroller
Mechanical Specification
- Specifies a 25-pin connector
- A 9-pin connector is used most often in PC but not specified in the standard
No.9-7
The PIC18 Microcontroller
Signal Signal
Direction Signal Name Signal Name Direction
5 Ground
Ring Indicator 9
4 DTE Ready
Clear to Send 8
3 Transmitted Data
Request to send 7
2 Received Data
DCE Ready 6
1 Received Line Signal Detect
No.9-8
The PIC18 Microcontroller
No.9-9
The PIC18 Microcontroller
Time
Local Remote
1. DCE asserts DSR
No.9-10
The PIC18 Microcontroller
Tx Tx Tx Tx
Rx Rx Rx Rx
RING RING RING RING
Phone line
DCD DCD DCD DCD
CTS CTS CTS CTS
RTS RTS RTS RTS
DSR DSR DSR DSR
DTR DTR DTR DTR
GND GND GND GND
No.9-11
The PIC18 Microcontroller
time
Local (transmission side) Remote (receiving side)
Connection
establishment
phase
1. DTE asserts DTR
No.9-12
The PIC18 Microcontroller
time
Local (transmission side) Remote (receiving side)
Data
transmission
phase
1. DTE asserts RTS
No.9-13
The PIC18 Microcontroller
Data Format
No.9-14
The PIC18 Microcontroller
Example 9.1 Sketch the output of the letter K when it is transmitted using the format of
one start bit, eight data bits, and one stop bit.
Solution: Letters are represented in ASCII code. The ASCII code of letter K is $4B (=
01001011). The format of the output of letter K is shown in Figure 9.6.
0 1 1 0 1 0 0 1 0 1
0 1 1 0 1 0 0 1 0 1
(b) output waveform at EIA232E interface
Figure 9.6 Data format for letter k
No.9-15
The PIC18 Microcontroller
1. Framing error
- May occur due to clock synchronization problem
- Can be detected by the missing stop bit
2. Receiver overrun
- May occur when the CPU did not read the received data for a while
3. Parity errors
- Occur due to odd number of bits change values
No.9-16
The PIC18 Microcontroller
DTE 1 DTE 2
Signal Name Signal Name
DB25 pin DB9 pin DB9 pin DB25 pin
FG (frame ground) 1 - - 1 FG
TD (transmit data) 2 3 2 3 RD
RD (receive data) 3 2 3 2 TD
RTS (request to send) 4 7 8 5 CTS
CTS (clear to send) 5 8 7 4 RTS
SG (signal ground) 7 5 5 7 SG
DSR (data set ready) 6 6 4 20 DTR
CD (carrier detect) 8 1 4 20 DTR
DTR (data terminal ready ) 20 4 1 8 CD
DTR (data terminal ready ) 20 4 6 6 DSR
No.9-17
The PIC18 Microcontroller
USART-Related Pins
USART-Related Registers
- Transmit status register (TXSTA) - Transmit register (TXREG)
- Receive status register (RCSTA) - Receive register (RCREG)
- Baud rate generate register (SPBRG)
No.9-18
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
No.9-19
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
Value after SPEN RX9 SREN CREN ADDEN FERR OERR RX9D
reset 0 0 0 0 0 0 1 0
SPEN: Serial Port Enable bit
0 = Serial port disabled
1 = Serial port enabled
RX9: 9-bit Receive Enable bit
0 = Selects 8-bit reception
1 = Selects 9-bit reception
SREN: Single Receive Enable bit
Asynchronous mode (don't care)
Synchronous mode - Master (This bit is cleared after reception is complete):
0 = Disables single receive
1 = Enables single receive
Synchronous mode - Slave: (don't care)
CREN: Continuous Receive Enable bit
Asynchronous mode:
0 = Disables receiver
1 = Enables receiver
Synchronous mode:
0 = Disables continuous receive
1 = Enables continuous receive (CREN overrides SREN)
ADDEN: Address Detect Enable bit
Asynchronous mode 9-bit (RX9 = 1):
0 = Disables address detection, all bytes are received, and 9th bit can be used
as parity bit.
1 = Enables address detection, enable interrupt and load of the receive buffer
when RSR<8> is set
FERR: Framing Error bit
0 = no framing error
1 = Framing error
OERR: Overrun Error bit
0 = No overrun error
1 = Overrun error (can be cleared by clearing bit CREN)
RX9D: 9th bit of Received Data
This can be Address/Data bit or a parity bit, and must be calculated by firmware.
Figure 9.9 The RXSTA Register (redraw with permission of Microchip)
No.9-20
The PIC18 Microcontroller
- The shift clock for the USART is generated by the baud rate generator (SPBRG).
- In asynchronous mode, the BRGH bit of the TXSTA register also involves in the baud
rate computation.
- The baud rate is computed using the formula shown in Table 9.2.
In asynchronous mode:
When BRGH = 1, SPBRG = (FOSC/(16 x baud rate)) - 1
When BRGH = 0, SPBRG = (FOSC/(64 x baud rate)) - 1
In synchronous mode:
SPBRG = (FOSC/(4 x baud rate)) - 1
No.9-21
The PIC18 Microcontroller
Example 9.2 Compute the value to be written into the SPBRG register to generate 9600
baud for asynchronous mode high-speed transmission assuming the frequency of the crystal
oscillator is 20 MHz.
Solution: The value (for BRGH = 1) to be written into the SPBRG register is
The same baud rate can also be achieved by using low speed (BRGH = 0) approach in which
No.9-22
The PIC18 Microcontroller
Example 9.3 Write a subroutine to configure the USART1 transmitter to transmit data
in asynchronous mode using 8-bit data format, disable interrupt, set baud rate to 9600.
Assume the frequency of the crystal oscillator is 16 MHz.
Solution:
- Write the value of 0x24 into the TXSTA1 register
- Configure TX1 pin for output, RX1 pin for input:
No.9-24
The PIC18 Microcontroller
In C language,
void usart1_open(void)
{
TXSTA1 = 0x24;
SPBRG1 = 103;
TRISCbits.RC7 = 1; /* configure RX1 pin for input */
TRISCbits.RC6 = 0; /* configure TX1 pin for output */
PIE1bits.TXIE = 0; /* disable transmit interrupt */
RCSTA1bits.SPEN = 1; /* enable USART port */
}
No.9-25
The PIC18 Microcontroller
Example 9.4 Write a subroutine to output the character in WREG to USART1 using
the polling method.
Solution:
- Data can be sent to the transmitter only when the transmit register is empty.
putc_usart1 btfss PIR1,TXIF,A ; wait until TXIF flag is set before output
bra putc_usart1
movwf TXREG1
return
In C language,
No.9-26
The PIC18 Microcontroller
Example 9.5 Write a subroutine to output a string (in program memory) pointed to by
TBLPTR and terminated by a NULL character from USART1.
Solution:
; *******************************************************************
; The following subroutine outputs the string pointed to by TBLPTR. It is called
; with fast save enabled.
; *******************************************************************
puts_usart1 TBLRD*+ ; read one character into TABLAT
movf TABLAT,W,A ; place the character in WREG
bz done ; is it a NULL character?
call putc_usart1 ; not NULL, output
bra puts_usart1 ; continue
done return fast
In C language,
No.9-27
The PIC18 Microcontroller
RX pin
RX9
Pin Buffer Data
and Control Recovery
FIFO
RX9D RCREG Register
SPEN
interrupt
RCIF
RCIE 8
Data Bus
Figure 9.11 USART receive block diagram (redraw with permission of Microchip)
No.9-28
The PIC18 Microcontroller
Example 9.6 Write an instruction sequence to configure the USART1 to receive data in
asynchronous mode using 8-bit data format, disable interrupt, set baud rate to 9600.
Assume that the frequency of the crystal oscillator is 16 MHz.
Solution:
In C language,
RCSTA1 = 0x90;
SPBRG = 103;
TRISC |= 0x80; /* configure RC7/RX1 pin for input */
TRISC &= 0xBF /* configure RC6/TX1 pin for output */
No.9-29
The PIC18 Microcontroller
Example 9.7 Write a subroutine to read a character from USART1 and return the
character in WREG using the polling method. Ignore any errors.
Solution: A new character is received if the RCIF flag of the PIR1 register is set to 1.
getc_usart1 btfss PIR1,RCIF ; make sure a new character has been received
bra getc_usart1
movf RCREG1,W ; read the character
return FAST
In C language,
No.9-30
The PIC18 Microcontroller
Example 9.8 Write a subroutine to read a string from the USART1 and store the string
in a buffer pointed to by FSR0.
Solution:
The string from the USART port is terminated by a carriage return character.
CR equ 0x0D
gets_usart1 call getc_usart1
movwf INDF0 ; save the character in buffer
sublw CR
bz done
clrf PREINC0,F ; move the pointer
goto gets_usart1
done clrf INDF0 ; terminate the string with a NULL character
return
No.9-31
The PIC18 Microcontroller
In C language,
#define CR 0x0D
void gets_usart1 (char *ptr)
{
char xx;
while (1)
{
xx = getc_usart1( ); /* read a character */
if (xx == CR) { /* is it a carriage return? */
*ptr = ‗\0‘; /* terminate the string with a NULL */
return;
}
ptr++ = xx; /* store the received character in the buffer */
}
}
No.9-32
The PIC18 Microcontroller
- In some circumstances, the software cannot read the received data and needs to inform
the transmitter to stop.
- In some other situation, the transmitter may need to be told to suspend transmission
because the receiver is too busy to read data.
- Both situations are handled by flow control.
- There are two flow control methods: hardware and XON/XOFF.
- XON and XOFF are two standard ASCII characters.
- The ASCII code for XON and XOFF are 0x11 and 0x13, respectively.
- Whenever a microcontroller cannot handle the incoming data, it sends the XOFF to
the transmitter.
- When the microcontroller can handle incoming characters, it sends out XON
character.
No.9-33
The PIC18 Microcontroller
No.9-34
The PIC18 Microcontroller
No.9-35
The PIC18 Microcontroller
Any one of the following functions read a byte from the receive buffer including the 9 th
bit:
The following functions read the specified number of byes from the USART module and
save the string in a buffer:
void getsUSART (char *buffer, unsigned len); -- for devices with single USART
char gets1USART (char *buffer, unsigned len); -- for devices with two USART
char gets2USART (char *buffer, unsigned len); -- for devices with two USART
No.9-36
The PIC18 Microcontroller
The status bit and the 9th data bit are saved in a union with the following declaration:
union USART
{
unsigned char val;
struct
{
unsigned RX_NINE: 1;
unsigned TX_NINE: 1;
unsigned FRAME_ERROR: 1;
unsigned OVERRUN_ERROR: 1;
unsigned fill: 4;
};
};
No.9-37
The PIC18 Microcontroller
The following functions output a string in program memory to the USART module:
void putrsUSART (const rom char *data); -- used on devices with single USART
void putrs1USART (const rom char *data); -- used on devices with two USARTs
void putrs2USART (const rom char *data); -- used on devices with two USARTs
The following functions output a string in data memory to the USART module:
No.9-38
The PIC18 Microcontroller
Interrupt on Transmission:
USART_TX_INT_ON Transmit interrupt ON
USART_TX_INT_OFF Transmit interrupt OFF
Interrupt on Reception:
USART_RX_INT_ON Receive interrupt ON
USART_RX_INT_OFF Receive interrupt OFF
USART Mode:
USART_ASYNCH_MODE Asynchronous mode
USART_SYNCH_MODE Synchronous mode
No.9-39
The PIC18 Microcontroller
Transmission Width:
USART_EIGHT_BIT 8-bit transmit/receive
USART_NINE_BIT 9-bit transmit/receive
Slave/Master Select:
USART_SYNC_SLAVE Synchronous slave mode
USART_SYNC_MASTER Synchronous master mode
Reception mode:
USART_SINGLE_RX Single reception
USART_CONT_RX Continuous reception
Baud rate: (applied to asynchronous mode only)
USART_BRGH_HIGH High baud rate
USART_BRGH_LOW Low baud rate
The spbrg is the value to be written into the SPBRG register to set the baud rate.
An example,
Open1USART (USART_TX_INT_OFF & USART_RX_INT_OFF &
USART_ASYNCH_MODE & USART_EIGHT_BIT &
USART_BRGH_HIGH, 103);
No.9-40
The PIC18 Microcontroller
- The USART in asynchronous mode is mainly used with the EIA232 interface.
- The USART module uses 0 and 5V to represent logic 0 and 1 and hence cannot be
connected to the EIA232 circuit directly.
- A circuit called EIA232 transceiver is needed to translate the voltage levels of the
USART to and from the voltage levels of the EIA232 interface.
- EIA232 transceivers are available from many vendors.
- LT1080/1081 from Linear Technology, ST232 from SGS Thompson, the ICL232
from Intersil, the MAX232 from MAXIM, and the DS14C232 from National
Semiconductor are examples of the EIA232 transceiver. These EIA232 transceivers
operate with a 5-V power supply.
- The pin assignment of the MAX232 is shown in Figure 9.12.
- The circuit connection of the MAX232 with the PIC18 is shown in Figure 9.13.
No.9-41
The PIC18 Microcontroller
+5 V
6.3V
0.1F - +
16 0.1F C4
1 VCC
C1+
2
C1 0.1F V+
3
C1-
4 6
C2+ V-
C3 0.1F
C2 0.1F DC-to-DC Converter
5
C2-
+5 V
TTL/CMOS 11 T1IN D1
T1OUT 14
inputs +5 V
EIA-232-E
outputs
10 T2IN T2OUT 7
TTL/CMOS D2
inputs
GND
15
No.9-42
The PIC18 Microcontroller
MAX232 1
DCD
6 DSR
11 14 2
RC6/TX T1IN T1OUT RxD
10 8 7 RTS
CTS* T2IN R2IN
12 13 3
RC7/RX R1OUT R1IN TxD
9 7 8 CTS
RTS* R2OUT T2OUT
4
DTR
Note: Both CTS and RTS are
jumpered to an I/O pin in case 9 RI
hardware handshake is needed
5
GND
DB9 connector
Figure 9.13 Diagram of USART and EIA232 DB9 connector wiring in SSE452,
SSE8680, and SSE8720 demo boards
No.9-43
The PIC18 Microcontroller
No.9-44
The PIC18 Microcontroller
QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQ
1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
RC6/TX/CK
Write to
TXREG
TXIF bit
TRMT bit
TXEN bit
Figure 9.14 USART transmission in synchronous master mode (redraw with permission of
Microchip)
No.9-45
The PIC18 Microcontroller
QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQ
1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
RC6/TX/CK
Write to
SREN
SREN bit
RCIF bit
(interrupt)
No.9-46
The PIC18 Microcontroller
No.9-47
The PIC18 Microcontroller
VCC CP2 P3 P2 P1 P0 DS Q7
16 15 14 13 12 11 10 9
74LS165
1 2 3 4 5 6 7 8
PL CP1 P4 P5 P6 P7 GND
Q7
No.9-48
The PIC18 Microcontroller
Example 9.9 Show the circuit connection for using one 74LS165 to add an input port
to the PIC18F8720 using the USART2 in synchronous master mode. Write a
subroutine to configure the USART2 properly and a subroutine to shift one byte of
data assuming that the PIC18F8720 is running with a 16-MHz crystal oscillator.
Assume that the user uses eight switches to set the value to be input and uses INT1
interrupt to inform the arrival of data.
Solution:
1. Use the synchronous master mode to interface with the 74LS165.
2. Configure RG2/DT2 and RG1/CK2 for input and output, respectively.
3. Set baud rate to 1 Mbps
4. Enable INT1 interrupt
5. Circuit connection is shown in Figure 9.17.
No.9-49
The PIC18 Microcontroller
PIC18F8720 74LS165 5V
VCC
RG1/CK CP2 P0 D7
P1 D6
RG2/DT2 Q7 P2 D5
P3 D4 connected
to DIP
INT1 DS P4 D3 switches
debounced
CP1 P5 D2
switch
P6 D1
RB4 PL P7 D0
GND
No.9-50
The PIC18 Microcontroller
#include <p18F8720.inc>
rcv_buf set 0 ; buffer to hold the received byte
org 0x00
goto start
org 0x08
goto hi_ISR
org 0x18
retfie
start bcf TRISG,RG1,A ; configure CK2 pin for output
bsf TRISG,RG2,A ; configure DT2 pin for input
call open_usart2
call open_INT1
forever nop
bra forever
No.9-51
The PIC18 Microcontroller
; *****************************************************************
; The following function configures USART2 to operate in
; synchronous master mode with baud rate set to 10**6.
; *****************************************************************
open_usart2 movlw 0x03
movwf SPBRG2,A ; set the shift rate to 1MHz
movlw 0x90 ; set synchronous master mode
movwf TXSTA2,A ; "
movlw 0x80 ; enable USART2 and disable
movwf RCSTA2,A ; reception
return
; ************************************************************************
; The following subroutine configures INT1 to high priority and
; then enable its interrupt.
; ************************************************************************
open_INT1 bsf RCON,IPEN,A ; enable priority interrupt
movlw 0x48 ; set INT1 interrupt to high priority,
movwf INTCON3,A ; and then enable INT1 interrupt
movlw 0xC0 ; enable global interrupt
movwf INTCON ; "
return
No.9-52
The PIC18 Microcontroller
; *************************************************************************
; The high priority interrupt service routine makes sure
; that the interrupt is caused by usart2 INT1IF and then enable
; reception by setting SPEN bit. Wait until a byte is received.
; *************************************************************************
hi_ISR btfss INTCON3,INT1IF,A ; is interrupt caused by INT1?
retfie ; interrupt is not caused by INT1
bcf INTCON3,INT1IF,A ; clear INT1IF
bcf PORTB,RB4,A ; load data into 74LS165
nop ; "
bsf PORTB,RB4,A ; disable new data into 74LS165
bcf PIR3,RC2IF,A ;
bsf RCSTA2,SREN,A ; enable single reception from USART2
wait btfss PIR3,RC2IF,A ; wait for the arrival of a byte
bra wait
movff RCREG2,rcv_buf
retfie
end
No.9-53
The PIC18 Microcontroller
74LS164
1 2 3 4 5 6 7
A B Q0 Q1 Q2 Q3 GND
No.9-54
The PIC18 Microcontroller
Example 9.10 Show the circuit connection if you are to use one 74LS164 to add an
output port to the PIC18F8720 using the USART2 module in synchronous master
mode. Write a subroutine to shift out one byte of data assuming that the PIC18F8720 is
running with a 16-MHz crystal oscillator. The user may uses Q7..Q0 to drive LEDs.
Solution: The circuit connection is shown in Figure 9.19. Q7…Q0 should be used as
the least significant bit to the most significant bit.
PIC18F8720 74LS164 5V
VCC
RG1/CK CP Q7
Q6
RG2/DT2 A
Q5 used to
5V drive
Q4 output
B Q3 devces
such as
Q2 LEDs
MR
Q1
GND Q0
No.9-55
The PIC18 Microcontroller
Using the USART Synchronous Mode to Exchange Data with other PIC18 MCUs
RC7/TX1/CK1 RC7/TX1/CK1
RC7/RX1/DT1 RC7/RX1/DT1
Figure 9.20 Two PIC18s exchange data using USART synchronous mode
No.9-56
The PIC18 Microcontroller
Enhanced USART
No.9-57
The PIC18 Microcontroller
Chapter 9
Analog-to-Digital Converter
No.9-1
The PIC18 Microcontroller
temperature
pressure Digital
signal
voltage voltage A/D value
light Transducer conditioning Computer
weight circuit converter
airflow
Such as a (optional)
humidity sensor,
. load cell,
. photocall, or
. thermocouple
. Figure 12.1 The A/D conversion process
.
No.9-2
The PIC18 Microcontroller
Voltage
Figure 12.2 An ideal A/D converter output characteristic
No.9-3
The PIC18 Microcontroller
- The area between dotted line and staircase is called the quantization error.
- The resolution of this A/D converter is VDD/2n.
- Average conversion error is VDD/2n+1.
- A real A/D converter has nonlinearity.
2 n-
1
output code
1
0 Voltage
VDD
n
VDD /2
Figure 12.3 Output characteristic of an ideal n-bit A/D
converter
No.9-4
The PIC18 Microcontroller
analog
comparator
+ Vin (analog input)
-
Successive VRH
Control Digital-to-analog
Clock Logic approximation
converter VRL
register (SAR)
Output Digital
Latch code
No.9-5
The PIC18 Microcontroller
Start
SAR[n-1, ..., 0] 0
in-1
SAR[i] 1
Is the
Converted voltage yes
SAR[i] 0
greater than
the input?
no
no
i = 0?
yes
Sop
No.9-6
The PIC18 Microcontroller
- A/D converter requires a low reference voltage (VREF-) and a high reference
voltage (VREF+) to perform conversion.
- Most A/D converters are ratiomertic:
No.9-7
The PIC18 Microcontroller
Example 12.1 Suppose that there is a 10-bit A/D converter with VREF- = 1 V and VREF+
= 4V. Find the corresponding voltage values for the A/D conversion results of 25, 80,
240, 500, 720, 800, and 900.
Solution:
The corresponding voltages are as follows:
No.9-8
The PIC18 Microcontroller
Scaling Circuit
VIN +
OP AMP VOUT
R1 R2
No.9-9
The PIC18 Microcontroller
Example 12.2 Suppose the transducer output voltage ranges from 0V to 200 mV.
Choose the appropriate values for R1 and R2 to scale this range to 0~5V.
Solution:
No.9-10
The PIC18 Microcontroller
+12 V
- R1 +12 V
741 VIN -
+ VM 741 VOUT
+
- 12 V R2
- 12 V
VM = - VIN V1 Rf
VOUT = VIN - Rf V1 (12-5)
R1 R2
No.9-11
The PIC18 Microcontroller
R0
Rf
R0 +12 V
VIN - R1 +12 V
741 -
+ VM 741 V
+
- 12 V R2
- 12 V
VM = - VIN V1 Rf
VOUT = VIN - R
R1 R
No.9-12
The PIC18 Microcontroller
R0
Rf
R0 +12 V
VIN - R1 +12 V
741 -
+ VM 741 VOUT
+
- 12 V R2
- 12 V
VM = - VIN V1 Rf
VOUT = VIN - Rf V1
R1 R2
No.9-13
The PIC18 Microcontroller
R0 Example 12.3 Choose appropriate resistor values R and the adjusting voltage so that the
f the range of –1.2V ~ 3.0V to
circuit shown in Figure 12.7c can shift the voltage from
the range of 0V ~ 5V.
+12 Solution:
V Applying Equation 12.5:
R1 +12 V
41 0 = -1.2 (Rf/R1) – (Rf/R2) V1 -
5 = 3.0V (Rf/R1) – (Rf/R2) V1 741
M VOUT
+ R2 = 50 KW, and Rf = 12KW
Choose R0 = R1 = 10 KW and V1 = -5V, solve
12 V R2
- 12 V
= - VIN V1 Rf
VIN - Rf V1
M
VOUT =
R0
Rf
R1 R2
R0 +12 V
VIN -R +12 V
ure 12T.7 Level
741 shifting and scaling
V
- circuit 1
+ M 741 VOUT
+
- 12 V R2
- 12 V
VM = - VIN V1 Rf
VOUT = VIN - Rf V1 (12-5)
R1 R2
No.9-15
The PIC18 Microcontroller
ADCON0 Register
7 6 5 4 3 2 1 0
ADCS1 ADCS0 CHS2 CHS1 CHS0 GO/DONE -- ADON
value after
reset 0 0 0 0 0 0 0 0
No.9-16
The PIC18 Microcontroller
No.9-17
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
-- -- CHS3 CHS2 CHS1 CHS0 GO/DONE ADON
value after
reset 0 0 0 0 0 0 0 0
No.9-18
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
VCFG1 VCFG0 -- CHS2 CHS1 CHS0 GO/DONE ADON
value after
reset 0 0 0 0 0 0 0 0
VCFG1:VCFG0: Voltage reference configuration bits
(See Table 12.2)
CHS2:CHS0: Analog channel select bits
000 = channel 0, (AN0)
001 = channel 1, (AN1) Table 12.2 Voltage reference configuration bits
010 = channel 2, (AN2)
011 = channel 3, (AN3) VCFG1:VCFG0 A/D VREF+ A/D VREF-
100 = channel 4, (AN4) 00 AVDD AVSS
101 = channel 5, (AN5) 01 External VREF+ AVSS
110 = channel 6, (AN6) 10 AVDD External VREF-
111 = channel 7, (AN7) 11 External VREF+ External VREF-
GO/DONE: A/D conversion status bit
when ADON = 1
0 = A/D conversion not in progress
1 = A/D conversion in progress (setting this bit starts the A/D conversion.
This bit will be cleared by hardware when A/D conversion is done)
ADON: A/D on bit
0 = A/D converter module is shut-off
1 = A/D converter module is powered up
No.9-19
The PIC18 Microcontroller
ADCON1 Register
- Configure an input pin as analog or digit.
- An input to be converted must be an analog input.
7 6 5 4 3 2 1 0
ADFM ADCS2 -- -- PCFG3 PCFG2 PCFG1 PCFG0
value after
reset 0 0 0 0 0 0 0 0
No.9-20
The PIC18 Microcontroller
No.9-21
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
-- -- VCFG1 VCFG0 PCFG3 PCFG2 PCFG1 PCFG0
value after
reset 0 0 0 0 0 0 0 0
0000 A A A A A A A A A A A A A A A A
0001 D D A A A A A A A A A A A A A A
0010 D D D A A A A A A A A A A A A A
0011 D D D D A A A A A A A A A A A A
0100 D D D D D A A A A A A A A A A A
0101 D D D D D D A A A A A A A A A A
0110 D D D D D D D A A A A A A A A A
0111 D D D D D D D D A A A A A A A A
1000 D D D D D D D D D A A A A A A A
1001 D D D D D D D D D D A A A A A A
1010 D D D D D D D D D D D A A A A A
1011 D D D D D D D D D D D D A A A A
1100 D D D D D D D D D D D D D A A A
1101 D D D D D D D D D D D D D D A A
1110 D D D D D D D D D D D D D D D A
1111 D D D D D D D D D D D D D D D D
No.9-22
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
-- PCFG6 PCFG5 PCFG4 PCFG3 PCFG2 PCFG1 PCFG0
value after
reset 0 0 0 0 0 0 0 0
PCFG6..PFCG0: AN6..AN0 A/D port configuration bit
0 = Pin configured as an analog channel -- digital input disabled and read as 0
1 = Pin configured as a digital input
Figure 12.9c ADCON1 register (PIC18F1220/1320)
(redraw with permission of Microchip)
No.9-23
The PIC18 Microcontroller
ADCON2 Register
7 6 5 4 3 2 1 0
ADFM -- ACQT2 ACQT1 ACQT0 ADCS2 ADCS1 ADCS0
value after
reset 0 0 0 0 0 0 0 0
ADFM: A/D result format select bit
0 = left justified
1 = right justified
ACQT2:ACQT0: A/D acquisition time select bits
000 = 0 TAD(1)
001 = 2 TAD
010 = 4 TAD
011 = 6 TAD
100 = 8 TAD
101 = 12 TAD
110 = 16 TAD
111 = 20 TAD
ADCS2:ADCS0: A/D conversion clock select bits
000 = FOSC/2
001 = FOSC/8
010 = FOSC/32
011 = FRC (clock derived from A/D RC oscillator)
100 = FOSC/4
101 = FOSC/16
110 = FOSC/64
111 = FRC (clock derived from A/D RC oscillator)
Note 1: If the A/D FRC clock source is selected, a delay of one TCY (instruction
cycle) is added before the A/D clock starts. This allows the SLEEP
instruction to be executed before starting a conversion.
No.9-24
The PIC18 Microcontroller
7 6 5 4 3 2 1 0
ADFM -- -- -- -- ADCS2 ADCS1 ADCS0
value after
reset 0 0 0 0 0 0 0 0
ADFM: A/D result format select bit
0 = left justified
1 = right justified
ADCS2:ADCS0: A/D conversion clock select bits
000 = FOSC/2
001 = FOSC/8
010 = FOSC/32
011 = FRC (clock derived from an RC oscillator = 1 MHz max)
100 = FOSC/4
101 = FOSC/16
110 = FOSC/64
111 = FRC (clock derived from an RC oscillator = 1 MHz)
No.9-25
The PIC18 Microcontroller
No.9-26
The PIC18 Microcontroller
- For earlier PIC18 members, when the GO/DONE bit is set, sampling is stopped and
conversion begins.
- The user is responsible for making sure enough acquisition time is provided.
- For newer PIC18 members, the A/D module will continue to sample after the
GO/DONE bit is set for the selected acquisition time.
- The automatic acquisition time makes A/D programming a little easier.
No.9-28
The PIC18 Microcontroller
Note. Lower power device has a letter L in its name. For example,
PIC18LF8720
- For PIC18 members without the feature of automatic acquisition, A/D conversion
will start immediately after setting the GO/DONE bit.
- For devices with automatic acquisition, the device will continue to perform data
acquisition until the preprogrammed time is up and then start the A/D conversion.
No.9-29
The PIC18 Microcontroller
Example 12.4 Write an instruction sequence to configure the A/D converter of the
PIC18F8680 to operate with the following parameters:
• Conversion result right justified
• fOSC = 32 MHz
• The highest ambient temperature may reach 60oC
• Use VDD and VSS as the high and low reference voltages
• Convert channel AN0
• Enable A/D module
Solution:
- TCOFF = (60 -25) 0.05 = 1.75 ms
- The required acquisition time = (9.61 + 2 + 1.75) = 13.36 ms.
- fOSC = 32 MHz, the A/D clock source must be set to 64 fOSC, which makes TAD =
2ms.
- PIC18F8680 supports automatic acquisition time, it must be set to at least 8 TAD to
make it greater than 13.36 ms
No.9-30
The PIC18 Microcontroller
In C language,
ADCON0 = 0x01;
ADCON1 = 0x0E;
ADCON2 = 0xA6;
No.9-31
The PIC18 Microcontroller
Example 12.5 Write an instruction sequence to configure the A/D converter of the
PIC18F452 to operate with the following parameters:
Solution:
movlw 0x81 ; select fOSC/64 as the conversion clock
movwf ADCON0,A ; ―
movlw 0xCE ; A/D conversion result right justified
movwf ADCON1,A ; configure only AN0 pin as analog,
No.9-32
The PIC18 Microcontroller
No.9-33
The PIC18 Microcontroller
Example 12.6 Assume that the AN0 pin of a PIC18F8680 running with a 32 MHz
crystal oscillator is connected to a potentiometer. The voltage range of the
potentiometer is from 0V to 5V. Write a program to measure the voltage applied to the
AN0 pin, convert it, and retrieved the conversion result and place it in
PRODH:PRODL.
Solution:
No.9-34
The PIC18 Microcontroller
#include <p18F8680.inc>
org 0x00
goto start
org 0x08
retfie
org 0x18
retfie
start movlw 0x01 ; select channel AN0 and enable A/D
movwf ADCON0,A ; "
movlw 0x0E ; use VDD & VSS as reference voltages &
movwf ADCON1,A ; configure channel AN0 as analog input
movlw 0xA6 ; select FOSC/64 as conversion clock,
movwf ADCON2,A ; 8 TAD for acquisition time, right-justified
bsf ADCON0,GO,A ; start A/D conversion
wait_con btfsc ADCON0,DONE,A ; wait until conversion is done
bra wait_con
movff ADRESH,PRODH ; save conversion result
movff ADRESL,PRODL ; "
end
No.9-35
The PIC18 Microcontroller
No.9-36
The PIC18 Microcontroller
No.9-37
The PIC18 Microcontroller
No.9-38
The PIC18 Microcontroller
No.9-39
The PIC18 Microcontroller
No.9-40
The PIC18 Microcontroller
No.9-41
The PIC18 Microcontroller
No.9-42
The PIC18 Microcontroller
No.9-43
The PIC18 Microcontroller
No.9-44
The PIC18 Microcontroller
ADC_CH11 Channel 11
ADC_CH12 Channel 12
ADC_CH13 Channel 13
ADC_CH14 Channel 14
ADC_CH15 Channel 15
A/D Interrupts
ADC_INT_ON Interrupts enabled
ADC_INT_OFF Interrupts disabled
A/D voltage configuration
ADC_VREFPLUS_VDD VREF+ = AVDD
ADC_VREFPLUS_EXT VREF+ = external
ADC_VREFMINUS_VSS VREF- = AVSS
ADC_VREFMINUS_EXT VREF- = external
- The third argument portconfig is any value from 0 to 127 for the
PIC18F1220/1320.
- The argument portconfig is any value from 0 to 15 for the PIC2220/2320/4220
and PIC18F4320/6X8X/8X8X.
No.9-45
The PIC18 Microcontroller
Example 12.7 Write a C program to configure the A/D module of the PIC18F452 with
the following characteristics and take one sample, convert it, and store the result in a
memory location:
• Clock source set to FOSC/64
• Result right justified
• Set AN0 pin of port A for analog input, others for digital
• Use VDD and VSS as high and low reference voltages
• Select AN0 to convert
• Disable interrupt
Solution:
No.9-46
The PIC18 Microcontroller
#include <p18F452.h>
#include <adc.h>
#include <stdlib.h>
#include <delays.h>
int result;
void main (void)
{
OpenADC(ADC_FOSC_64 & ADC_RIGHT_JUST & ADC_1ANA_0REF,
ADC_CH0 & ADC_INT_OFF);
Delay10TCYx(20); // provides 200 instruction cycles of acquisition time
ConvertADC( ); // start A/D conversion
while(BusyADC( )); // wait for completion
result = ReadADC( ); // read result
CloseADC( );
}
No.9-47
The PIC18 Microcontroller
VOUT
1.75
VSS
1.4
3
0.9
TC1047A
0.5
1 2
0.1
VDD VOUT
-40 0 40 90 125
Temperature
Figure 12.14 TC1047A V OUT vs. temperature characteristic
No.9-48
The PIC18 Microcontroller
Example 12.8 Describe a circuit connection and the required program to build a digital
thermometer. Display the temperature in three integral and one fractional digits using
the LCD. Measure and display the temperature over the whole range of TC1047A; that
is, -40oC to +125oC. Update the display data ten times per second and assume that the
PIC18F8680 operates with a 32 MHz crystal oscillator.
Solution:
- A signal conditioning circuit is needed to shift and scale the output of the TC1047A
to 0 ~ 5V.
- To convert the A/D conversion result back to the corresponding temperature,
perform the following operations:
No.9-49
The PIC18 Microcontroller
5V 9K
10K Rf PIC18F8680
TC1047A
10K +12 V
VOUT - +12 V
3K -
741
+ VM R1 741 AN0
+
- 12 V 150K R2
- 12 V
- 5V
Figure 12.15 Circuit connection between the TC1047A and the PIC18
The Procedure
Step 1
Configure A/D converter and Timer0 properly. Timer0 is configured to overflow every
200 ms.
Step 2
Start an A/D conversion.
Step 3
Wait until the A/D conversion is complete.
Step 4
Multiply the conversion result by 10.
No.9-50
The PIC18 Microcontroller
Step 5
Divide the product resulted in step 4 by 62 to obtain temperature reading. Use variables
quo and rem to hold the quotient and remainder.
Step 6
Subtract 40 from the variable quo to obtain the actual temperature.
Step 7
If (quo > 0), go to step 9; else replace quo with its two’s complement.
Step 8
If rem 0, then
decrement quo by 1
rem 62 – rem.
Step 9
Compute the fractional digit by multiplying rem by 10 and then dividing the resulted
product by 62.
Step 10
Compute the integral digits by performing repeated division by 10 to quo.
Step 11
Wait until Timer0 overflows and then go to Step 2.
No.9-51
The PIC18 Microcontroller
#include <p18F8680.inc>
; -----
; include macro definitions for pushr, push_dat, popr, alloc_stk, dealloc_stk here.
; -----
; ********************************************************************
; The following definitions are used by the 16-bit multiplication routine
; ********************************************************************
loc_varm equ 4 ; number of bytes used for local variable
pd0 equ 7 ; offset of PD3 from frame pointer
pd1 equ 6 ; offset of PD2 from frame pointer
pd2 equ 5 ; offset of PD1 from frame pointer
pd3 equ 4 ; offset of PD0 from frame pointer
MD_lo equ -8 ; offset of MD_lo from frame pointer
MD_hi equ -7 ; offset of MD_hi from frame pointer
ND_lo equ -6 ; offset of ND_lo from frame pointer
ND_hi equ -5 ; offset of ND_hi from frame pointer
buf_lo equ -4
buf_hi equ -3
ptr_hi equ 0x01 ; address of buffer to hold product
ptr_lo equ 0x00 ; "
No.9-52
The PIC18 Microcontroller
; ********************************************************************
; The following definitions are used by the 16-bit unsigned divide routine
; ********************************************************************
loc_var equ 2 ; local variable size
lp_cnt equ 1 ; loop count
temp equ 2 ; temporary storage
quo_hi equ -7 ; offset for quotient and dividend from frame
quo_lo equ -8 ; pointer
rem_hi equ -5 ; offset for remainder from frame pointer
rem_lo equ -6 ; "
dsr_hi equ -3 ; offset for divisor from frame pointer
dsr_lo equ -4 ; "
quo set 0x02 ; memory space to hold the quotient
rem set 0x04 ; memory space to hold the remainder
; ************************************************************************
; variables for holding temperature conversion result and string
; ************************************************************************
int_pt set 0x06 ; space to hold integer part of the temperature
temp_buf set 0x08 ; reserve 6 bytes to hold the temperature
; digits, sign, period, and NULL
No.9-53
The PIC18 Microcontroller
No.9-54
The PIC18 Microcontroller
No.9-55
The PIC18 Microcontroller
dealloc_stk 2
popr rem+1 ; retrieve remainder high byte (should be 0)
popr rem ; retrieve remainder low byte
popr int_pt+1 ; retrieve integer part of the (should be 0)
popr int_pt ; temperature
; subtract 40 from integer part to obtain the actual temperature
movlw 0x28 ; calculate the actual temperature
subwf int_pt,F,A ;"
bnn non_minus ; if non-minus, no need for further check
negf int_pt,A ; find the magnitude of temperature
movlw 0x2D
movlw temp_buf ; store the minus sign
movf rem,W,A ; check the fractional part before divide
bz separate_dd ; branch to separate integer digits if rem = 0
decf int_pt,F,A ; fractional digit 0, decrement integer part
movlw 0x3E ; need to find the complement of the fractional
subwf rem,F,A ; digit
negf rem,A ;"
; calculate the fractional digit
non_minus
movlw 0x0A
mulwf rem
No.9-56
The PIC18 Microcontroller
No.9-57
The PIC18 Microcontroller
No.9-58
The PIC18 Microcontroller
goto yes_ge
movlw 0x30
addwf quo,W,A
movwf temp_buf+1 ; save the ten's digit
goto next_time ; "
yes_ge movlw 0x31 ; save "1" as the hundred's digit
movwf temp_buf,A ; "
movlw 0x0A ; separate the ten's digit and place it
subwf quo,W,A ; in WREG
addlw 0x30 ; convert ten's digit to ASCII and
movwf temp_buf+1,A ; save ten's digit
next_time btfss INTCON,TMR0IF,A ; wait until 200 ms is over
goto next_time
; -----
; add instructions to update display here
; -----
goto forever ; prepare to perform next A/D conversion
No.9-59
The PIC18 Microcontroller
; *********************************************************************
; This routine will place 15535 in TMR0 so that it overflows in 50000 count.
; When prescaler is set to 32 with fOSC = 32MHz, it will overflow in 200 ms.
; *******************************************************************
OpenTmr0 movlw 0x3C ; place 15535 in TMR0
movwf TMR0H ; so that it overflows in
movlw 0xAF ; 200 ms
movwf TMR0L ; "
movlw 0x84 ; enable TMR0, select internal clock,
movwf T0CON ; set prescaler to 32
bcf INTCON,TMR0IF ; clear TMR0IF flag
return
; ************************************************************
; This routine initialize the A/D converter to select channel AN0 as
; analog input other pins for digital pin. Select VDD and VSS as A/D
; conversion reference voltages, result right justified, FOSC/64 as
; A/D clock source, 8 TAD for acquisition time.
; *************************************************************
a2d_init movlw 0x01 ; select channel AN0
movwf ADCON0 ; and enable A/D module
movlw 0x0E ; use VDD & VSS as A/D reference voltage
movwf ADCON1 ; & configure AN0 as analog input
No.9-60
The PIC18 Microcontroller
No.9-61
The PIC18 Microcontroller
#include <p18F8680.h>
#include <timers.h>
#include <adc.h>
unsigned char temp_buf[6];
void main (void)
{
int a2d_val;
unsigned int quo, rem;
char fd1, fdr;
ADCON0 = 0x01; //select channel AN0, enable A/D module
ADCON1 = 0x0E; //use VDD, VSS as reference and configure AN0 for analog
ADCON2 = 0xA6; //result right justified, 8TAD acquisition time, FOSC/64
OpenTimer0(TIMER_INT_OFF & T0_16BIT & T0_SOURCE_INT &
T0_PS_1_32); //start Timer0 and make it overflow in 200 ms
while (1) {
temp_buf[5] = '\0';
temp_buf[0] = 0x20; //set to space
temp_buf[1] = 0x20; //set to space
temp_buf[2] = 0x30; //set to digit 0
temp_buf[3] = 0x2E; //store the decimal point
temp_buf[4] = 0x30; //set to digit 0
ConvertADC( ); //start an A/D conversion
No.9-62
The PIC18 Microcontroller
No.9-63
The PIC18 Microcontroller
No.9-64
The PIC18 Microcontroller
IH-3605
GND VOUT VS
Figure 12.16 Honeywell IH-3605 humidity sensor
No.9-65
The PIC18 Microcontroller
No.9-66
The PIC18 Microcontroller
VS (= 5V)
R0
Rf
1KW R0 +12 V
VOUT - R1 +12 V
0.16mF 741 -
IH-3605 + 741 VOUT
GND +
- 12 V R2
- 12 V
V1
R0 = R1 = 10KW
R W PIC18F8680
Rf W
V1 = 5V AN0
No.9-67
The PIC18 Microcontroller
#include <p18F8680.h>
#include <timers.h>
#include <adc.h>
unsigned char hum_buf[6]; //buffer to hold relative humidity
void main (void)
{
unsigned short long a2d_val;
unsigned short long quo, rem, temp1;
char fd1, i;
ADCON0 = 0x01; //select channel AN0, enable A/D module
ADCON1 = 0x0E; //use VDD, VSS as reference and configure AN0 for analog
ADCON2 = 0xA6; //result right justified, acquisition time = 8 TAD, FOSC/64
OpenTimer0(TIMER_INT_OFF & T0_16BIT & T0_SOURCE_INT &
T0_PS_1_32); //start Timer0 and make it overflow in 200 ms
while (1) {
hum_buf[0] = 0x20; //set to space
hum_buf[1] = 0x20; //set to space
hum_buf[2] = 0x30; //set to digit 0
hum_buf[3] = 0x2E; //store the decimal point
hum_buf[4] = 0x30; //set to digit 0
hum_buf[5] = '\0'; //terminate with a NULL character
ConvertADC( ); //start an A/D conversion
while (BusyADC( )); //wait until A/D conversion is done
No.9-68
The PIC18 Microcontroller
No.9-69
The PIC18 Microcontroller
if (quo == 1)
hum_buf[0] = 0x31;
while(!INTCONbits.TMR0IF); //wait until Timer0 overflows
for (i = 0; i < 4; i++) { //wait for Timer0 to overflow four more times
INTCONbits.TMR0IF = 0; //clear the TMR0IF flag
while(!INTCONbits.TMR0IF); //wait for Timer0 to overflow
}
INTCONbits.TMR0IF = 0
}
}
No.9-70
The PIC18 Microcontroller
- Barometric pressure is the pressure existing at any point in the earth atmosphere.
- The barometric pressure can be measured as an absolute pressure or can be
referenced to some other value or scale.
- The meteorology and avionics industries measure the absolute pressure.
- The units used to represent the barometric pressure include in-Hg, kPa, mbar, and
psi.
- A comparison of barometric pressures in different units is shown in Table 12.6.
No.9-71
The PIC18 Microcontroller
1 2 3 4 5 6
No.9-72
The PIC18 Microcontroller
(1)
Table 12.7 ASCX30AN performance characteristics
Characteristic min typ max
Pressure range 0 psia -- 30 psia
Zero pressure offset 0.205 0.250 0.295
Full-scale span (2) 4.455 4.500 4.545
Output at FS pressure 4.660 4.750 4.840
Combined pressure non-linearity and -- ±0.1 ±0.5
pressure hysteresis (3)
Temperature effect on span (4) -- ±0.2 ±1.0
Temperature effect on offset (4) -- ±0.2 ±1.0
Response time (10% - 90%) (5) -- 0.1 --
Repeatability -- ±0.05 --
Note 1. Reference conditions: TA = 25 oC, supply voltage VS = 5 V
2. Full scale span is the algebraic difference between the output
voltage at full-scale pressure and the output at zero pressure.
Full-scale span is ratiometric to the supply voltage.
3. Pressure non-linearity is based on the best-fit straight line.
Pressure hysteresis is the maximum output difference at any
point within the operating pressure range for increasing and
decreasing pressure.
4. Maximum error band of the offset voltage or span over the
compensated temperature range, relative to the 25 oC reading.
5. Response time for 0 psi to full-scale pressure step response.
6. If maximum pressure is exceeded, even momentarily, the
package may leak or burst, or the pressure-sensing die may
burst.
No.9-73
The PIC18 Microcontroller
Example 12.10 Describe the circuit connection of the ASCX30AN, the voltage level
shifting and scaling circuit, and write a program to measure and display the barometric
pressure in units of mbar.
Solution:
- A shift and scale circuit is needed to convert the voltage to the range from 0 to 5V.
- The typical offset adjust is 0.25V and can be achieved by using a potentiometer.
5V
27K PIC18F8680
10K Rf
ASCX30AN
10K +12 V 1.6K
VOUT - R1 +12 V
5V 74 -
+1 VM 74 AN0
+1
offset adjust 3.9 R2
- 12 V
- 12 V
5V
Figure 12.19 Barometric pressure sensor output scaling and shifting circuit.
No.9-74
The PIC18 Microcontroller
- The barometric pressure (in mbar) can be derived by dividing the A/D conversion
result by 7.53 and then add 948 to the quotient.
#include <p18F8680.h>
#include <timers.h>
#include <adc.h>
unsigned char bp_buf[7];
void main (void)
{
unsigned short long a2d_val;
unsigned short long quo, rem, temp1;
char fd1, i;
No.9-75
The PIC18 Microcontroller
while (1) {
bp_buf[0] = 0x20; //set to space
bp_buf[1] = 0x20; //set to space
bp_buf[2] = 0x20; //set to space
bp_buf[3] = 0x30; //set to digit 0
bp_buf[4] = 0x2E; //store the decimal point
bp_buf[5] = 0x30; //set to digit 0
bp_buf[6] = '\0'; //terminate the string with a NULL character
ConvertADC( ); //start an A/D conversion
while(BusyADC()); //wait until A/D conversion is done
a2d_val = 100 * ReadADC();
quo = a2d_val/753; //convert to barometric pressure
rem = a2d_val%753; // "
quo += 948; //add the barometric pressure at A/D
//conversion result 0 to obtain the
//actual barometric pressure
No.9-76
The PIC18 Microcontroller
No.9-77