AN557, Four-Channel Digital Voltmeter with Display and Keyboard

AN557
Four-Channel Digital Voltmeter with Display and Keyboard
Author:
MULTIPLEXING FOUR 7-SEGMENT
LED DISPLAYS
Stan D’Souza
Microchip Technology Inc.
Hardware
INTRODUCTION
The PIC16C71 device’s I/O ports have an improved
sink/source specification. Each I/O pin can sink up to
25 mA and source 20 mA. In addition, total PORTB
source current is 100 mA and sink current is 150 mA.
PORTA is rated for a 50 mA source current and 80 mA
sink current. This makes the PIC16C71 ideal for driving
7-segment LEDs. Since the total number of I/O pins is
limited to 13, the 8-bit PORTB is used to drive the
4 LEDs, while external sink transistors, or MOSFETs,
are used to sink the digit current (Figure 1). Another
alternative is to use ULN2003 open-collector sink
current drivers, which are available in 16-pin DIP or
very small 16-pin SOIC packages. Each transistor on
the ULN2003 can sink a maximum of 500 mA and the
base drive can be directly driven from the PORTA pins.
The PIC16C71 is a member of the mid-range family of
8-bit, high-speed microcontrollers, namely, the
PIC16CXXX. The salient features of the PIC16C71 are:
•
•
•
•
Improved and enhanced instruction set
14-bit instruction word
Interrupt capability
On-chip, four-channel, 8-bit A/D Converter
This application note demonstrates the capability of the
PIC16C71 and has been broken down into four
subsections:
• Multiplexing Four 7-Segment LED Displays
• Multiplexing Four 7-Segment LED Displays and
Scanning a 4x4 Keypad
• Multiplexing Four 7-Segment LED Displays and
the A/D Channel 0
• Multiplexing Four 7-Segment LED Displays with a
4x4 Keypad and 4 A/D Channels
FIGURE 1:
MULTIPLEXING FOUR 7-SEGMENT LEDS
LED Module
8 x 220W
NPN
4.7k
NPN
4.7k
NPN
4.7k
17
18
1
2
RA0
RA1
RA2
RA3
RB0
RB1
RB2
RB3
RB4
RB5
RB6
RB7
6
7
8
9
10
11
12
13
NPN
4.7k
PIC16C71
© 2005 Microchip Technology Inc.
DS00557D-page 1
AN557
MULTIPLEXING FOUR 7-SEGMENT
LED DISPLAYS AND SCANNING A
4x4 KEYPAD
Software
The multiplexing is achieved by turning on each LED for
a 5 ms duration every 20 ms. This gives an update rate
of 50 Hz, which is quite acceptable to the human eye as
a steady display. The 5 ms time base is generated by
dividing the 4.096 MHz oscillator clock. The internal
prescaler is configured to be a divide by 32 and assigned
to Timer0. TMR0 is preloaded with a value = 96. TMR0
will increment to FFh and then roll over to 00h after a
period = (256 – 96) • (32 • 4/4096000) = 5 ms.
Hardware
A 4x4 keypad can very easily be interfaced to the
PIC16C71 device’s PORTB (Figure 2). Internal pull-ups
on pins RB7:RB4 can be enabled/disabled by clearing/
setting bit RBPU (OPTION<7>). The internal pull-ups
have a value of 20k at 5V (typical). In order to sense a
low level at the input, the switch is “connected” to ground
through a 2.2 kΩ resistor. A key hit normally lasts anywhere from 50 ms to as long as a person holds the key
down. In order not to miss any key hits, the keypad is
sampled every 20 ms (just after the update of the MSD).
When TMR0 rolls over, the T0IF flag bit is set, and
because bits T0IE and GIE are enabled, an interrupt is
generated.
The software implements a simple timer which increments at a 1-second rate. Every second, the 4 nibbles
(two 8-bit registers, MsdTime and LsdTime) are
incremented in a BCD format. The lower 4 bits of
LsdTime correspond to the Least Significant Digit
(LSD) on the display. The high 4 bits of LsdTime correspond to the second significant digit of the display and
so on. Depending on which display is turned on, the
corresponding 4-bit BCD value is extracted from either
MsdTime or LsdTime and decoded to a 7-segment
display. The TMR0 interrupt is generated at a steady
rate of 5 ms and given an instruction time of 1 μs. The
entire display update program can reside in the
Interrupt Service Routine with no chance of getting an
interrupt within an interrupt. The code listing for this
section is in Appendix A: “MPLX.ASM”.
FIGURE 2:
Software
To sample the keypad, the digit sinks are first disabled.
PORTB is then configured with RB7:RB4 as inputs and
RB3:RB0 as outputs driven high. The pull-ups on
RB7:RB4 are enabled. Sequentially, RB3:RB0 are
made low, while RB7:RB4 are checked for a key hit (a
low level). One key hit per scan is demonstrated in this
program. Multiple key hits per scan can very easily be
implemented. Once the key hit is sensed, a 40 ms
debounce period elapses before key sampling is
resumed. No more key hits are sensed until the present
key is released. This prevents erroneous key inputs.
The program basically inputs the key hit and displays
its value as a hexadecimal character on the multiplexed
7-segment LEDs. The code listing for this section is in
Appendix B: “MPLXKEY.ASM”.
MULTIPLEXING FOUR 7-SEGMENT LEDS WITH A 4X4 KEYPAD
LED Module
9
10
11
12
4 x 220W
NPN
4.7k
NPN
4.7k
NPN
4.7k
17
18
1
2
RA0
RA1
RA2
RA3
RB0
RB1
RB2
RB3
RB4
RB5
RB6
RB7
6
7
8
9
10
11
12
13
4 x 220W
NPN
4.7k
2.2k
PIC16C71
DS00557D-page 2
2.2k
2.2k
2.2k
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
© 2005 Microchip Technology Inc.
AN557
MULTIPLEXING FOUR 7-SEGMENT
LED DISPLAYS AND THE A/D
CHANNEL 0
FIGURE 3:
TYPICAL CONNECTION FOR
ANALOG/DIGITAL INPUT
Digital I/O
Hardware
The four analog channels are connected to RA3:RA0. If
any of these pins are used normally as digital I/O, they
can momentarily be used as analog inputs. In order to
avoid interference from the analog source, it is advisable
to buffer the analog input through a voltage follower
op amp; however, it is not always necessary. Figure 3
and Figure 4 show some typical configurations. In this
application, the analog input is a potentiometer whose
wiper is connected through an RC network to Channel 0.
The RC is necessary in order to smooth out the analog
voltage. The RC does contribute to a delay in the
sampling time; however, the stability of the analog
reading is greatly improved.
1k
RA0
Analog
Input
PIC16C71
FIGURE 4:
TYPICAL CONNECTION FOR
ANALOG/DIGITAL INPUT
Digital I/O
Software
The analog input is sampled every 20 ms. The digit
sinks and the drivers are turned off (i.e., PORTA is
configured as an input and PORTB outputs are made
low). A 1 ms settling time is allowed for the external RC
network connected to the analog input to settle and
then the A/D conversion is started. The result is read,
then converted, from an 8-bit binary value to a 3-digit
Binary Code Decimal (BCD) value, which is then
displayed on the 7-segment LEDs. The code listing for
this section is in Appendix C: “MPLXCH0.ASM”.
© 2005 Microchip Technology Inc.
Analog
Input
1k
RA0
10 nF
PIC16C71
DS00557D-page 3
AN557
MULTIPLEXING FOUR 7-SEGMENT
LED DISPLAYS WITH A 4x4 KEYPAD
AND 4 A/D CHANNELS
Code Size
Four 7-Segment LEDs
Hardware
This section essentially incorporates the previous three
sections to give a complete four-channel voltmeter.
Figure 5 shows a typical configuration. The analog
channels are connected through individual potentiometers to their respective analog inputs and are
sampled every 20 ms in a round robin fashion. The
sampling rate can be increased to as fast as once
every 5 ms if required. The keypad sampling need not
be any faster than once every 20 ms.
Program Memory:
139
Data Memory:
6
Four 7-Segment LEDs
Program Memory:
and 4x4 Keypad Sampling Data Memory:
207
Four 7-Segment LEDs
and A/D
Program Memory:
207
Data Memory:
11
Four 7-Segment LEDs,
4x4 Keypad Sampling
and A/D
Program Memory:
207
Data Memory:
13
13
Software
CONCLUSION
The program samples the analog inputs and saves the
result in four consecutive locations, starting at
“ADVALUE”, with Channel 0 saved at the first location
and so on:
KEY 0 → Channel 0
or
KEY 1 → Channel 0
The four A/D channels on the PIC16C71 can be
multiplexed with digital I/O, thus reducing overall pin
counts and improving I/O pin usage in an analog
application.
Key hits greater than 3 are ignored. The code listing for
this section is in Appendix D: “MPLXAD.ASM”D.
FIGURE 5:
FOUR-CHANNEL VOLTMETER WITH DISPLAY AND KEYPAD
LED Module
9
10
11
12
4 x 220W
17
18
1
2
NPN
4.7k
NPN
RA0
RA1
RA2
RA3
4.7k
NPN
4.7k
RB0
RB1
RB2
RB3
RB4
RB5
RB6
RB7
6
7
8
9
10
11
12
13
4 x 220W
NPN
4.7k
2.2k
2.2k
2.2k
2.2k
PIC16C71
10 nF
10 nF
10 nF
10 nF
4x1k
+5V
500
DS00557D-page 4
+5V +5V
500
+5V
500
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
500
© 2005 Microchip Technology Inc.
AN557
Software License Agreement
The software supplied herewith by Microchip Technology Incorporated (the “Company”) is intended and supplied to you, the
Company’s customer, for use solely and exclusively with products manufactured by the Company.
The software is owned by the Company and/or its supplier, and is protected under applicable copyright laws. All rights are reserved.
Any use in violation of the foregoing restrictions may subject the user to criminal sanctions under applicable laws, as well as to civil
liability for the breach of the terms and conditions of this license.
THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR
SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
APPENDIX A:
MPLX.ASM
MPASM 01.40 Released
LOC OBJECT CODE
VALUE
0000000C
0000000D
0000000E
0000000F
00000010
00000011
00000001
00000002
00000026
00000027
0000
0000 2805
0004
0004 281D
0005
0005 2008
0006 2012
0007
0007 2807
0008
MPLX.ASM
1-16-1997
16:20:47
PAGE
1
LINE SOURCE TEXT
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00001
00002
00142
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
© 2005 Microchip Technology Inc.
;*********************************************************************
;This program demonstrates how to multiplex four 7 segment LED
;digits using a PIC16C71. The four digits will start at 0000 and
;increment at a 1 sec rate up to 9999.
;The LEDs are updated every 5 mS, for a multiplexing rate of 20 mS.
;The TMR0 timer is used in internal interrupt mode to generate the
;5 mS.
;
;
Stan D'Souza 5/8/93
;
;
Program:
MPLX.ASM
;
Revision Date:
;
1-15-97
Compatibility with MPASMWIN 1.40
;
;**********************************************************************
LIST P=16C71
ERRORLEVEL -302
;
include
<p16c71.inc>
LIST
; P16C71.INC Standard Header File, Version 1.00 Microchip Technology
LIST
;
TempC
equ
0x0c
;temp general purpose regs
TempD
equ
0x0d
TempE
equ
0x0e
Count
equ
0x0f
;count
MsdTime
equ
0x10
;most significant Timer
LsdTime
equ
0x11
;Least significant Timer
OptionReg equ
1
PCL
equ
2
BcdMsd
equ
26
Bcd
equ
27
;
org
0
goto
Start
;skip over interrupt vector
;
org
4
goto
ServiceInterrupts
;
Start
call
InitPorts
call
InitTimers
loop
goto
loop
;
InitPorts
DS00557D-page 5
AN557
0008
0009
000A
000B
000C
000D
000E
000F
0010
0011
1683
3003
0088
0185
0186
1283
0185
0186
1585
0008
0012
0012
0013
0014
0015
0016
0017
0018
0019
001A
001B
001C
0190
0191
1683
3084
0081
1283
3020
008B
3060
0081
0009
001D
001D
001E
001F
0020
0021
190B
2822
3020
008B
0009
0022
0022
0023
0024
0025
0026
0027
3060
0081
110B
2028
2050
0009
0028
0028
0029
002A
002B
002C
002D
002E
002E
002F
0030
0031
0032
0033
0034
0035
0A0F
3AC8
1903
282E
0A8F
0008
018F
0A11
390F
3A0A
1903
2836
0A91
0008
DS00557D-page 6
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
bsf
movlw
movwf
clrf
clrf
bcf
clrf
clrf
bsf
return
STATUS, RP0
3
ADCON1
TRISA
TRISB
STATUS, RP0
PORTA
PORTB
PORTA, 3
;select Bank1
;make RA0-3 digital I/O
;
/
;make RA0-4 outputs
;make RB0-7 outputs
;select Bank0
;make all outputs low
;
/
;enable MSB digit sink
;
;
;The clock speed is 4.096Mhz. Dividing internal clk. by a 32 prescaler,
;the TMR0 will be incremented every 31.25uS. If TMR0 is preloaded
;with 96, it will take (256-96)*31.25uS to overflow i.e. 5mS. So the
;end result is that we get a TMR0 interrupt every 5mS.
InitTimers
clrf
MsdTime
;clr timers
clrf
LsdTime
;
/
bsf
STATUS, RP0
;select Bank1
movlw
B'10000100'
;assign ps to TMR0
movwf
OptionReg
;ps = 32
bcf
STATUS, RP0
;select Bank0
movlw
B'00100000'
;enable TMR0 interrupt
movwf
INTCON
;
movlw
.96
;preload TMR0
movwf
TMR0
;start counter
retfie
;
ServiceInterrupts
btfsc
INTCON, T0IF
;TMR0 interrupt?
goto
ServiceTMR0
;yes then service
movlw
B'00100000'
;else clr rest
movwf
INTCON
retfie
;
ServiceTMR0
movlw
.96
;initialize TMR0
movwf
TMR0
bcf
INTCON, T0IF
;clr int flag
call
IncTimer
;inc timer
call
UpdateDisplay
;update display
retfie
;
;The display is incremented every 200*5mS = 1 Sec.
IncTimer
incf
Count, W
;inc count
xorlw
.200
;= 200?
btfsc
STATUS, Z
;no then skip
goto
DoIncTime
;else inc time
incf
Count, F
return
DoIncTime
clrf
Count
;clr count
incf
LsdTime, W
;get lsd
andlw
0x0F
;mask high nibble
xorlw
0x0a
; = 10?
btfsc
STATUS, Z
;no then skip
goto
IncSecondLsd
;inc next lsd
incf
LsdTime, F
;else inc timer
return
© 2005 Microchip Technology Inc.
AN557
0036
0036
0037
0038
0039
003A
003B
003C
003D
003E
003F
003F
0040
0041
0042
0043
0044
0045
0046
0047
0047
0048
0049
004A
004B
004C
004D
004E
004F
0050
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
005A
005B
005C
005D
005E
005E
005F
0060
0061
0061
0062
0063
0064
0065
0066
0066
0067
0068
0069
006A
0E11
390F
3E01
0091
0E91
3A0A
1903
283F
0008
0191
0A10
390F
3A0A
1903
2847
0A90
0008
0E10
390F
3E01
0090
0E90
3A0A
1903
0190
0008
0805
0185
390F
008C
160C
0C8C
1C03
118C
180C
286B
188C
2866
190C
2861
0811
390F
286F
2080
1D03
0E11
390F
286F
2088
1D03
0810
390F
286F
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
© 2005 Microchip Technology Inc.
IncSecondLsd
swapf
andlw
addlw
movwf
swapf
xorlw
btfsc
goto
return
IncThirdLsd
clrf
incf
andlw
xorlw
btfsc
goto
incf
return
IncMsd
swapf
andlw
addlw
movwf
swapf
xorlw
btfsc
clrf
return
;
;
UpdateDisplay
movf
clrf
andlw
movwf
bsf
rrf
btfss
bcf
btfsc
goto
btfsc
goto
btfsc
goto
UpdateLsd
movf
andlw
goto
Update2ndLsd
call
btfss
swapf
andlw
goto
Update3rdLsd
call
btfss
movf
andlw
goto
LsdTime, W
0x0F
1
LsdTime
LsdTime, F
0x0a
STATUS, Z
IncThirdLsd
;get hi in low nibble
;mask hi nibble
;inc it
;restore back
;
/
; = 10?
;no then skip
;else inc next lsd
LsdTime
MsdTime, W
0x0F
0x0a
STATUS, Z
IncMsd
MsdTime, F
;get 3rd lsd
;mask hi nibble
;= 10?
;no then skip
;else Msd
;else inc timer
MsdTime, W
0x0F
1
MsdTime
MsdTime, F
0x0a
STATUS, Z
MsdTime
;get hi in lo nibble
;mask hi nibble
;inc timer
;restore back
;
/
;= 10?
;no then skip
;clr msd
PORTA, W
PORTA
0x0f
TempC
TempC, 4
TempC, F
STATUS, C
TempC, 3
TempC, 0
UpdateMsd
TempC, 1
Update3rdLsd
TempC, 2
Update2ndLsd
;present sink value in w
;disable all digits sinks
LsdTime, W
0x0f
DisplayOut
;get Lsd in w
;
/
;enable display
Chk2LsdZero
STATUS, Z
LsdTime, W
0x0f
DisplayOut
;msd = 0 & 2 lsd 0?
;yes then skip
;get 2nd Lsd in w
;mask rest
;enable display
ChkMsdZero
STATUS, Z
MsdTime, W
0x0f
DisplayOut
;msd = 0?
;yes then skip
;get 3rd Lsd in w
;mask low nibble
;enable display
;save sink value in tempC
;preset for lsd sink
;determine next sink value
;c=1?
;no then reset LSD sink
;else see if Msd
;yes then do Msd
;see if 3rdLsd
;yes then do 3rd Lsd
;see if 2nd Lsd
;yes then do 2nd lsd
DS00557D-page 7
AN557
006B
006B
006C
006D
006E
006F
006F
0070
0071
0072
0073
0E10
390F
1903
300A
2074
0086
080C
0085
0008
0074
0074
0075
0076
0077
0078
0079
007A
007B
007C
007D
007E
007F
0782
343F
3406
345B
344F
3466
346D
347D
3407
347F
3467
3400
0080
0080
0081
0082
0083
0084
0085
0086
0087
2088
1D03
0008
0E11
390F
1D03
0008
340A
0088
0088
0089
008A
008B
0810
1D03
0008
340A
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
UpdateMsd
swapf
andlw
btfsc
movlw
DisplayOut
call
movwf
movf
movwf
return
;
;
LedTable
addwf
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
;
;
Chk2LsdZero
call
btfss
return
swapf
andlw
btfss
return
retlw
;
ChkMsdZero
movf
btfss
return
retlw
;
MsdTime, W
0x0f
STATUS, Z
0x0a
;get Msd in w
;mask rest
;msd != 0 then skip
LedTable
PORTB
TempC, W
PORTA
;get digit output
;drive leds
;get sink value in w
PCL, F
B'00111111'
B'00000110'
B'01011011'
B'01001111'
B'01100110'
B'01101101'
B'01111101'
B'00000111'
B'01111111'
B'01100111'
B'00000000'
;add to PC
;led drive
;led drive
;led drive
;led drive
;led drive
;led drive
;led drive
;led drive
;led drive
;led drive
;blank led
ChkMsdZero
STATUS, Z
LsdTime, W
0x0f
STATUS, Z
;msd = 0?
;yes then skip
;else return
;get 2nd lsd
;mask of LSD
;0? then skip
.10
;else return with 10
MsdTime, W
STATUS, Z
;get Msd in w
;= 0? skip
;else return
;ret with 10
.10
low
for 0
for 1
for 2
for 3
for 4
for 5
for 6
for 7
for 8
for 9
drive
end
MEMORY USAGE MAP ('X' = Used,
'-' = Unused)
0000 : X---XXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
0040 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
0080 : XXXXXXXXXXXX---- ---------------- ---------------- ---------------All other memory blocks unused.
Program Memory
Program Memory
Errors
:
Warnings :
Messages :
DS00557D-page 8
Words Used:
Words Free:
0
0 reported,
0 reported,
137
887
0 suppressed
3 suppressed
© 2005 Microchip Technology Inc.
AN557
APPENDIX B:
MPLXKEY.ASM
MPASM 01.40 Released
LOC OBJECT CODE
VALUE
0000000C
0000000D
0000000E
00000020
00000021
0000000F
00000010
00000011
00000012
00000000
00000001
00000002
00000003
00000013
00000014
0000002F
0000002E
00000001
00000002
MPLXKEY.ASM
1-16-1997
16:24:40
PAGE
1
LINE SOURCE TEXT
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00001
00002
00142
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
© 2005 Microchip Technology Inc.
;*********************************************************************
;This program is to demonstrate how to multiplex four 7 segment LED
;digits and a 4x4 keypad using a PIC16C71.
;The four digits will start as '0000' and when a key is hit
;it is displayed on the 7 segment leds as a hex value 0 to F. The last
;digit hit is always displayed on the right most led with the rest of
;the digits shifted to the left. The left most digit is deleted.
;The LEDs are updated every 20mS, the keypad is scanned at a rate of 20
;mS. The TMR0 timer is used in internal interrupt mode to generate the
;5 mS.
;
;
Stan D'Souza 5/8/93
;
;
Program:
MPLXKEY.ASM
;
Revision Date:
;
1-15-97
Compatibility with MPASMWIN 1.40
;
;**********************************************************************
LIST P=16C71
ERRORLEVEL -302
;
include
<p16c71.inc>
LIST
; P16C71.INC Standard Header File,Ver. 1.00 Microchip Technology, Inc.
LIST
;
TempC
equ
0x0c
;temp general purpose regs
TempD
equ
0x0d
TempE
equ
0x0e
PABuf
equ
0x20
PBBuf
equ
0x21
Count
equ
0x0f
;count
MsdTime
equ
0x10
;most significant Timer
LsdTime
equ
0x11
;Least significant Timer
KeyFlag
equ
0x12
;flags related to key pad
keyhit
equ
0
;bit 0 --> key-press on
DebnceOn
equ
1
;bit 1 --> debounce on
noentry
equ
2
;no key entry = 0
ServKey
equ
3
;bit 3 --> service key
Debnce
equ
0x13
;debounce counter
NewKey
equ
0x14
WBuffer
equ
0x2f
StatBuffer equ
0x2e
OptionReg equ
1
PCL
equ
2
;
;
push
macro
movwf
WBuffer
;save w reg in Buffer
swapf
WBuffer, F
;swap it
swapf
STATUS, W
;get status
movwf
StatBuffer
;save it
endm
;
pop
macro
swapf
StatBuffer, W
;restore status
movwf
STATUS
;
/
DS00557D-page 9
AN557
0000
0000 280D
0004
0004
0005
0006
0007
0008
00AF
0EAF
0E03
00AE
2036
0009
000A
000B
000C
0E2E
0083
0E2F
0009
000D
000D
000E
000F
000F
0010
0011
0012
0012
0013
0014
0015
0016
0017
0018
0019
001A
001B
001C
001D
001E
001F
0020
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
2020
202A
1992
2012
280F
0814
008E
0E10
39F0
0090
0E11
390F
0490
0E11
39F0
040E
0091
1192
0008
1683
3003
0088
0185
0186
1283
0185
0186
1585
0008
002A
DS00557D-page 10
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
M
M
M
M
00065
00066
M
M
M
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
swapf
endm
WBuffer, W
;restore W reg
org
goto
0
Start
;skip over interrupt vector
;
;
org
4
;It is always a good practice to save and restore the w reg,
;and the status reg during an interrupt.
push
movwf
WBuffer
;save w reg in Buffer
swapf
WBuffer, F
;swap it
swapf
STATUS, W
;get status
movwf
StatBuffer
;save it
call
ServiceInterrupts
pop
swapf
StatBuffer, W
;restore status
movwf
STATUS
;
/
swapf
WBuffer, W
;restore W reg
retfie
;
Start
call
InitPorts
call
InitTimers
loop
btfsc
KeyFlag, ServKey ;key service pending
call
ServiceKey
;yes then service
goto
loop
;
;ServiceKey, does the software service for a keyhit. After a key
;service, the ServKey flag is reset, to denote a completed operation.
ServiceKey
movf
NewKey, W
;get key value
movwf
TempE
;save in TempE
swapf
MsdTime, W
;move MSD out
andlw
B'11110000'
;clr lo nibble
movwf
MsdTime
;save back
swapf
LsdTime, W
;get Lsd
andlw
B'00001111'
;mask off lsd
iorwf
MsdTime, F
;and left shift 3rd
swapf
LsdTime, W
;get Lsd again
andlw
B'11110000'
;mask off 2nd
iorwf
TempE, W
;or with new lsd
movwf
LsdTime
;make Lsd
bcf
KeyFlag, ServKey ;reset service flag
return
;
InitPorts
bsf
movlw
movwf
clrf
clrf
bcf
clrf
clrf
bsf
return
STATUS, RP0
3
ADCON1
TRISA
TRISB
STATUS, RP0
PORTA
PORTB
PORTA, 3
;select Bank1
;make RA0-3 digital I/O
;
/
;make RA0-4 outputs
;make RB0-7 outputs
;select Bank0
;make all outputs low
;
/
;enable MSB digit sink
;
;
;The clock speed is 4.096Mhz. Dividing internal clk. by a 32 prescaler,
;the TMR0 will be incremented every 31.25uS. If TMR0 is preloaded
;with 96, it will take (256-96)*31.25uS to overflow i.e. 5mS. So the
;end result is that we get a TMR0 interrupt every 5mS.
InitTimers
© 2005 Microchip Technology Inc.
AN557
002A
002B
002C
002D
002E
002F
0030
0031
0032
0033
0034
0035
0190
0191
0192
1683
3084
0081
1283
3020
008B
3060
0081
0009
0036
0036
0037
0038
0039
003A
190B
283B
018B
168B
0008
003B
003B
003C
003D
003E
003F
0040
0041
3060
0081
110B
1805
2042
20A1
0008
0042
0042
0043
0044
0045
0046
0047
0048
0048
0049
004A
004B
004B
004C
004D
004E
004F
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
005A
005B
005C
005D
005E
1C92
2848
0B93
0008
1092
0008
208A
30EF
008D
0806
100B
0C8D
1C03
2862
080D
0086
0000
1C0B
284B
1812
2860
1412
0E06
008E
2064
0094
1592
1492
3004
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
© 2005 Microchip Technology Inc.
clrf
clrf
clrf
bsf
movlw
movwf
bcf
movlw
movwf
movlw
movwf
retfie
MsdTime
LsdTime
KeyFlag
STATUS, RP0
B'10000100'
OptionReg
STATUS, RP0
B'00100000'
INTCON
.96
TMR0
;clr timers
;
/
;clr all flags
;select Bank1
;assign ps to TMR0
;ps = 32
;select Bank0
;enable TMR0 interrupt
;
;preload TMR0
;start counter
;
ServiceInterrupts
btfsc
INTCON, T0IF
;TMR0 interrupt?
goto
ServiceTMR0
;yes then service
clrf
INTCON
;else clr all int
bsf
INTCON, T0IE
return
;
ServiceTMR0
movlw
.96
;initialize TMR0
movwf
TMR0
bcf
INTCON, T0IF
;clr int flag
btfsc
PORTA, 0
;if msb on then do
call
ScanKeys
;do a quick key scan
call
UpdateDisplay
;update display
return
;
;
;ScanKeys, scans the 4X4 keypad matrix and returns a key value in
;NewKey (0 - F) if a key is pressed, if not it clears the keyhit flag.
;Debounce for a given keyhit is also taken care of.
;The rate of key scan is 20mS with a 4.096Mhz clock.
ScanKeys
btfss
KeyFlag, DebnceOn ;debounce on?
goto
Scan1
;no then scan keypad
decfsz Debnce, F
;else dec debounce time
return
;not over then return
bcf
KeyFlag, DebnceOn ;over, clr debounce flag
return
;and return
Scan1
call
SavePorts
;save port values
movlw
B'11101111'
;init TempD
movwf
TempD
ScanNext
movf
PORTB, W
;read to init port
bcf
INTCON, RBIF
;clr flag
rrf
TempD, F
;get correct column
btfss
STATUS, C
;if carry set?
goto
NoKey
;no then end
movf
TempD, W
;else output
movwf
PORTB
;low column scan line
nop
btfss
INTCON, RBIF
;flag set?
goto
ScanNext
;no then next
btfsc
KeyFlag, keyhit
;last key released?
goto
SKreturn
;no then exit
bsf
KeyFlag, keyhit
;set new key hit
swapf
PORTB, W
;read port
movwf
TempE
;save in TempE
call
GetKeyValue
;get key value 0 - F
movwf
NewKey
;save as New key
bsf
KeyFlag, ServKey
;set service flag
bsf
KeyFlag, DebnceOn ;set flag
movlw
4
DS00557D-page 11
AN557
005F 0093
0060
0060 2097
0061 0008
0062
0062 1012
0063 2860
0064
0064
0065
0066
0067
0068
0069
006A
006B
006C
006D
006E
006E
006F
0070
0071
0072
0073
0074
0074
0075
0075
0076
0077
0077
0078
0078
0079
007A
007B
007C
007D
007E
007F
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
018C
1D8D
286E
0A8C
1D0D
286E
0A8C
1C8D
286E
0A8C
1C0E
2878
1C8E
2877
1D0E
2875
150C
158C
2878
150C
080C
0782
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
340A
340B
340C
340D
340E
340F
DS00557D-page 12
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
movwf
Debnce
;load debounce time
call
return
RestorePorts
;restore ports
bcf
goto
KeyFlag, keyhit
SKreturn
;clr flag
SKreturn
;
NoKey
;
;GetKeyValue gets the key as per the following layout
;
;
Col1
Col2
Col3
Col4
;
(RB3)
(RB2)
(RB1)
(RB0)
;
;Row1(RB4)
0
1
2
3
;
;Row2(RB5)
4
5
6
7
;
;Row3(RB6)
8
9
A
B
;
;Row4(RB7)
C
D
E
F
;
GetKeyValue
clrf
TempC
btfss
TempD, 3
;first column
goto
RowValEnd
incf
TempC, F
btfss
TempD, 2
;second col.
goto
RowValEnd
incf
TempC, F
btfss
TempD, 1
;3rd col.
goto
RowValEnd
incf
TempC, F
;last col.
RowValEnd
btfss
TempE, 0
;top row?
goto
GetValCom
;yes then get 0,1,2&3
btfss
TempE, 1
;2nd row?
goto
Get4567
;yes the get 4,5,6&7
btfss
TempE, 2
;3rd row?
goto
Get89ab
;yes then get 8,9,a&b
Getcdef
bsf
TempC, 2
;set msb bits
Get89ab
bsf
TempC, 3
;
/
goto
GetValCom
;do common part
Get4567
bsf
TempC, 2
GetValCom
movf
TempC, W
addwf
PCL, F
retlw
0
retlw
1
retlw
2
retlw
3
retlw
4
retlw
5
retlw
6
retlw
7
retlw
8
retlw
9
retlw
0a
retlw
0b
retlw
0c
retlw
0d
retlw
0e
retlw
0f
© 2005 Microchip Technology Inc.
AN557
008A
008A
008B
008C
008D
008E
008F
0090
0091
0092
0093
0094
0095
0096
0097
0097
0098
0099
009A
009B
009C
009D
009E
009F
00A0
00A1
00A1
00A2
00A3
00A4
00A5
00A6
00A7
00A8
00A9
00AA
00AB
00AC
00AD
00AE
00AF
00AF
00B0
00B1
00B2
00B2
00B3
00B4
00B5
00B5
00B6
00B7
00B8
00B8
00B9
0805
00A0
0185
0806
00A1
30FF
0086
1683
1381
30F0
0086
1283
0008
0821
0086
0820
0085
1683
1781
0185
0186
1283
0008
0805
0185
390F
008C
160C
0C8C
1C03
118C
180C
28B8
188C
28B5
190C
28B2
0811
390F
28BA
0E11
390F
28BA
0810
390F
28BA
0E10
390F
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
© 2005 Microchip Technology Inc.
;
;SavePorts, saves the porta and portb
;operation.
SavePorts
movf
PORTA, W
movwf
PABuf
clrf
PORTA
movf
PORTB, W
movwf
PBBuf
movlw
0xff
movwf
PORTB
bsf
STATUS, RP0
bcf
OptionReg, 7
movlw
B'11110000'
movwf
TRISB
bcf
STATUS, RP0
return
;
;RestorePorts, restores the condition
;key scan operation.
RestorePorts
movf
PBBuf, W
movwf
PORTB
movf
PABuf, W
movwf
PORTA
bsf
STATUS, RP0
bsf
OptionReg, 7
clrf
TRISA
clrf
TRISB
bcf
STATUS, RP0
return
;
;
UpdateDisplay
movf
PORTA, W
clrf
PORTA
andlw
0x0f
movwf
TempC
bsf
TempC, 4
rrf
TempC, F
btfss
STATUS, C
bcf
TempC, 3
btfsc
TempC, 0
goto
UpdateMsd
btfsc
TempC, 1
goto
Update3rdLsd
btfsc
TempC, 2
goto
Update2ndLsd
UpdateLsd
movf
LsdTime, W
andlw
0x0f
goto
DisplayOut
Update2ndLsd
swapf
LsdTime, W
andlw
0x0f
goto
DisplayOut
Update3rdLsd
movf
MsdTime, W
andlw
0x0f
goto
DisplayOut
UpdateMsd
swapf
MsdTime, W
andlw
0x0f
condition during a key scan
;Get sink value
;save in buffer
;disable all sinks
;get port b
;save in buffer
;make all high
;on port b
;select Bank1
;enable pull ups
;port b hi nibble inputs
;lo nibble outputs
;Bank0
of porta and portb after a
;get port b
;get port a value
;select Bank1
;disable pull ups
;make port a outputs
;as well as PORTB
;Bank0
;present sink value in w
;disable all digits sinks
;save sink value in tempC
;preset for lsd sink
;determine next sink value
;c=1?
;no then reset LSD sink
;else see if Msd
;yes then do Msd
;see if 3rdLsd
;yes then do 3rd Lsd
;see if 2nd Lsd
;yes then do 2nd lsd
;get Lsd in w
;
/
;get 2nd Lsd in w
;mask rest
;enable display
;get 3rd Lsd in w
;mask low nibble
;enable display
;get Msd in w
;mask rest
DS00557D-page 13
AN557
00BA
00BA
00BB
00BC
00BD
00BE
00BF
00BF
00C0
00C1
00C2
00C3
00C4
00C5
00C6
00C7
00C8
00C9
00CA
00CB
00CC
00CD
00CE
00CF
20BF
0086
080C
0085
0008
0782
343F
3406
345B
344F
3466
346D
347D
3407
347F
3467
3477
347C
3439
345E
3479
3471
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
DisplayOut
:
:
:
:
X---XXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
LedTable
PORTB
TempC, W
PORTA
addwf
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
PCL, F
B'00111111'
B'00000110'
B'01011011'
B'01001111'
B'01100110'
B'01101101'
B'01111101'
B'00000111'
B'01111111'
B'01100111'
B'01110111'
B'01111100'
B'00111001'
B'01011110'
B'01111001'
B'01110001'
;get digit output
;drive leds
;get sink value in w
;
;
LedTable
;add
;led
;led
;led
;led
;led
;led
;led
;led
;led
;led
;led
;led
;led
;led
;led
;led
to PC
drive
drive
drive
drive
drive
drive
drive
drive
drive
drive
drive
drive
drive
drive
drive
drive
low
for
for
for
for
for
for
for
for
for
for
for
for
for
for
for
for
0
1
2
3
4
5
6
7
8
9
A
b
C
d
E
F
;
;
end
MEMORY USAGE MAP ('X' = Used,
0000
0040
0080
00C0
call
movwf
movf
movwf
return
'-' = Unused)
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
----------------
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
----------------
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
----------------
All other memory blocks unused.
Program Memory Words Used:
Program Memory Words Free:
Errors
:
Warnings :
Messages :
DS00557D-page 14
0
0 reported,
0 reported,
205
819
0 suppressed
6 suppressed
© 2005 Microchip Technology Inc.
AN557
APPENDIX C:
MPLXCH0.ASM
MPASM 01.40 Released
LOC OBJECT CODE
VALUE
00000026
00000027
0000000C
0000000D
0000000E
00000020
00000021
0000000F
00000010
00000011
00000012
00000005
0000002F
0000002E
00000001
00000002
0000
0000 280D
MPLXCH0.ASM
1-16-1997
16:24:14
PAGE
1
LINE SOURCE TEXT
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00001
00002
00142
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
© 2005 Microchip Technology Inc.
;*********************************************************************
;This program is to demonstrate how to multiplex four 7 segment LED
;and sample ch0 of the a/d in a PIC16C71. The a/d value is displayed
;as a 3 digit decimal value of the a/d input (0 - 255).
;The LEDs are updated every 20mS, the a/d is sampled every 20 mS.
;The TIMER0 timer is used in internal interrupt mode to generate the
;5 mS.
;
;
Stan D'Souza 5/8/93
;
;
;
;
Program:
MPLXCH0.ASM
;
Revision Date:
;
1-15-97
Compatibility with MPASMWIN 1.40
;
;**********************************************************************
LIST P=16C71
ERRORLEVEL -302
;
include
<p16c71.inc>
LIST
; P16C71.INC Standard Header File, Ver. 1.00 Microchip Technology, Inc.
LIST
;
BcdMsd
equ
26
Bcd
equ
27
TempC
equ
0x0c
;temp general purpose regs
TempD
equ
0x0d
TempE
equ
0x0e
PABuf
equ
0x20
PBBuf
equ
0x21
Count
equ
0x0f
;count
MsdTime
equ
0x10
;most significant Timer
LsdTime
equ
0x11
;Least significant Timer
ADFlag
equ
0x12
;flags related to key pad
ADOver
equ
5
;bit 5 --> a/d over
WBuffer
equ
0x2f
StatBuffer equ
0x2e
OptionReg equ
1
PCL
equ
2
;
push
macro
movwf
WBuffer
;save w reg in Buffer
swapf
WBuffer, F
;swap it
swapf
STATUS, W
;get status
movwf
StatBuffer
;save it
endm
;
pop
macro
swapf
StatBuffer, W
;restore status
movwf
STATUS
;
/
swapf
WBuffer, W
;restore W reg
endm
;
org
0
goto
Start
;skip over interrupt vector
DS00557D-page 15
AN557
0004
0004
0005
0006
0007
0008
00AF
0EAF
0E03
00AE
2039
0009
000A
000B
000C
0E2E
0083
0E2F
0009
000D
000D
000E
000F
0010
0010
0011
0012
2021
202B
2036
1A92
2013
2810
0013
0013
0014
0015
0016
0017
0018
0019
001A
001B
001C
001D
001E
001F
0020
1C88
0008
0809
00A1
01A0
20AD
0824
0091
0823
0090
1088
1008
1292
0008
0021
0021
0022
0023
0024
0025
0026
0027
0028
0029
002A
1683
3003
0088
0185
0186
1283
0185
0186
1585
0008
002B
002B
002C
002D
002E
002F
0190
0191
1683
3084
0081
DS00557D-page 16
00055
00056
00057
00058
00059
M
M
M
M
00060
00061
M
M
M
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
;
org
4
;It is always a good practice to save and restore the w reg,
;and the status reg during an interrupt.
push
movwf
WBuffer
;save w reg in Buffer
swapf
WBuffer, F
;swap it
swapf
STATUS, W
;get status
movwf
StatBuffer
;save it
call
ServiceInterrupts
pop
swapf
StatBuffer, W
;restore status
movwf
STATUS
;
/
swapf
WBuffer, W
;restore W reg
retfie
;
Start
call
InitPorts
call
InitTimers
call
InitAd
loop
btfsc
ADFlag, ADOver
;a/d over?
call
UpdateAd
;yes then update
goto
loop
;
UpdateAd
btfss
ADCON0, ADIF
;a/d done?
return
;no then leave
movf
ADRES, W
;get a/d value
movwf
L_byte
clrf
H_byte
call
B2_BCD
movf
R2, W
;get LSd
movwf
LsdTime
;save in LSD
movf
R1, W
;get Msd
movwf
MsdTime
;save in Msd
bcf
ADCON0, ADIF
;clr interrupt flag
bcf
ADCON0, ADON
;turn off a/d
bcf
ADFlag, ADOver
;clr flag
return
;
;
;
InitPorts
bsf
STATUS, RP0
;select Bank1
movlw
3
;make RA0-3 digital I/O
movwf
ADCON1
;
/
clrf
TRISA
;make RA0-4 outputs
clrf
TRISB
;make RB0-7 outputs
bcf
STATUS, RP0
;select Bank0
clrf
PORTA
;make all outputs low
clrf
PORTB
;
/
bsf
PORTA, 3
;enable MSB digit sink
return
;
;
;The clock speed is 4.096Mhz. Dividing internal clk. by a 32 prescaler,
;the TMR0 will be incremented every 31.25uS. If TMR0 is preloaded
;with 96, it will take (256-96)*31.25uS to overflow i.e. 5mS. So the
;end result is that we get a TMR0 interrupt every 5mS.
InitTimers
clrf
MsdTime
;clr timers
clrf
LsdTime
;
/
bsf
STATUS, RP0
;select Bank1
movlw
B'10000100'
;assign ps to TMR0
movwf
OptionReg
;ps = 32
© 2005 Microchip Technology Inc.
AN557
0030
0031
0032
0033
0034
0035
1283
3020
008B
3060
0081
0009
0036
0036 30C0
0037 0088
0038 0008
0039
0039
003A
003B
003C
003D
190B
283E
018B
168B
0008
003E
003E
003F
0040
0041
0042
0043
0044
3060
0081
110B
1C05
2045
2071
0008
0045
0045
0046
0047
0047
0048
0049
004A
004B
004C
004C
004D
004E
004F
0050
0051
0052
0053
0054
0055
0056
0056
0057
0057
0058
0059
005A
205A
204C
1908
2847
1692
2067
0008
0186
1683
300F
0085
1283
1408
307D
2056
1508
0008
008C
0B8C
2857
0008
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
© 2005 Microchip Technology Inc.
bcf
movlw
movwf
movlw
movwf
retfie
STATUS, R P0
B'00100000'
INTCON
.96
TMR0
;select Bank0
;enable TMR0 interrupt
;
;preload TMR0
;start counter
movlw
movwf
return
B'11000000'
ADCON0
;rc osc, ch 0 for a/d
;
;
InitAd
;
;
ServiceInterrupts
btfsc
goto
clrf
bsf
return
;
ServiceTMR0
movlw
movwf
bcf
btfss
call
call
return
;
;
SampleAd
call
call
AdDone
btfsc
goto
bsf
call
return
;
;
DoAd
clrf
bsf
movlw
movwf
bcf
bsf
movlw
call
bsf
return
;
;
Wait
movwf
Next
decfsz
goto
return
INTCON, T0IF
ServiceTMR0
INTCON
INTCON, T0IE
;TMR0 interrupt?
;yes then service
.96
TMR0
INTCON, T0IF
PORTA, 0
SampleAd
UpdateDisplay
;initialize TMR0
;clr int flag
;last digit?
;then sample a/d
;else update display
SavePorts
DoAd
;do a ad conversion
ADCON0, GO
AdDone
ADFlag, ADOver
RestorePorts
;ad done?
;no then loop
;set a/d over flag
;restore ports
PORTB
STATUS,
0x0f
TRISA
STATUS,
ADCON0,
.125
Wait
ADCON0,
RP0
ADON
;turn off leds
;select Bank1
;make port a hi-Z
;
/
;select Bank0
;start a/d
GO
;start conversion
TempC
RP0
;store in temp
TempC, F
Next
;
;SavePorts, saves the porta and portb condition during a key scan
;operation.
SavePorts
DS00557D-page 17
AN557
005A
005B
005C
005D
005E
005F
0060
0061
0062
0063
0064
0065
0066
0067
0067
0068
0069
006A
006B
006C
006D
006E
006F
0070
0071
0071
0072
0073
0074
0075
0076
0077
0078
0079
007A
007B
007C
007D
007E
007F
007F
0080
0081
0082
0082
0083
0084
0085
0086
0087
0087
0088
0089
008A
008B
008C
008C
008D
008E
008F
0805
00A0
0185
0806
00A1
30FF
0086
1683
1381
30F0
0086
1283
0008
0821
0086
0820
0085
1683
1781
0185
0186
1283
0008
0805
0185
390F
008C
160C
0C8C
1C03
118C
180C
288C
188C
2887
190C
2882
0811
390F
2890
20A1
1D03
0E11
390F
2890
20A9
1D03
0810
390F
2890
0E10
390F
1903
300A
DS00557D-page 18
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
movf
movwf
clrf
movf
movwf
movlw
movwf
bsf
bcf
movlw
movwf
bcf
return
PORTA, W
PABuf
PORTA
PORTB, W
PBBuf
0xff
PORTB
STATUS, RP0
OptionReg, 7
B'11110000'
TRISB
STATUS, RP0
;Get sink value
;save in buffer
;disable all sinks
;get port b
;save in buffer
;make all high
;on port b
;select Bank1
;enable pull ups
;port b hi nibble inputs
;lo nibble outputs
;Bank0
;
;RestorePorts, restores the condition of porta and portb after a
;key scan operation.
RestorePorts
movf
PBBuf, W
;get port n
movwf
PORTB
movf
PABuf, W
;get port a value
movwf
PORTA
bsf
STATUS, RP0
;select Bank1
bsf
OptionReg, 7
;disable pull ups
clrf
TRISA
;make port a outputs
clrf
TRISB
;as well as PORTB
bcf
STATUS, RP0
;Bank0
return
;
;
UpdateDisplay
movf
PORTA, W
;present sink value in w
clrf
PORTA
;disable all digits sinks
andlw
0x0f
movwf
TempC
;save sink value in tempC
bsf
TempC, 4
;preset for lsd sink
rrf
TempC, F
;determine next sink value
btfss
STATUS, C
;c=1?
bcf
TempC, 3
;no then reset LSD sink
btfsc
TempC, 0
;else see if Msd
goto
UpdateMsd
;yes then do Msd
btfsc
TempC, 1
;see if 3rdLsd
goto
Update3rdLsd
;yes then do 3rd Lsd
btfsc
TempC, 2
;see if 2nd Lsd
goto
Update2ndLsd
;yes then do 2nd lsd
UpdateLsd
movf
LsdTime, W
;get Lsd in w
andlw
0x0f
;
/
goto
DisplayOut
;enable display
Update2ndLsd
call
Chk2LsdZero
;msd = 0 & 2 lsd 0?
btfss
STATUS, Z
;yes then skip
swapf
LsdTime, W
;get 2nd Lsd in w
andlw
0x0f
;mask rest
goto
DisplayOut
;enable display
Update3rdLsd
call
ChkMsdZero
;msd = 0?
btfss
STATUS, Z
;yes then skip
movf
MsdTime, W
;get 3rd Lsd in w
andlw
0x0f
;mask low nibble
goto
DisplayOut
;enable display
UpdateMsd
swapf
MsdTime, W
;get Msd in w
andlw
0x0f
;mask rest
btfsc
STATUS, Z
;msd != 0 then skip
movlw
0x0a
© 2005 Microchip Technology Inc.
AN557
0090
0090
0091
0092
0093
0094
0095
0095
0096
0097
0098
0099
009A
009B
009C
009D
009E
009F
00A0
00A1
00A1
00A2
00A3
00A4
00A5
00A6
00A7
00A8
00A9
00A9
00AA
00AB
00AC
2095
0086
080C
0085
0008
0782
343F
3406
345B
344F
3466
346D
347D
3407
347F
3467
3400
20A9
1D03
0008
0E11
390F
1D03
0008
340A
0810
1D03
0008
340A
00000026
00000027
00000020
00000021
00000022
00000023
00000024
00AD
00AE
00AF
00B0
00B1
00B2
00B3
00B4
00B5
00B6
00B7
1003
3010
00A6
01A2
01A3
01A4
0DA1
0DA0
0DA4
0DA3
0DA2
00B8 0BA6
00B9 28BB
00BA 3400
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
© 2005 Microchip Technology Inc.
DisplayOut
call
movwf
movf
movwf
return
LedTable
PORTB
TempC, W
PORTA
;get digit output
;drive leds
;get sink value in w
addwf
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
PCL, F
B'00111111'
B'00000110'
B'01011011'
B'01001111'
B'01100110'
B'01101101'
B'01111101'
B'00000111'
B'01111111'
B'01100111'
B'00000000'
;add to PC
;led drive
;led drive
;led drive
;led drive
;led drive
;led drive
;led drive
;led drive
;led drive
;led drive
;blank led
call
btfss
return
swapf
andlw
btfss
return
retlw
ChkMsdZero
STATUS, Z
LsdTime, W
0x0f
STATUS, Z
;msd = 0?
;yes then skip
;else return
;get 2nd lsd
;mask of LSD
;0? then skip
.10
;else return with 10
movf
btfss
return
retlw
MsdTime, W
STATUS, Z
;get Msd in w
;= 0? skip
;else return
;ret with 10
;
;
LedTable
low
for 0
for 1
for 2
for 3
for 4
for 5
for 6
for 7
for 8
for 9
drive
;
;
Chk2LsdZero
;
ChkMsdZero
;
;
;
count
temp
;
H_byte
L_byte
R0
R1
R2
;
;
B2_BCD
loop16
equ
equ
.10
26
27
equ
equ
equ
equ
equ
20
21
22
23
24
bcf
movlw
movwf
clrf
clrf
clrf
rlf
rlf
rlf
rlf
rlf
STATUS, 0
.16
count
R0
R1
R2
L_byte, F
H_byte, F
R2, F
R1, F
R0, F
decfsz
goto
RETLW
count, F
adjDEC
0
; RAM Assignments
; clear the carry bit
;
DS00557D-page 19
AN557
00BB 3024
00BC 0084
00BD 20C5
00BE 3023
00BF 0084
00C0 20C5
00C1 3022
00C2 0084
00C3 20C5
00C4 28B3
00C5
00C6
00C7
00C8
00C9
00CA
00CB
00CC
00CD
00CE
00CF
3003
0700
00A7
19A7
0080
3030
0700
00A7
1BA7
0080
3400
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
;
adjDEC
:
:
:
:
X---XXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
R2
FSR
adjBCD
movlw
movwf
call
R1
FSR
adjBCD
movlw
movwf
call
R0
FSR
adjBCD
goto
loop16
movlw
addwf
movwf
btfsc
movwf
movlw
addwf
movwf
btfsc
movwf
RETLW
3
0, W
temp
temp, 3
0
30
0, W
temp
temp, 7
0
0
;
;
;
;
adjBCD
; test if result > 7
; test if result > 7
; save as MSD
;
;
end
MEMORY USAGE MAP ('X' = Used,
0000
0040
0080
00C0
movlw
movwf
call
'-' = Unused)
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
----------------
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
----------------
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
----------------
All other memory blocks unused.
Program Memory Words Used:
Program Memory Words Free:
Errors
:
Warnings :
Messages :
DS00557D-page 20
0
0 reported,
0 reported,
205
819
0 suppressed
7 suppressed
© 2005 Microchip Technology Inc.
AN557
APPENDIX D:
MPLXAD.ASM
MPASM 01.40 Released
LOC OBJECT CODE
VALUE
0000000C
0000000D
0000000E
00000020
00000021
0000000F
00000010
00000011
00000012
00000013
00000014
00000015
00000016
0000002F
0000002E
00000001
00000002
MPLXAD.ASM
1-16-1997
16:23:40
PAGE
1
LINE SOURCE TEXT
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00001
00002
00142
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
© 2005 Microchip Technology Inc.
;*********************************************************************
;This program demonstrates how to multiplex four 7 segment LED
;digits and a 4X4 keypad along with 4 A/D inputs using a PIC16C71.
;The four digits will first display the decimal a/d value of ch0.
;When keys from 0 - 3 are hit the corresponding channel's a/d value
;is displayed in decimal.
;The LEDs are updated every 20mS, the keypad is scanned at a rate of 20
;mS. All 4 channels are scanned at 20mS rate, so each channel gets
;scanned every 80mS. A faster rate of scanning is possible as required
;by the users application.
;Timer0 is used in internal interrupt mode to generate the
;5 mS.
;
;
Stan D'Souza 5/8/93
;
;Corrected error in display routine.
;
Stan D'Souza 2/27/94
;
;
Program:
MPLXAD.ASM
;
Revision Date:
;
1-15-97
Compatibility with MPASMWIN 1.40
;
;**********************************************************************
LIST P=16C71
ERRORLEVEL -302
;
include
<p16c71.inc>
LIST
; P16C71.INC Standard Header File, Ver. 1.00 Microchip Technology, Inc.
LIST
;
TempC
equ
0x0c
;temp general purpose regs
TempD
equ
0x0d
TempE
equ
0x0e
PABuf
equ
0x20
PBBuf
equ
0x21
Count
equ
0x0f
;count
MsdTime
equ
0x10
;most significant Timer
LsdTime
equ
0x11
;Least significant Timer
;
Flag
equ
0x12
;general purpose flag reg
#define
keyhit
Flag, 0
;bit 0 --> key-press on
#define
DebnceOn Flag, 1
;bit 1 -> debounce on
#define
noentry
Flag, 2
;no key entry = 0
#define
ServKey
Flag, 3
;bit 3 --> service key
#define
ADOver
Flag, 4
;bit 4 --> a/d conv. over
;
Debnce
equ
0x13
;debounce counter
NewKey
equ
0x14
DisplayCh equ
0x15
;channel to be displayed
;
ADTABLE
equ
0x16
;4 locations are reserved here
;from 0x16 to 0x19
;
WBuffer
equ
0x2f
StatBuffer equ
0x2e
OptionReg equ
1
PCL
equ
2
DS00557D-page 21
AN557
0000
0000 280D
0004
0004
0005
0006
0007
0008
00AF
0EAF
0E03
00AE
2052
0009
000A
000B
000C
0E2E
0083
0E2F
0009
000D
000D
000E
000F
0010
0010
0011
0012
0013
0014
203B
20EE
2045
1992
2015
1A12
2028
2810
0015
0015
0016
0017
0018
0019
001A
001B
1192
0814
3C03
1C03
0008
0814
0095
001C
001C
001D
001E
001F
0020
0021
0022
0023
0024
0025
3016
0715
0084
0800
00A1
01A0
2106
0824
0091
0823
DS00557D-page 22
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
M
M
M
M
00078
00079
M
M
M
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
;
;
push
;
pop
macro
movwf
swapf
swapf
movwf
endm
WBuffer
WBuffer, F
STATUS, W
StatBuffer
;save w reg in Buffer
;swap it
;get status
;save it
macro
swapf
movwf
swapf
endm
StatBuffer, W
STATUS
WBuffer, W
;restore status
;
/
;restore W reg
org
goto
0
Start
;skip over interrupt vector
;
;
org
4
;It is always a good practice to save and restore the w reg,
;and the status reg during a interrupt.
push
movwf
WBuffer
;save w reg in Buffer
swapf
WBuffer, F
;swap it
swapf
STATUS, W
;get status
movwf
StatBuffer
;save it
call
ServiceInterrupts
pop
swapf
StatBuffer, W
;restore status
movwf
STATUS
;
/
swapf
WBuffer, W
;restore W reg
retfie
;
Start
call
InitPorts
call
InitAd
call
InitTimers
loop
btfsc
ServKey
;key service pending
call
ServiceKey
;yes then service
btfsc
ADOver
;a/d pending?
call
ServiceAD
;yes the service a/d
goto
loop
;
;ServiceKey, does the software service for a keyhit. After a key
;service, the ServKey flag is reset, to denote a completed operation.
ServiceKey
bcf
ServKey
;reset service flag
movf
NewKey, W
;get key value
sublw
3
;key > 3?
btfss
STATUS, C
;no then skip
return
;else ignore key
movf
NewKey, W
movwf
DisplayCh
;load new channel
;
LoadAD
movlw
ADTABLE
;get top of table
addwf
DisplayCh, W
;add offset
movwf
FSR
;init FSR
movf
0, W
;get a/d value
movwf
L_byte
clrf
H_byte
call
B2_BCD
movf
R2, W
;get LSd
movwf
LsdTime
;save in LSD
movf
R1, W
;get Msd
© 2005 Microchip Technology Inc.
AN557
0026 0090
0027 0008
0028
0028
0029
002A
002B
002C
002D
002E
0808
008C
3008
0708
1A88
30C1
0088
002F
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
003A
3016
0084
0C8C
0C8C
0C0C
3903
0784
0809
0080
1212
201C
0008
003B
003B
003C
003D
003E
003F
0040
0041
0042
0043
0044
0045
0045
0046
0047
0048
0049
004A
004B
004C
004D
004E
004F
0050
0051
1683
3003
0088
0185
0186
1283
0185
0186
1585
0008
0190
0191
0195
0192
1683
3084
0081
1283
3020
008B
3060
0081
0009
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
© 2005 Microchip Technology Inc.
movwf
return
MsdTime
;save in Msd
;
;This routine essentially loads the ADRES value in the table location
;determined by the channel offset. If channel 0 then ADRES is saved
;in location ADTABLE. If channel 1 then ADRES is saved at ADTABLE + 1.
;and so on.
ServiceAD
movf
ADCON0, W
;get adcon0
movwf
TempC
;save in temp
movlw
B'00001000'
;select next channel
addwf
ADCON0, W
;
/
btfsc
ADCON0, 5
;if <= ch3
movlw
B'11000001'
;select ch0
movwf
ADCON0
;now load adres in the table
movlw
ADTABLE
movwf
FSR
;load FSR with top
rrf
TempC, F
rrf
TempC, F
rrf
TempC, W
;get in w reg
andlw
3
;mask off all but last 2
addwf
FSR, F
;add offset to table
movf
ADRES, W
;get a/d value
movwf
0
;load indirectly
bcf
ADOver
;clear flag
call
LoadAD
;load a/d value in display reg.
return
;
InitPorts
bsf
movlw
movwf
clrf
clrf
bcf
clrf
clrf
bsf
return
STATUS, RP0
3
ADCON1
TRISA
TRISB
STATUS, RP0
PORTA
PORTB
PORTA, 3
;select Bank1
;make RA0-3 digital I/O
;
/
;make RA0-4 outputs
;make RB0-7 outputs
;select Bank0
;make all outputs low
;
/
;enable MSB digit sink
;
;
;The clock speed is 4.096Mhz. Dividing internal clk. by a 32 prescaler,
;the TMR0 will be incremented every 31.25uS. If TMR0 is preloaded
;with 96, it will take (256-96)*31.25uS to overflow i.e. 5mS. So the
;end result is that we get a TMR0 interrupt every 5mS.
InitTimers
clrf
MsdTime
;clr timers
clrf
LsdTime
;
/
clrf
DisplayCh
;show channel 0
clrf
Flag
;clr all flags
bsf
STATUS, RP0
;select Bank1
movlw
B'10000100'
;assign ps to TMR0
movwf
OptionReg
;ps = 32
bcf
STATUS, RP0
;select Bank0
movlw
B'00100000'
;enable TMR0 interrupt
movwf
INTCON
;
movlw
.96
;preload TMR0
movwf
TMR0
;start counter
retfie
;
DS00557D-page 23
AN557
0052
0052
0053
0054
0055
0056
190B
2857
018B
168B
0008
0057
0057
0058
0059
005A
005B
005C
005D
005E
005F
3060
0081
110B
1805
2060
1985
20F1
20BF
0008
0060
0060
0061
0062
0063
0064
0065
0066
0066
0067
0068
0069
0069
006A
006B
006C
006D
006E
006F
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
007A
007B
007C
007D
007E
007E
007F
1C92
2866
0B93
0008
1092
0008
20A8
30EF
008D
0806
100B
0C8D
1C03
2880
080D
0086
0000
1C0B
2869
1812
287E
1412
0E06
008E
2082
0094
1592
1492
3004
0093
20B5
0008
0080
0080 1012
0081 287E
DS00557D-page 24
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
ServiceInterrupts
btfsc
INTCON, T0IF
;TMR0 interrupt?
goto
ServiceTMR0
;yes then service
clrf
INTCON
;else clr all int
bsf
INTCON, T0IE
return
;
ServiceTMR0
movlw
.96
;initialize TMR0
movwf
TMR0
bcf
INTCON, T0IF
;clr int flag
btfsc
PORTA, 0
;scan keys every 20 mS
call
ScanKeys
;when digit 1 is on
btfsc
PORTA, 3
;scan a/d every 20mS
call
SampleAd
;when digit 4 is on
call
UpdateDisplay
;update display
return
;
;
;ScanKeys, scans the 4x4 keypad matrix and returns a key value in
;NewKey (0 - F) if a key is pressed, if not it clears the keyhit flag.
;Debounce for a given keyhit is also taken care of.
;The rate of key scan is 20mS with a 4.096Mhz clock.
ScanKeys
btfss
DebnceOn
;debounce on?
goto
Scan1
;no then scan keypad
decfsz Debnce, F
;else dec debounce time
return
;not over then return
bcf
DebnceOn
;over, clr debounce flag
return
;and return
Scan1
call
SavePorts
;save port values
movlw
B'11101111'
;init TempD
movwf
TempD
ScanNext
movf
PORTB, W
;read to init port
bcf
INTCON, RBIF
;clr flag
rrf
TempD, F
;get correct column
btfss
STATUS, C
;if carry set?
goto
NoKey
;no then end
movf
TempD, W
;else output
movwf
PORTB
;low column scan line
nop
btfss
INTCON, RBIF
;flag set?
goto
ScanNext
;no then next
btfsc
keyhit
;last key released?
goto
SKreturn
;no then exit
bsf
keyhit
;set new key hit
swapf
PORTB,W
;read port
movwf
TempE
;save in TempE
call
GetKeyValue
;get key value 0 - F
movwf
NewKey
;save as New key
bsf
ServKey
;set service flag
bsf
DebnceOn
;set flag
movlw
4
movwf
Debnce
;load debounce time
SKreturn
call
RestorePorts
;restore ports
return
;
NoKey
bcf
keyhit
;clr flag
goto
SKreturn
;
;GetKeyValue gets the key as per the following layout
;
© 2005 Microchip Technology Inc.
AN557
0082
0082
0083
0084
0085
0086
0087
0088
0089
008A
008B
008C
008C
008D
008E
008F
0090
0091
0092
0092
0093
0093
0094
0095
0095
0096
0096
0097
0098
0099
009A
009B
009C
009D
009E
009F
00A0
00A1
00A2
00A3
00A4
00A5
00A6
00A7
00A8
00A8
00A9
00AA
00AB
00AC
00AD
00AE
018C
1D8D
288C
0A8C
1D0D
288C
0A8C
1C8D
288C
0A8C
1C0E
2896
1C8E
2895
1D0E
2893
150C
158C
2896
150C
080C
0782
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
340A
340B
340C
340D
340E
340F
0805
00A0
0185
0806
00A1
30FF
0086
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
© 2005 Microchip Technology Inc.
;
;
;
;Row1(RB4)
;
;Row2(RB5)
;
;Row3(RB6)
;
;Row4(RB7)
;
GetKeyValue
Col1
(RB3)
Col2
(RB2)
Col3
(RB1)
Col4
(RB0)
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
clrf
btfss
goto
incf
btfss
goto
incf
btfss
goto
incf
TempC
TempD, 3
RowValEnd
TempC, F
TempD, 2
RowValEnd
TempC, F
TempD, 1
RowValEnd
TempC, F
btfss
goto
btfss
goto
btfss
goto
TempE, 0
GetValCom
TempE, 1
Get4567
TempE, 2
Get89ab
;top
;yes
;2nd
;yes
;3rd
;yes
bsf
TempC, 2
;set msb bits
bsf
goto
TempC, 3
GetValCom
;
/
;do common part
bsf
TempC, 2
movf
addwf
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
TempC, W
PCL, F
0
1
2
3
4
5
6
7
8
9
0a
0b
0c
0d
0e
0f
;first column
;second col.
;3rd col.
;last col.
RowValEnd
row?
then get 0,1,2&3
row?
the get 4,5,6&7
row?
then get 8,9,a&b
Getcdef
Get89ab
Get4567
GetValCom
;
;SavePorts, saves the porta and portb condition during a key scan
;operation.
SavePorts
movf
PORTA, W
;Get sink value
movwf
PABuf
;save in buffer
clrf
PORTA
;disable all sinks
movf
PORTB, W
;get port b
movwf
PBBuf
;save in buffer
movlw
0xff
;make all high
movwf
PORTB
;on port b
DS00557D-page 25
AN557
00AF
00B0
00B1
00B2
00B3
00B4
00B5
00B5
00B6
00B7
00B8
00B9
00BA
00BB
00BC
00BD
00BE
00BF
00BF
00C0
00C1
00C2
00C3
00C4
00C5
00C6
00C7
00C8
00C9
00CA
00CB
00CC
00CD
00CD
00CE
00CF
00D0
00D0
00D1
00D2
00D3
00D3
00D4
00D5
00D6
00D6
00D7
00D8
00D8
00D9
00DA
00DB
00DC
00DD
00DD
00DE
00DF
00E0
00E1
1683
1381
30F0
0086
1283
0008
0821
0086
0820
0085
1683
1781
0185
0186
1283
0008
0805
0185
390F
008C
160C
0C8C
1C03
118C
180C
28D6
188C
28D3
190C
28D0
0811
390F
28D8
0E11
390F
28D8
0810
390F
28D8
0E10
390F
20DD
0086
080C
0085
0008
0782
343F
3406
345B
344F
DS00557D-page 26
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
bsf
bcf
movlw
movwf
bcf
return
STATUS, RP0
OptionReg, 7
B'11110000'
TRISB
STATUS, RP0
;select Bank1
;enable pull ups
;port b hi nibble inputs
;lo nibble outputs
;Bank0
;
;RestorePorts, restores the condition of porta and portb after a
;key scan operation.
RestorePorts
movf
PBBuf, W
;get port b
movwf
PORTB
movf
PABuf, W
;get port a value
movwf
PORTA
bsf
STATUS, RP0
;select Bank1
bsf
OptionReg, 7
;disable pull ups
clrf
TRISA
;make port a outputs
clrf
TRISB
;as well as PORTB
bcf
STATUS, RP0
;Bank0
return
;
;
UpdateDisplay
movf
PORTA, W
;present sink value in w
clrf
PORTA
;disable all digits sinks
andlw
0x0f
movwf
TempC
;save sink value in tempC
bsf
TempC, 4
;preset for lsd sink
rrf
TempC, F
;determine next sink value
btfss
STATUS, C
;c=1?
bcf
TempC, 3
;no then reset LSD sink
btfsc
TempC, 0
;else see if Msd
goto
UpdateMsd
;yes then do Msd
btfsc
TempC, 1
;see if 3rdLsd
goto
Update3rdLsd
;yes then do 3rd Lsd
btfsc
TempC, 2
;see if 2nd Lsd
goto
Update2ndLsd
;yes then do 2nd lsd
UpdateLsd
movf
LsdTime, W
;get Lsd in w
andlw
0x0f
;
/
goto
DisplayOut
Update2ndLsd
swapf
LsdTime, W
;get 2nd Lsd in w
andlw
0x0f
;mask rest
goto
DisplayOut
;enable display
Update3rdLsd
movf
MsdTime, W
;get 3rd Lsd in w
andlw
0x0f
;mask low nibble
goto
DisplayOut
;enable display
UpdateMsd
swapf
MsdTime, W
;get Msd in w
andlw
0x0f
;mask rest
DisplayOut
call
LedTable
;get digit output
movwf
PORTB
;drive leds
movf
TempC, W
;get sink value in w
movwf
PORTA
return
;
;
LedTable
addwf
PCL, F
;add to PC low
retlw
B'00111111'
;led drive for 0
retlw
B'00000110'
;led drive for 1
retlw
B'01011011'
;led drive for 2
retlw
B'01001111'
;led drive for 3
© 2005 Microchip Technology Inc.
AN557
00E2
00E3
00E4
00E5
00E6
00E7
00E8
00E9
00EA
00EB
00EC
00ED
3466
346D
347D
3407
347F
3467
3477
347C
3439
345E
3479
3471
00EE
00EE 30C0
00EF 0088
00F0 0008
00F1
00F1
00F2
00F3
00F3
00F4
00F5
00F6
00F7
00F8
00F8
00F9
00FA
00FB
00FC
00FD
00FE
00FF
0100
0101
0102
0102
0103
0103
0104
0105
20A8
20F8
1908
28F3
1612
20B5
0008
0186
1683
300F
0085
1283
1408
307D
2102
1508
0008
008C
0B8C
2903
0008
00000026
00000027
00000020
00000021
00000022
00000023
00000024
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
B'01100110'
B'01101101'
B'01111101'
B'00000111'
B'01111111'
B'01100111'
B'01110111'
B'01111100'
B'00111001'
B'01011110'
B'01111001'
B'01110001'
;led
;led
;led
;led
;led
;led
;led
;led
;led
;led
;led
;led
drive
drive
drive
drive
drive
drive
drive
drive
drive
drive
drive
drive
for
for
for
for
for
for
for
for
for
for
for
for
4
5
6
7
8
9
A
b
C
d
E
F
movlw
movwf
B'11000000'
ADCON0
;internal rc for tad
;
/
;note that adcon1 is set in InitPorts
;
;
InitAd
return
;
SampleAd
call
call
SavePorts
DoAd
;do a ad conversion
btfsc
goto
bsf
call
return
ADCON0, GO
AdDone
ADOver
RestorePorts
;ad done?
;no then loop
;set a/d over flag
;restore ports
clrf
bsf
movlw
movwf
bcf
bsf
movlw
call
bsf
return
PORTB
STATUS,
0x0f
TRISA
STATUS,
ADCON0,
.125
Wait
ADCON0,
RP0
ADON
;turn off leds
;select Bank1
;make port a hi-Z
;
/
;select Bank0
;start a/d
GO
;start conversion
movwf
TempC
decfsz
goto
return
TempC, F
Next
equ
equ
26
27
equ
equ
equ
equ
equ
20
21
22
23
24
AdDone
;
;
DoAd
RP0
;
;
Wait
;store in temp
Next
;
;
count
temp
;
H_byte
L_byte
R0
R1
R2
;
;
© 2005 Microchip Technology Inc.
; RAM Assignments
DS00557D-page 27
AN557
0106
0107
0108
0109
010A
010B
010C
010D
010E
010F
0110
1003
3010
00A6
01A2
01A3
01A4
0DA1
0DA0
0DA4
0DA3
0DA2
0111 0BA6
0112 2914
0113 3400
0114 3024
0115 0084
0116 211E
0117 3023
0118 0084
0119 211E
011A 3022
011B 0084
011C 211E
011D 290C
011E
011F
0120
0121
0122
0123
0124
0125
0126
0127
0128
3003
0700
00A7
19A7
0080
3030
0700
00A7
1BA7
0080
3400
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
B2_BCD
loop16
:
:
:
:
:
X---XXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
STATUS, 0
.16
count
R0
R1
R2
L_byte, F
H_byte, F
R2, F
R1, F
R0, F
decfsz
goto
RETLW
count, F
adjDEC
0
movlw
movwf
call
R2
FSR
adjBCD
movlw
movwf
call
R1
FSR
adjBCD
movlw
movwf
call
R0
FSR
adjBCD
goto
loop16
movlw
addwf
movwf
btfsc
movwf
movlw
addwf
movwf
btfsc
movwf
RETLW
3
0, W
temp
temp, 3
0
30
0, W
temp
temp, 7
0
0
; clear the carry bit
;
;
adjDEC
;
;
;
;
adjBCD
; test if result > 7
; test if result > 7
; save as MSD
;
;
;
;
end
MEMORY USAGE MAP ('X' = Used,
0000
0040
0080
00C0
0100
bcf
movlw
movwf
clrf
clrf
clrf
rlf
rlf
rlf
rlf
rlf
'-' = Unused)
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXX-------
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX
----------------
All other memory blocks unused.
Program Memory Words Used:
Program Memory Words Free:
Errors
:
Warnings :
Messages :
DS00557D-page 28
0
0 reported,
0 reported,
294
730
0 suppressed
7 suppressed
© 2005 Microchip Technology Inc.
Note the following details of the code protection feature on Microchip devices:
•
Microchip products meet the specification contained in their particular Microchip Data Sheet.
•
Microchip believes that its family of products is one of the most secure families of its kind on the market today, when used in the
intended manner and under normal conditions.
•
There are dishonest and possibly illegal methods used to breach the code protection feature. All of these methods, to our
knowledge, require using the Microchip products in a manner outside the operating specifications contained in Microchip’s Data
Sheets. Most likely, the person doing so is engaged in theft of intellectual property.
•
Microchip is willing to work with the customer who is concerned about the integrity of their code.
•
Neither Microchip nor any other semiconductor manufacturer can guarantee the security of their code. Code protection does not
mean that we are guaranteeing the product as “unbreakable.”
Code protection is constantly evolving. We at Microchip are committed to continuously improving the code protection features of our
products. Attempts to break Microchip’s code protection feature may be a violation of the Digital Millennium Copyright Act. If such acts
allow unauthorized access to your software or other copyrighted work, you may have a right to sue for relief under that Act.
Information contained in this publication regarding device
applications and the like is provided only for your convenience
and may be superseded by updates. It is your responsibility to
ensure that your application meets with your specifications.
MICROCHIP MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND WHETHER EXPRESS OR IMPLIED,
WRITTEN OR ORAL, STATUTORY OR OTHERWISE,
RELATED TO THE INFORMATION, INCLUDING BUT NOT
LIMITED TO ITS CONDITION, QUALITY, PERFORMANCE,
MERCHANTABILITY OR FITNESS FOR PURPOSE.
Microchip disclaims all liability arising from this information and
its use. Use of Microchip’s products as critical components in
life support systems is not authorized except with express
written approval by Microchip. No licenses are conveyed,
implicitly or otherwise, under any Microchip intellectual property
rights.
Trademarks
The Microchip name and logo, the Microchip logo, Accuron,
dsPIC, KEELOQ, microID, MPLAB, PIC, PICmicro, PICSTART,
PRO MATE, PowerSmart, rfPIC, and SmartShunt are
registered trademarks of Microchip Technology Incorporated
in the U.S.A. and other countries.
AmpLab, FilterLab, Migratable Memory, MXDEV, MXLAB,
PICMASTER, SEEVAL, SmartSensor and The Embedded
Control Solutions Company are registered trademarks of
Microchip Technology Incorporated in the U.S.A.
Analog-for-the-Digital Age, Application Maestro, dsPICDEM,
dsPICDEM.net, dsPICworks, ECAN, ECONOMONITOR,
FanSense, FlexROM, fuzzyLAB, In-Circuit Serial
Programming, ICSP, ICEPIC, Linear Active Thermistor,
MPASM, MPLIB, MPLINK, MPSIM, PICkit, PICDEM,
PICDEM.net, PICLAB, PICtail, PowerCal, PowerInfo,
PowerMate, PowerTool, rfLAB, rfPICDEM, Select Mode,
Smart Serial, SmartTel, Total Endurance and WiperLock are
trademarks of Microchip Technology Incorporated in the
U.S.A. and other countries.
SQTP is a service mark of Microchip Technology Incorporated
in the U.S.A.
All other trademarks mentioned herein are property of their
respective companies.
© 2005, Microchip Technology Incorporated, Printed in the
U.S.A., All Rights Reserved.
Printed on recycled paper.
Microchip received ISO/TS-16949:2002 quality system certification for
its worldwide headquarters, design and wafer fabrication facilities in
Chandler and Tempe, Arizona and Mountain View, California in
October 2003. The Company’s quality system processes and
procedures are for its PICmicro® 8-bit MCUs, KEELOQ® code hopping
devices, Serial EEPROMs, microperipherals, nonvolatile memory and
analog products. In addition, Microchip’s quality system for the design
and manufacture of development systems is ISO 9001:2000 certified.
© 2005 Microchip Technology Inc.
DS00557D-page 29
WORLDWIDE SALES AND SERVICE
AMERICAS
ASIA/PACIFIC
ASIA/PACIFIC
EUROPE
Corporate Office
2355 West Chandler Blvd.
Chandler, AZ 85224-6199
Tel: 480-792-7200
Fax: 480-792-7277
Technical Support:
http://support.microchip.com
Web Address:
www.microchip.com
Australia - Sydney
Tel: 61-2-9868-6733
Fax: 61-2-9868-6755
India - Bangalore
Tel: 91-80-2229-0061
Fax: 91-80-2229-0062
China - Beijing
Tel: 86-10-8528-2100
Fax: 86-10-8528-2104
India - New Delhi
Tel: 91-11-5160-8631
Fax: 91-11-5160-8632
Austria - Weis
Tel: 43-7242-2244-399
Fax: 43-7242-2244-393
Denmark - Ballerup
Tel: 45-4450-2828
Fax: 45-4485-2829
China - Chengdu
Tel: 86-28-8676-6200
Fax: 86-28-8676-6599
Japan - Kanagawa
Tel: 81-45-471- 6166
Fax: 81-45-471-6122
France - Massy
Tel: 33-1-69-53-63-20
Fax: 33-1-69-30-90-79
China - Fuzhou
Tel: 86-591-8750-3506
Fax: 86-591-8750-3521
Korea - Seoul
Tel: 82-2-554-7200
Fax: 82-2-558-5932 or
82-2-558-5934
Germany - Ismaning
Tel: 49-89-627-144-0
Fax: 49-89-627-144-44
Atlanta
Alpharetta, GA
Tel: 770-640-0034
Fax: 770-640-0307
Boston
Westborough, MA
Tel: 774-760-0087
Fax: 774-760-0088
Chicago
Itasca, IL
Tel: 630-285-0071
Fax: 630-285-0075
Dallas
Addison, TX
Tel: 972-818-7423
Fax: 972-818-2924
Detroit
Farmington Hills, MI
Tel: 248-538-2250
Fax: 248-538-2260
Kokomo
Kokomo, IN
Tel: 765-864-8360
Fax: 765-864-8387
China - Hong Kong SAR
Tel: 852-2401-1200
Fax: 852-2401-3431
China - Shanghai
Tel: 86-21-5407-5533
Fax: 86-21-5407-5066
China - Shenyang
Tel: 86-24-2334-2829
Fax: 86-24-2334-2393
China - Shenzhen
Tel: 86-755-8203-2660
Fax: 86-755-8203-1760
China - Shunde
Tel: 86-757-2839-5507
Fax: 86-757-2839-5571
China - Qingdao
Tel: 86-532-502-7355
Fax: 86-532-502-7205
Malaysia - Penang
Tel:011-604-646-8870
Fax:011-604-646-5086
Philippines - Manila
Tel: 011-632-634-9065
Fax: 011-632-634-9069
Singapore
Tel: 65-6334-8870
Fax: 65-6334-8850
Italy - Milan
Tel: 39-0331-742611
Fax: 39-0331-466781
Netherlands - Drunen
Tel: 31-416-690399
Fax: 31-416-690340
England - Berkshire
Tel: 44-118-921-5869
Fax: 44-118-921-5820
Taiwan - Kaohsiung
Tel: 886-7-536-4818
Fax: 886-7-536-4803
Taiwan - Taipei
Tel: 886-2-2500-6610
Fax: 886-2-2508-0102
Taiwan - Hsinchu
Tel: 886-3-572-9526
Fax: 886-3-572-6459
Los Angeles
Mission Viejo, CA
Tel: 949-462-9523
Fax: 949-462-9608
San Jose
Mountain View, CA
Tel: 650-215-1444
Fax: 650-961-0286
Toronto
Mississauga, Ontario,
Canada
Tel: 905-673-0699
Fax: 905-673-6509
04/20/05
DS00557D-page 30
© 2005 Microchip Technology Inc.