
- •Table of Contents
- •Preface
- •Additional Material
- •Basic Electronics
- •1.0 The Atom
- •1.1 Isotopes and Ions
- •1.2 Static Electricity
- •1.3 Electrical Charge
- •1.4 Electrical Circuits
- •1.5 Circuit Elements
- •1.6 Semiconductors
- •Number Systems
- •2.0 Counting
- •2.1 The Origins of the Decimal System
- •2.2 Types of Numbers
- •2.3 Radix Representations
- •2.4 Number System Conversions
- •Data Types and Data Storage
- •3.0 Electronic-Digital Machines
- •3.1 Character Representations
- •3.2 Storage and Encoding of Integers
- •3.3 Encoding of Fractional Numbers
- •3.4 Binary-Coded Decimals (BCD)
- •Digital Logic, Arithmetic, and Conversions
- •4.0 Microcontroller Logic and Arithmetic
- •4.1 Logical Instructions
- •4.2 Microcontroller Arithmetic
- •4.3 Bit Manipulations and Auxiliary Operations
- •4.4 Unsigned Binary Arithmetic
- •4.5 Signed Binary Arithmetic
- •4.6 Data Format Conversions
- •Circuits and Logic Gates
- •5.0 Digital Circuits
- •5.1 The Diode Revisited
- •5.2 The Transistor
- •5.3 Logic Gates
- •5.4 Transistor-Transistor Logic
- •5.5 Other TTL Logic Families
- •5.6 CMOS Logic Gates
- •Circuit Components
- •6.0 Power Supplies
- •6.1 Clocked Logic and Flip-flops
- •6.2 Clocks
- •6.3 Frequency Dividers and Counters
- •6.4 Multiplexers and Demultiplexers
- •6.5 Input Devices
- •The Microchip PIC
- •7.0 The PICMicro Microcontroller
- •7.1 PIC Architecture
- •Mid-range PIC Architecture
- •8.0 Processor Architecture and Design
- •8.1 The Mid-range Core Features
- •8.2 Mid-Range CPU and Instruction Set
- •8.3 EEPROM Data Storage
- •8.4 Data Memory Organization
- •8.5 Mid-range I/O and Peripheral Modules
- •PIC Programming: Tools and Techniques
- •9.0 Microchip’s MPLAB
- •9.1 Integrated Development Environment
- •9.2 Simulators and Debuggers
- •9.3 Programmers
- •9.4 Engineering PIC Software
- •9.5 Pseudo Instructions
- •Programming Essentials: Input and Output
- •10.0 16F84A Programming Template
- •10.1 Introducing the 16F84A
- •10.2 Simple Circuits and Programs
- •10.3 Programming the Seven-segment LED
- •10.4 A Demonstration Board
- •Interrupts
- •11.0 Interrupts on the 16F84
- •11.1 Interrupt Sources
- •11.2 Interrupt Handlers
- •11.3 Interrupt Programming
- •11.4 Sample Programs
- •Timers and Counters
- •12.0 The 16F84 Timer0 Module
- •12.1 Delays Using Timer0
- •12.2 Timer0 as a Counter
- •12.3 Timer0 Programming
- •12.4 The Watchdog Timer
- •12.5 Sample Programs
- •LCD Interfacing and Programming
- •13.0 LCD Features and Architecture
- •13.1 Interfacing with the HD44780
- •13.2 HD44780 Instruction Set
- •13.3 LCD Programming
- •13.4 Sample Programs
- •Communications
- •14.0 PIC Communications Overview
- •14.1 Serial Data Transmission
- •14.2 Parallel Data Transmission
- •14.4 PIC Protocol-based Serial Programming
- •14.5 Sample Programs
- •Data EEPROM Programming
- •15.0 PIC Internal EEPROM Memory
- •15.1 EEPROM Devices and Interfaces
- •15.2 Sample Programs
- •Analog to Digital and Realtime Clocks
- •16.0 A/D Converters
- •16.1 A/D Integrated Circuits
- •16.2 PIC On-Board A/D Hardware
- •16.3 Realtime Clocks
- •16.4 Sample Programs
- •Index
Interrupts |
229 |
Processing by the interrupt service routine is straightforward. The code first determines which line caused the interrupt and takes the corresponding action in each case. In either case, the handler waits until all pushbuttons have been released before returning from the interrupt. This serves to debounce the switches.
11.4 Sample Programs
The following programs demonstrate the programming discussed in this chapter.
11.4.1 The RB0Int Program
;File: RB0Int.ASM
;Date: April 22, 2006
;Author: Julio Sanchez
;Processor: 16F84A
;Description:
;Program to test interrupt on port RB0
;A pushbutton switch is connected to port RB0.
;The pushbutton toggles a LED on port-B, line 2
;Another LED on port-B, line 1, flashes on and off
;at 1/2 second intervals ;===========================
;switches
;===========================
; Switches used in __config directive:
; |
|
_CP_ON |
Code protection ON/OFF |
; * |
_CP_OFF |
|
|
; |
* |
_PWRTE_ON |
Power-up timer ON/OFF |
;_PWRTE_OFF
; |
_WDT_ON |
Watchdog timer ON/OFF |
|
|
; * _WDT_OFF |
|
|
|
|
; |
_LP_OSC |
Low power crystal |
occilator |
|
; * _XT_OSC |
External parallel |
resonator/crystal oscillator |
||
; |
_HS_OSC |
High speed crystal resonator (8 to |
10 MHz) |
|
; |
|
Resonator: Murate |
Erie CSA8.00MG = |
8 MHz |
; |
_RC_OSC |
Resistor/capacitor oscillator (simplest, 20% |
error)
;|
;|_____ * indicates setup values
;========================= ; setup and configuration ;=========================
processor 16f84A include <p16f84A.inc>
__config _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF ;=====================================================
230 |
|
Chapter 11 |
; |
variables in PIC RAM |
|
;===================================================== |
||
; Local variables |
|
|
cblock |
0x0d |
; Start of block |
J |
|
; counter J |
K |
|
; counter K |
count1 |
|
; Auxiliary counter |
count2 |
|
; ISR counter |
old_w |
|
; Context saving |
old_STATUS ; Idem |
||
endc |
|
|
;======================================================== |
||
; |
m a i n |
p r o g r a m |
;======================================================== |
||
org |
0 |
; start at address 0 |
goto |
main |
|
;
;============================= ; interrupt handler ;=============================
org 0x04 goto IntServ
;=============================
;main program ;============================= main:
;Set up interrupt on falling edge
;by clearing OPTION register bit 6
movlw |
b’10111111’ |
|
|
option |
|
|
|
movlw |
b’11111111’ |
; Set port a |
for input |
tris |
PORTA |
|
|
movlw |
b’00000001’ |
; Port-B bit |
0 is input |
tris |
PORTB |
; all others |
are output |
clrf |
PORTB |
; All port-B |
to 0 |
; Initially turn on LED |
|
|
|
bsf |
PORTB,0 |
; Set line 0 |
bit |
;============================ |
|
|
;setup interrupts ;============================
;Clear external interrupt flag (INTF = bit 1)
bcf |
INTCON,INTF |
; Clear flag |
;Enable global interrupts (GIE = bit 7)
;Enable RB0 interrupt (INTE = bit 4)
bsf |
INTCON,GIE |
; |
Enable |
global int (bit |
7) |
bsf |
INTCON,INTE |
; |
Enable |
RB0 int (bit 4) |
|
;============================
Interrupts |
231 |
;flash LED ;============================
;Program flashes LED wired to Port-B, line 2 lights:
movlw |
b’00000010’ |
; Mask with bit 1 set |
xorwf |
PORTB,f |
; Complement bit 1 |
call |
long_delay |
|
call |
long_delay |
|
call |
long_delay |
|
goto |
lights |
|
;=======================================================
;Interrupt Service Routine ;=======================================================
;Service routine receives control when there is
;action on pushbutton switch wired to Port-B, line 0 IntServ:
;First test if source is an RB0 interrupt
btfss |
INTCON,INTF |
; INTF flag is RB0 interrupt |
goto |
notRB0 |
; Go if not RB0 origin |
; Save context |
|
|
movwf |
old_w |
; Save w register |
swapf |
STATUS,w ; STATUS to w |
|
movwf |
old_STATUS |
; Save STATUS |
;Make sure that interrupt occurred on the falling edge
;of the signal. If not, abort handler
btfsc |
PORTB,0 |
; |
Is |
bit set? |
goto |
exitISR |
; |
Go |
if clear |
;=========================
;interrupt action ;=========================
;Debounce switch
;Logic:
;Debounce algorithm consists in waiting until the
;same level is repeated on a number of samplings of the
;switch. At this point the RB0 line is clear since the
;interrupt takes place on the falling edge. An initial
;short delay makes sure that spikes are ignored.
movlw |
D’10’ |
; |
Number of repetitions |
movwf |
count2 |
; |
To counter |
wait:
;Check to see that port-B bit 0 is still 0
;If not, wait until it changes
btfsc |
PORTB,0 |
; Is bit set? |
|
goto |
exitISR |
; |
Go if bit not 0 |
; At this point RB0 bit is clear |
|
|
|
decfsz |
count2,f ; Count this iteration |
||
goto |
wait |
; |
Continue if not zero |
; Interrupt action consists of toggling bit 2 of
232
; port-B to turn LED on and off movlw b’00000100’
xorwf PORTB,f ;=========================
;exit ISR ;========================= exitISR:
;Restore context
swapf old_STATUS,w movfw STATUS
swapf old_w,f swapf old_w,w
; Reset,interrupt notRB0:
Chapter 11
;Xoring with a 1-bit produces
;the complement
;Complement bit 2, port-B
;Saved STATUS to w
;To STATUS register
;Swap file register in itself
;re-swap back to w
bcf INTCON,INTF ; Clear INTCON bit 1
retfie ;=======================
;Procedure to delay
;10 machine cycles ;======================= delay:
movlw |
D’4’ |
; Repeat 12 machine cycles |
movwf |
count1 |
; Store value in counter |
repeat |
|
|
decfsz |
count1,f |
; Decrement counter |
goto |
repeat |
; Continue if not 0 |
return |
|
|
;=============================
;long delay sub-routine
;(for debugging) ;============================= long_delay
|
movlw |
D’200’ ; w = 200 decimal |
|
|
movwf |
J |
; J = w |
jloop: |
movwf |
K |
; K = w |
kloop: |
decfsz |
K,f |
; K = K-1, skip next if zero |
|
goto |
kloop |
|
|
decfsz |
J,f |
; J = J-1, skip next if zero |
|
goto |
jloop |
|
|
return |
|
|
|
end |
|
|
11.4.2 The SleepDemo Program
;File: SleepDemo
;Date: April 25, 2006
Interrupts |
233 |
; Author: Julio Sanchez
;Processor: 16F84A
;Description:
;Program to use the External Interrupt on port RB0
;to terminate the power-down state caused by the
;SLEEP instruction. A pushbutton switch is connected to
;port RB0. The pushbutton generates the interrupt that
;ends the SLEEP conditions.
;Demonstration:
;A LED on port-B, line 1, flashes on and off at 1/2
;second intervals for 20 iterations. At that time the
;program enters the SLEEP condition. Pressing the
;pushbutton switch on line RB0 generates the interrupt
;that ends the SLEEP.
;===========================
;switches ;===========================
;Switches used in __config directive:
; |
|
_CP_ON |
Code protection ON/OFF |
; * |
_CP_OFF |
|
|
; |
* |
_PWRTE_ON |
Power-up timer ON/OFF |
;_PWRTE_OFF
; |
_WDT_ON |
Watchdog timer ON/OFF |
|
|
; * _WDT_OFF |
|
|
|
|
; |
_LP_OSC |
Low power crystal |
occilator |
|
; * _XT_OSC |
External parallel |
resonator/crystal oscillator |
||
; |
_HS_OSC |
High speed crystal resonator (8 to |
10 MHz) |
|
; |
|
Resonator: Murate |
Erie CSA8.00MG = |
8 MHz |
; |
_RC_OSC |
Resistor/capacitor oscillator (simplest, 20% |
error)
;|
;|_____ * indicates setup values
;========================= |
|
||
; setup and configuration |
|
||
;========================= |
|
||
|
processor 16f84A |
|
|
|
include |
<p16f84A.inc> |
|
|
__config |
_XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF |
|
;===================================================== |
|||
; |
variables in PIC RAM |
||
;===================================================== |
|||
; Local variables |
|
|
|
|
cblock |
0x0d |
; Start of block |
|
J |
|
; counter J |
234 |
|
Chapter 11 |
K |
|
; counter K |
count1 |
|
; Auxiliary counter |
count2 |
|
; Second auxiliary counter |
old_w |
|
; Context saving |
old_STATUS ; Idem |
||
endc |
|
|
;======================================================== |
||
; |
m a i n |
p r o g r a m |
;======================================================== |
||
org |
0 |
; start at address 0 |
goto |
main |
|
;
;============================= ; interrupt handler ;=============================
org 0x04 goto IntServ
;=============================
;main program ;============================= main:
;Set up interrupt on falling edge
;by clearing OPTION register bit 6 movlw b’10111111’
option
movlw |
b’11111111’ |
; Set port a |
for input |
||
tris |
PORTA |
|
|
|
|
movlw |
b’00000001’ |
; Port-B bit |
0 is input |
||
tris |
PORTB |
; |
all |
others |
are output |
clrf |
PORTB |
; |
All |
port-B |
to 0 |
;============================
;setup interrupts ;============================
;Clear external interrupt flag (INTF = bit 1)
bcf |
INTCON,INTF |
; Clear flag |
;Enable global interrupts (GIE = bit 7)
;Enable RB0 interrupt (INTE = bit 4)
bsf |
INTCON,GIE |
; |
Enable |
global int (bit |
7) |
bsf |
INTCON,INTE |
; |
Enable |
RB0 int (bit 4) |
|
;============================
;flash LED 20 times ;============================ wakeUp:
;Program flashes LED wired to port-B, line 2
;20 times before entering the sleep state
movlw |
D’20’ |
; |
Number of iterations |
movwf |
count2 |
; |
To counter |
Interrupts |
|
235 |
lights: |
|
|
movlw |
b’00000010’ |
; Mask with bit 1 set |
xorwf |
PORTB,f |
; Complement bit 1 |
call |
long_delay |
|
call |
long_delay |
|
call |
long_delay |
|
decfsz |
count2,f ; Decrement counter |
|
goto |
lights |
|
; 20 iterations have taken place |
|
|
sleep |
|
|
nop |
|
; Recommended! |
goto |
wakeUp |
; Resume execution |
;=======================================================
;Interrupt Service Routine ;=======================================================
;The interrupt service routine performs no operation IntServ:
|
bcf |
INTCON,INTF |
; Clear flag |
|
retfie |
|
|
;============================= |
|
||
; |
long delay sub-routine |
|
|
;============================= |
|
||
long_delay |
|
|
|
|
movlw |
D’200’ ; w = 200 decimal |
|
|
movwf |
J |
; J = w |
jloop: |
|
|
|
|
movwf |
K |
; K = w |
kloop: |
|
|
|
|
decfsz |
K,f |
; K = K-1, skip next if zero |
|
goto |
kloop |
|
|
decfsz |
J,f |
; J = J-1, skip next if zero |
|
goto |
jloop |
|
|
return |
|
|
end
11.4.3 The RB4to7Int Program
;File: RB4to7Int.ASM
;Date: April 26, 2006
;Author: Julio Sanchez
;Processor: 16F84A
;Description:
;Program to test the port-B, bits 4 to 7, STATUS
236 |
Chapter 11 |
;change interrupt. Pushbutton switches are connected
;to port-B lines 4 and 7. A red LED is wired to port
;RA1 and a green LED to port RA0. The pushbuttons
;generate interrupts that toggle a LEDs on and off. ;===========================
;switches
;===========================
; Switches used in __config directive:
; |
|
_CP_ON |
Code protection ON/OFF |
; * |
_CP_OFF |
|
|
; |
* |
_PWRTE_ON |
Power-up timer ON/OFF |
;_PWRTE_OFF
; |
_WDT_ON |
Watchdog timer ON/OFF |
|
|
; * _WDT_OFF |
|
|
|
|
; |
_LP_OSC |
Low power crystal |
occilator |
|
; * _XT_OSC |
External parallel |
resonator/crystal oscillator |
||
; |
_HS_OSC |
High speed crystal resonator (8 to |
10 MHz) |
|
; |
|
Resonator: Murate |
Erie CSA8.00MG = |
8 MHz |
; |
_RC_OSC |
Resistor/capacitor oscillator (simplest, 20% |
error)
;|
;|_____ * indicates setup values
;========================= ; set up and configuration ;=========================
|
processor 16f84A |
|
|
|
include |
<p16f84A.inc> |
|
|
__config |
_XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF |
|
;===================================================== |
|||
; |
variables in PIC RAM |
||
;===================================================== |
|||
; Local variables |
|
|
|
|
cblock |
0x0d |
; Start of block |
|
J |
|
; counter J |
|
K |
|
; counter K |
|
count1 |
|
; Auxiliary counter |
|
count2 |
|
; ISR counter |
|
old_w |
|
; Context saving |
|
old_STATUS ; Idem |
||
|
bitsB47 |
|
; Storage for previous value |
|
|
|
; in port-B bits 4-7 |
|
temp |
|
; Temporary storage |
|
endc |
|
|
;========================================================
; m a i n p r o g r a m
Interrupts |
|
237 |
;======================================================== |
||
org |
0 |
; start at address 0 |
goto |
main |
|
; |
|
|
;=============================
; interrupt handler
;=============================
org |
0x04 |
goto IntServ
;=============================
;main program ;============================= main:
;Disable port-B internal pullups
;Interrupts on falling edge of pushbutton action movlw b’10111111’
option
;Wiring:
; |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
<= port-B |
; |
| |
|
|
|_______________ red pushbutton |
|||||
; |
|________________________ black pushbutton |
||||||||
; |
|
|
|
|
|
|
|
|
|
; |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
<= Port-A |
; |
|
|
|
|
|
|
| |
|_____ red LED |
|
; |
|
|
|
|
|
|
|________ green LED |
||
; |
|
|
|
|
|
|
|
|
|
|
movlw |
|
b’00000000’ |
|
; Set Port-A for ouput |
||||
|
tris |
|
PORTA |
|
|
|
|
||
|
movlw |
|
b’11110000’ |
|
; Port-B bit 0-3 are output |
||||
|
|
|
|
|
|
|
|
|
; bits 4-7 are input |
|
tris |
|
PORTB |
|
|
|
; all others are output |
||
|
clrf |
|
PORTB |
|
|
|
; All Port-B to 0 |
||
|
movlw |
|
b’00000000’ |
|
; Zero to w |
||||
|
movwf |
|
bitsB47 |
|
|
; Store in local variable |
|||
; Initially turn on LEDs |
|
|
|
||||||
|
bsf |
|
PORTA,0 |
|
|
; Set LEDs on line 0 |
|||
|
bsf |
|
PORTA,1 |
|
|
; and on line 1 |
;============================
;set up interrupts ;============================
;Clear external interrupt flag (intf = bit 1)
bcf |
INTCON,RBIF |
; Clear flag |
;Enable global interrupts (GIE = bit 7)
;Enable RB0 interrupt (inte = bit 4)
|
bsf |
INTCON,GIE |
; |
Enable |
global int (bit |
7) |
|
bsf |
INTCON,RBIE |
; |
Enable |
RB0 int (bit 3) |
|
;============================ |
|
|
|
|
||
; |
flash LED |
|
|
|
|
238 |
Chapter 11 |
;============================
;Main program does nothing. All action takes place in
;Interrupt Service Routine
lights:
nop
goto lights
;=======================================================
; |
Interrupt Service Routine |
;=======================================================
;Service routine receives control whenever any of
;port-B lines 4 to 7 change state
IntServ:
; First test: make sure source is an RB4-7 interrupt
btfss |
INTCON,RBIF |
; RBIF flag is interrupt |
goto |
notRBIF |
; Go if not RBIF origin |
; Save context |
|
|
movwf |
old_w |
; Save w register |
swapf |
STATUS,w ; STATUS to w |
|
movwf |
old_STATUS |
; Save STATUS |
;=========================
;interrupt action ;=========================
;The interrupt occurs when any of Port-B bits 4 to 7
;have changed STATUS.
movf |
PORTB,w |
; Read Port-B bits |
|
movwf |
temp |
; Save reading |
|
xorwf |
bitsB47,f |
; |
Xor with old bits, |
|
|
; |
result in f |
; Test each meaningful bit (4 and 7 in this example)
btfsc |
bitsB47,4 |
; Test bit 4 |
goto |
bit4Chng ; Routine for changed bit 4 |
|
; At this point bit 4 did not change |
||
btfsc |
bitsB47,7 |
; Test bit 7 |
goto |
bit7Chng ; Routine for changed bit 7 |
|
; Invalid port line change. Exit |
|
|
goto |
pbRelease |
|
;======================== |
|
;bit 4 change routine ;========================
;Check for signal falling edge, ignore if not bit4Chng:
btfsc |
PORTB,4 |
; Is bit |
4 high |
goto |
pbRelease |
; Bit is |
high. Ignore |
; Toggling bit 1 of Port-A turns LED on and off |
|||
movlw |
b’00000010’ |
; Xoring |
with a 1-bit produces |
|
|
; the complement |
|
xorwf |
PORTA,f |
; Complement bit 1, Port-A |
|
goto |
pbRelease |
|
|
Interrupts |
239 |
;========================
;bit 7 change routine ;========================
;Check for signal falling edge, ignore if not bit7Chng:
btfsc |
PORTB,7 |
; Is bit 7 high |
goto |
exitISR |
; Bit is high. Ignore |
; Toggling bit 0 of Port-A turns LED on and off |
||
movlw |
b’00000001’ |
; Xoring with a 1-bit produces |
|
|
; the complement |
xorwf |
PORTA,f |
; Complement bit 1, Port-A |
; |
|
|
pbRelease: |
|
|
call |
delay |
; Debounce switch |
movf |
PORTB,w |
; Read port-B into w |
andlw |
b’10010000’ ; Eliminate unused bits |
|
btfsc |
STATUS,Z ; Check for zero |
|
goto |
pbRelease |
; Wait |
;At this point all port-B pushbuttons are released ;=========================
;exit ISR
;========================= |
|
|
exitISR: |
|
|
; Store new value of port-B |
|
|
movf |
temp,w |
; This port-B value to w |
movwf |
bitsB47 |
; Store |
; Restore context |
|
|
swapf |
old_STATUS,w |
; Saved STATUS to w |
movfw |
STATUS |
; To STATUS register |
swapf |
old_w,f |
; Swap file register in itself |
swapf |
old_w,w |
; re-swap back to w |
; Reset,interrupt |
|
|
notRBIF: |
|
|
bcf |
INTCON,RBIF |
; Clear INTCON bit 0 |
retfie |
|
|
;=======================
;Procedure to delay
;10 machine cycles ;======================= delay:
movlw |
D’6’ |
; Repeat 18 machine cycles |
movwf |
count1 |
; Store value in counter |
repeat: |
|
|
decfsz |
count1,f |
; Decrement counter |
goto |
repeat |
; Continue if not 0 |
return |
|
|
;=============================
240 |
Chapter 11 |
;long delay sub-routine
;(for debugging) ;============================= long_delay
movlw |
D’200’ |
; w = 200 decimal |
movwf |
J |
; J = w |
jloop: |
|
|
movwf |
K |
; K = w |
kloop: |
|
|
decfsz |
K,f |
; K = K-1, skip next if zero |
goto |
kloop |
|
decfsz |
J,f |
; J = J-1, skip next if zero |
goto |
jloop |
|
return |
|
|
end |
|
|