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.