MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 1 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00001 ; NWRD Nixie Clock program for 2 B5870 tubes and PIC16F872 00002 ; 00003 ; Copyright (C) 2005 David Forbes 00004 ; 00005 ; This program is free software; you can redistribute it and/or modify 00006 ; it under the terms of the GNU General Public License as published by 00007 ; the Free Software Foundation; either version 2 of the License, or 00008 ; (at your option) any later version. 00009 ; 00010 ; This program is distributed in the hope that it will be useful, 00011 ; but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 ; GNU General Public License for more details. 00014 ; 00015 ;------------------------------------------------------------- 00016 ; Revision history 00017 ; 00018 ; 7/19/03 DF Got watch running. Tilt is not working - triggers 00019 ; at nearly any angle. Going back to MSBs of ADC. 00020 ; 1/11/05 DF Copied from NWFB to NWRA. Changed disp pinouts. 00021 ; Removed tilt00 stuff. Left LSB A/D in case we modify it. 00022 ; 1/12/05 DF Fixed tilt to match board. 00023 ; 1/15/05 DF Converting to NWRB code base for seconds, other improvements. 00024 ; 3/05/05 DF Converting from NWRA to NWRD board. 00025 ; 5/06/05 DF Did update seconds disp during setting, 00026 ; tried fix blobby glow at turn-on by moving poweron later, 00027 ; Need to improve tilt angle detection 00028 ; 5/10/05 DF Added GPL license blurb 00029 ; 5/16/05 DF Fixed tilt margins, cleaned up comments, removed dead wood 00030 ; 5/18/05 DF Fixing seconds reset to clear timer also for precise zeroing 00031 ; 00032 ;------------------------------------------------------------- 00033 ; Theory of Operation 00034 ; 00035 ; This clock has two display tubes and uses them to show 00036 ; first hours, then minutes when the tilt sensor says to. 00037 ; 00038 ; The processor runs at the stately speed of 8192 instructions per second. 00039 ; This has had a big influence on the code structure, as there are no 00040 ; spare cycles to waste. Every NOP is visible in the display. 00041 ; 00042 ; The tilt sensor is a 2-axis accelerometer ADXL311JE or ADXL202JE 00043 ; used in analog mode for max speed. A/D converter is two channels 00044 ; with A3 used as both Vref and digital power out to tilt sensor. 00045 ; 00046 ; The tilt sensing algorithm works by looking for both X and Y g factors 00047 ; of approximately 0.65g in the desired direction of upwards and toward 00048 ; the user. 00049 ; To prevent false triggering, an additional constraint is Xtilt + ytilt. 00050 ; 00051 ; The ADC is not very sensitive as used; the tilt values have the following 00052 ; range (approximate). 00053 ; X is h'70' at horizontal, h'80' at vertical. Good tilt < h'75'. MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 2 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00054 ; Y is h'80' at horizontal, h'90' at vertical. Good tilt > h'8B'. 00055 ; 00056 ; OffLoop waits for valid angles from tilt sensor or Set button push. 00057 ; Pressing the Adv button while off enters diagnostic tilt display mode. 00058 ; 00059 ; When the display turns on it displays hours for a second, then 00060 ; displays minutes for a second, then either shuts off or displays seconds. 00061 ; 00062 ; The display code is constructed to minimize off-time of tubes 00063 ; so that display will be as bright as possible. This means that 00064 ; all display formatting is done outside the tube-scanning loop. 00065 ; 00066 ; There is a diagnostic tilt angle display activated by pressing Adv when off. 00067 ; First X tilt is displayed, then Y tilt, then back to off. 00068 ; The tilt angle display does a cheesy hex display by lighting two cathodes 00069 ; such as '9' and '1' for hex 'A'. Their sum is the hex value. 00070 ; I could modify this to use BCD, but life is too short. 00071 ; Perhaps someone else wants to do that. 00072 ; 00073 ; Timesetting mode is entered from off loop by detecting Set button held. 00074 ; first we set 12/24 then hours then tens minutes then unit minutes then 00075 ; the tilt angle. The Adv button advances the digit(s) being set. 00076 ; 00077 ; If the watch is tilted for 1 whole second after hrs/mins display, 00078 ; then it enters seconds display mode. It turns off either 00079 ; if it's no longer tilted right or if the seconds timeout expires. 00080 ; Tilt check occurs right after the change of the second. 00081 ; 00082 ; The display period for each second is 2/3 second to save power. 00083 ; 00084 ; Timer is set to div/16384 to give one tick per second. 00085 ; No interrupts are used since they cause display glitches. 00086 ; Instead, time is incremented by DoTime when timer0 overflows. 00087 ; 00088 ; Hardware trick: Resistor from TiltPwr to HV sense provides 00089 ; blanking control by driving HV below 120V if TiltPwr on. 00090 ; Tilt is not needed at this time, so it's a free control bit. 00091 ; 00092 ;--------------------------------------------------------------- 00093 ; 00094 ; define chip type, hardware addrs & bits 00095 ; 00096 list p=16f872 00097 00098 include "p16f872.inc" 00001 LIST 00002 ; P16F872.INC Standard Header File, Version 1.00 Microchip Technology, Inc. 00310 LIST 00099 00100 ; 12 hour display mode parameters 00101 00000001 00102 FHr12 equ 1 ; hour to wrap to 00000001 00103 LHrT12 equ 1 ; last hour tens MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 3 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00000003 00104 LHrU12 equ 3 ; last hour units 00000001 00105 DHrT12 equ 1 ; display hour tens 00000002 00106 DHrU12 equ 2 ; display hour units 00107 00108 ; 24 hour display mode parameters 00109 00000000 00110 FHr24 equ 0 ; hour to wrap to 00000002 00111 LHrT24 equ 2 ; last hour tens 00000004 00112 LHrU24 equ 4 ; last hour units 00000002 00113 DHrT24 equ 2 ; display hour tens 00000004 00114 DHrU24 equ 4 ; display hour units 00115 00116 ; Time constants for display 00117 0000000A 00118 DigTim equ h'0A' ; # loops per 6 milliseconds (Less due to DoSet) 000000C0 00119 OffTim equ h'C0' ; # loops per 1/8 second for offloop 0000000E 00120 TiltTim equ h'0E' ; # of mux cycles to display tilt 0000001A 00121 HrsTim equ h'1A' ; # of mux cycles to display hours 00000030 00122 PausTim equ h'30' ; # of mux cycles to pause btwn hrs,mins 00000020 00123 MinTim equ h'20' ; # of mux cycles to display minutes 00000014 00124 SecTim equ h'14' ; # of mux cycles to display seconds 0000000C 00125 BlnkTim equ h'0C' ; blink half-period in mux cycles 00000006 00126 HangTim equ h'06' ; # of Offtims to wait after displaying 00000040 00127 SetTOut equ h'40' ; time setting timeout in seconds 0000000F 00128 TDTOut equ h'0F' ; tilt display timeout in seconds 00000001 00129 XTMargin equ h'01' ; display X tilt margin from captured X 000000FF 00130 YTMargin equ h'ff' ; display Y tilt margin from captured Y 00131 00132 ; Port A bit definitions 00133 ; 00134 ; PA5 I Adv 0=Adv button pushed 00135 ; PA4 I Set 0=Set button pushed 00136 ; PA3 A,O TPwr Analog vref in and 1->TiltPwr, HV blank 00137 ; PA2 O DispEn 1->DispPwr 00138 ; PA1 A TiltX Analog X tilt signal 00139 ; PA0 A TiltY Analog Y tilt signal 00140 00000005 00141 AdvButt equ 5 ; Adv button bit pressed = 0 00000004 00142 SetButt equ 4 ; Set button bit pressed = 0 00000000 00143 TiltY equ 0 ; Y tilt sensor analog signal 00000001 00144 TiltX equ 1 ; X tilt sensor analog signal 00145 ; 00146 ; Write the following literals to PORTA to set power bits 00147 ; 00000000 00148 PwrOff equ h'00' ; no power to nuthin' 00000004 00149 PwrDisp equ h'04' ; display HV on and not blanked 00000008 00150 PwrTilt equ h'08' ; Tilt sensor power on, no HV 0000000C 00151 PwrBlnk equ h'0C' ; display HV on but blanked 00152 ; 00153 ; Port B bit definitions 00154 ; 00155 ; PB7 O R1 ; Right digit cathode 1 00156 ; PB6 O R0 MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 4 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00157 ; PB5 O R2 00158 ; PB4 O R9 00159 ; PB3 O R3 00160 ; PB2 O R8 00161 ; PB1 O R4 00162 ; PB0 O R5 00163 00164 ; Port C bit definitions 00165 ; 00166 ; PC7 O L2 ; Left digit cathode 2 00167 ; PC6 O L3 00168 ; PC5 O L4 00169 ; PC4 O L1 00170 ; PC3 O R6 00171 ; PC2 O R7 00172 ; PC1 O L0 00173 ; PC0 O L5 00174 ; 00175 ; Bits in SetDig tell which digit's being set 00176 ; 00000000 00177 NotSet equ 0 ; not in set mode 00000001 00178 H24Set equ 1 ; setting hours 00000002 00179 HrsSet equ 2 ; setting hours 00000003 00180 TMinSet equ 3 ; setting tens of minutes 00000004 00181 UMinSet equ 4 ; setting units minutes 00000005 00182 SecSet equ 5 ; set seconds to 00 when Adv pushed 00000006 00183 T45Set equ 6 ; setting tilt angle for 45 degrees 00000007 00184 DoneSet equ 7 ; were setting tilt, shut off display now 00185 ; 00186 ; Bits in TDDig tell which tilt axis is displayed 00187 ; 00000000 00188 NotTD equ 0 ; not in tilt disp mode 00000001 00189 XTDisp equ 1 ; display X tilt 00000002 00190 YTDisp equ 2 ; display Y tilt 00000003 00191 DoneTD equ 3 ; were displaying tilt, shut off display now 00192 ; 00193 ; bit definitions for display status word Display 00194 ; 00000000 00195 LBlink equ 0 ; left blink flag 1=blink 00000001 00196 RBlink equ 1 ; right blink flag 1=blink 00000002 00197 LBlank equ 2 ; left blank flag 1=blank 00000003 00198 RBlank equ 3 ; right blank flag 1=blank 00000007 00199 Hrs24 equ 7 ; 12/24 hour mode: 1=24hr 00200 ; 00201 ; Define RAM storage variables 00202 ; 00203 cblock h'020' 00000020 00204 THrs ; tens of hours range 0-1 00000021 00205 UHrs ; units hours range 0-9 00000022 00206 TMins ; tens of minutes range 0-5 00000023 00207 UMins ; units of minutes range 0-9 00000024 00208 TSecs ; tens of seconds range 0-5 00000025 00209 USecs ; units of seconds range 0-9 MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 5 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00000026 00210 TMinD ; displayed tens of minutes 00000027 00211 UMinD ; displayed units of minutes 00000028 00212 LDigit ; Left digit BCD value to display 00000029 00213 RDigit ; Right digit BCD value to display 0000002A 00214 SetDig ; code of digit being set 0000002B 00215 SetHist ; time that Set button has been held on 0000002C 00216 TDHist ; time that Adv button has been held on for tdisplp 0000002D 00217 TDDig ; mode of tilt display 0000002E 00218 AdvHist ; time that Adv button has been held on 0000002F 00219 TltHist ; time that tilt has been correct 00000030 00220 Display ; display status bits per above 00000031 00221 DispTim ; time left to display this bit 00000032 00222 XTilt ; tilt of X axis from tilt sensor 00000033 00223 YTilt ; tilt of Y axis from tilt sensor 00000034 00224 DTilt ; Y tilt - X tilt from tilt sensor 00000035 00225 XTLim45 ; X tilt limit for 45 degree display 00000036 00226 YTLim45 ; Y tilt limit for 45 degree display 00000037 00227 DTLim45 ; Y-X tilt limit for 45 degree display 00000038 00228 TimLeft ; delay routine working storage 00000039 00229 LBData ; Left digit B port cathode bits 0000003A 00230 LCData ; Left digit C port cathode bits 0000003B 00231 RBData ; Right digit B port cathode bits 0000003C 00232 RCData ; Right digit C port cathode bits 0000003D 00233 SetTim ; timeout countdown for time setting mode (secs) 0000003E 00234 TDTim ; timeout countdown for tilt display mode (secs) 0000003F 00235 FirstHr ; first hour 0 or 1 00000040 00236 LastHrT ; last tens hour 1 or 2 00000041 00237 LastHrU ; last units hour 3 or 4 00000042 00238 DispHrT ; display tens hour 1 or 2 00000043 00239 DispHrU ; display units hour 3 or 4 00000044 00240 SecCnt ; number of seconds left to display 00241 00242 endc 00243 ; 00244 ; Upon reset, init ports and timer 00245 ; 0000 00246 org h'000' 0000 0000 00247 nop ; for debugger 0001 285F 00248 goto Start 00249 ; 00250 ; Load display digits with various time digits 00251 ; These are called by all display updating functions 00252 ; 0002 0824 00253 LdSecs movfw TSecs ; copy current secs into disp digits 0003 00A8 00254 movwf LDigit 0004 0825 00255 movfw USecs 0005 00A9 00256 movwf RDigit 0006 201A 00257 call LdDigs 0007 0008 00258 return 00259 0008 0822 00260 LdMins movfw TMins ; copy current mins into disp digits 0009 00A8 00261 movwf LDigit 000A 0823 00262 movfw UMins MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 6 LOC OBJECT CODE LINE SOURCE TEXT VALUE 000B 00A9 00263 movwf RDigit 000C 201A 00264 call LdDigs 000D 0008 00265 return 00266 000E 0826 00267 LdMinD movfw TMinD 000F 00A8 00268 movwf LDigit 0010 0827 00269 movfw UMinD ; copy saved minutes into L&R digits 0011 00A9 00270 movwf RDigit 0012 201A 00271 call LdDigs 0013 0008 00272 return 00273 0014 0820 00274 LdHrs movfw THrs 0015 00A8 00275 movwf LDigit 0016 0821 00276 movfw UHrs 0017 00A9 00277 movwf RDigit ; copy current time into local storage 0018 201A 00278 call LdDigs 0019 0008 00279 return 00280 ; 00281 ; Load port B and C digit storage with cathode codes 00282 ; Reads LDigit and RDigit 00283 ; puts results in LBData..RCData 00284 ; 00285 ; This is done here to increase brightness by reducing workload 00286 ; of DispLp, which used to do all this stuff every iteration. 00287 ; 001A 3007 00288 LdDigs movlw h'07' ; prepare for left digit display 001B 05A8 00289 andwf LDigit,f ; fix range of number 001C 2027 00290 call BLeft 001D 00B9 00291 movwf LBData ; save B and C cathode codes 001E 2031 00292 call CLeft ; using bizarre PIC table lookup subroutines 001F 00BA 00293 movwf LCData 0020 300F 00294 movlw h'0F' ; prepare for right digit display 0021 05A9 00295 andwf RDigit,f ; fix range of number 0022 203B 00296 call BRight 0023 00BB 00297 movwf RBData ; Save B and C cathode codes 0024 204D 00298 call CRight 0025 00BC 00299 movwf RCData 0026 0008 00300 return 00301 ; 00302 ; The following tables are located here to ensure no wrap on PCL 00303 ; 00304 ; Lookup routines to set ports B and C to Nixie cathode 00305 ; per LDigit and RDigit 00306 ; 00307 ; Port B left tube 00308 ; 0027 0828 00309 BLeft movfw LDigit 0028 0782 00310 addwf PCL,f 00311 ; RRRRRRRR 00312 ; 10293845 0029 3400 00313 retlw B'00000000' ; left 0 002A 3400 00314 retlw B'00000000' ; left 1 002B 3400 00315 retlw B'00000000' ; left 2 MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 7 LOC OBJECT CODE LINE SOURCE TEXT VALUE 002C 3400 00316 retlw B'00000000' ; left 3 002D 3400 00317 retlw B'00000000' ; left 4 002E 3400 00318 retlw B'00000000' ; left 5 002F 3400 00319 retlw B'00000000' ; left 6 displays 1,5 0030 3400 00320 retlw B'00000000' ; left 7 displays 2,5 00321 ; 00322 ; Port C left tube 00323 ; 0031 0828 00324 CLeft movfw LDigit 0032 0782 00325 addwf PCL,f 00326 ; LLLLRRLL 00327 ; 23416705 0033 3402 00328 retlw B'00000010' ; left 0 0034 3410 00329 retlw B'00010000' ; left 1 0035 3480 00330 retlw B'10000000' ; left 2 0036 3440 00331 retlw B'01000000' ; left 3 0037 3420 00332 retlw B'00100000' ; left 4 0038 3401 00333 retlw B'00000001' ; left 5 0039 3411 00334 retlw B'00010001' ; left 6 displays 1,5 003A 3481 00335 retlw B'10000001' ; left 7 displays 2,5 00336 ; 00337 ; Port B right tube 00338 ; 003B 0829 00339 BRight movfw RDigit 003C 0782 00340 addwf PCL,f 00341 ; RRRRRRRR 00342 ; 10293845 003D 3440 00343 retlw B'01000000' ; right 0 003E 3480 00344 retlw B'10000000' ; right 1 003F 3420 00345 retlw B'00100000' ; right 2 0040 3408 00346 retlw B'00001000' ; right 3 0041 3402 00347 retlw B'00000010' ; right 4 0042 3401 00348 retlw B'00000001' ; right 5 0043 3400 00349 retlw B'00000000' ; right 6 0044 3400 00350 retlw B'00000000' ; right 7 0045 3404 00351 retlw B'00000100' ; right 8 0046 3410 00352 retlw B'00010000' ; right 9 0047 34C0 00353 retlw B'11000000' ; right 10 displays 1,0 0048 3430 00354 retlw B'00110000' ; right 11 displays 2,9 0049 34A0 00355 retlw B'10100000' ; right 12 displays 1,2 004A 3488 00356 retlw B'10001000' ; right 13 displays 1,3 004B 3482 00357 retlw B'10000010' ; right 14 displays 1,4 004C 3481 00358 retlw B'10000001' ; right 15 displays 1,5 00359 ; 00360 ; Port C right tube 00361 ; 004D 0829 00362 CRight movfw RDigit 004E 0782 00363 addwf PCL,f 00364 ; LLLLRRLL 00365 ; 23416705 004F 3400 00366 retlw B'00000000' ; right 0 0050 3400 00367 retlw B'00000000' ; right 1 0051 3400 00368 retlw B'00000000' ; right 2 MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 8 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0052 3400 00369 retlw B'00000000' ; right 3 0053 3400 00370 retlw B'00000000' ; right 4 0054 3400 00371 retlw B'00000000' ; right 5 0055 3408 00372 retlw B'00001000' ; right 6 0056 3404 00373 retlw B'00000100' ; right 7 0057 3400 00374 retlw B'00000000' ; right 8 0058 3400 00375 retlw B'00000000' ; right 9 0059 3400 00376 retlw B'00000000' ; right 10 displays 1,0 005A 3400 00377 retlw B'00000000' ; right 11 displays 2,9 005B 3400 00378 retlw B'00000000' ; right 12 displays 1,2 005C 3400 00379 retlw B'00000000' ; right 13 displays 1,3 005D 3400 00380 retlw B'00000000' ; right 14 displays 1,4 005E 3400 00381 retlw B'00000000' ; right 15 displays 1,5 00382 ; 00383 ; Execution starts here after reset 00384 ; 005F 0000 00385 Start nop 0060 1283 00386 bcf STATUS,RP0 ; point to low bank 0061 1303 00387 bcf STATUS,RP1 0062 0185 00388 clrf PORTA ; turn off power 0063 0186 00389 clrf PORTB ; Clear nixie ports 0064 0187 00390 clrf PORTC 0065 30C0 00391 movlw B'11000000' ; osc=rc, chan0, A/D disabled 0066 009F 00392 movwf ADCON0 00393 ; hi RAM 0067 1683 00394 bsf STATUS,RP0 ; point to high bank 0068 3084 00395 movlw B'10000100' ; TMR0 prescaler, 1:32 Message[302]: Register in operand not in bank 0. Ensure that bank bits are correct. 0069 0081 00396 movwf OPTION_REG 006A 3033 00397 movlw B'00110011' ; PORTA bits 2,3 output Message[302]: Register in operand not in bank 0. Ensure that bank bits are correct. 006B 0085 00398 movwf TRISA Message[302]: Register in operand not in bank 0. Ensure that bank bits are correct. 006C 0186 00399 clrf TRISB ; PORTB all outputs Message[302]: Register in operand not in bank 0. Ensure that bank bits are correct. 006D 0187 00400 clrf TRISC ; PORTC all outputs 006E 3005 00401 movlw B'00000101' ; Left justify, 2 analog channel 00402 ;msb movlw B'10000101' ; Right justify, 2 analog channel Message[302]: Register in operand not in bank 0. Ensure that bank bits are correct. 006F 009F 00403 movwf ADCON1 ; AN3 and VSS references 00404 ; low RAM 0070 1283 00405 bcf STATUS,RP0 ; point to low bank 0071 01A6 00406 clrf TMinD 0072 01A7 00407 clrf UMinD 0073 01A2 00408 clrf TMins 0074 01A3 00409 clrf UMins ; set mins,secs to :00:00 0075 01A4 00410 clrf TSecs 0076 01A5 00411 clrf USecs 0077 01A8 00412 clrf LDigit 0078 01A9 00413 clrf RDigit 0079 01B9 00414 clrf LBData 007A 01BA 00415 clrf LCData 007B 01BB 00416 clrf RBData MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 9 LOC OBJECT CODE LINE SOURCE TEXT VALUE 007C 01BC 00417 clrf RCData 007D 01AE 00418 clrf AdvHist 007E 01AB 00419 clrf SetHist 007F 01AF 00420 clrf TltHist 0080 01B0 00421 clrf Display 0081 01B1 00422 clrf DispTim 0082 01B2 00423 clrf XTilt 0083 01B3 00424 clrf YTilt 0084 3074 00425 movlw h'74' ;h'64' ; close to -0.65g 0085 00B5 00426 movwf XTLim45 0086 308C 00427 movlw h'8C' ;h'64' ; close to -0.65g 0087 00B6 00428 movwf YTLim45 0088 3018 00429 movlw h'18' ;h'C0' ; Y - X 0089 00B7 00430 movwf DTLim45 008A 218D 00431 call SetHr12 ; set to 12 hour mode 008B 01A0 00432 clrf THrs 008C 083F 00433 movfw FirstHr ; Set the hours to 00:00 or 1:00 008D 00A1 00434 movwf UHrs 008E 01BD 00435 clrf SetTim 008F 01AA 00436 clrf SetDig 0090 142A 00437 bsf SetDig,NotSet ; flag no setting going on 0091 01BE 00438 clrf TDTim 0092 01AD 00439 clrf TDDig 0093 142D 00440 bsf TDDig,NotTD ; turn off tilt display mode 00441 ; 00442 ; OffLoop follows tilt sequence, incs time, uses little power. 00443 ; 0094 2215 00444 OffLoop call WaitOff ; wait for 1/8 of second 0095 221A 00445 call DoTime ; update time variables 0096 211B 00446 call DoSet ; check for set button 0097 1C2A 00447 btfss SetDig,NotSet 0098 2909 00448 goto SetLoop ; Got to timesetting loop if setting 0099 20EF 00449 call DoTD ; check for Adv button 009A 1C2D 00450 btfss TDDig,NotTD 009B 28D9 00451 goto TDLoop ; goto tilt disp loop if Adv was pressed 009C 2249 00452 call GetTilt ; read sensor 009D 0AAF 00453 incf TltHist,f ; assume tilt is good 009E 2263 00454 call ChkT45 ; See if tilt is 45 yet 009F 1C03 00455 skpc ; good tilt 00A0 01AF 00456 clrf TltHist ; bad tilt, start over 00A1 3002 00457 movlw 2 ; test TltHist is 2 for good tilt 00A2 022F 00458 subwf TltHist,w 00A3 1D03 00459 skpz 00A4 2894 00460 goto OffLoop ; not good, do it all again 00461 ; 00462 ; Tilt sequence correct - turn on watch to show time 00463 ; 00A5 0AAF 00464 incf TltHist,f ; force another tilt to display again 00A6 2014 00465 call LdHrs ; get hours into display bytes 00A7 0822 00466 movfw TMins 00A8 00A6 00467 movwf TMinD ; save current minutes 00A9 0823 00468 movfw UMins ; so it won't show old hrs but new mins 00AA 00A7 00469 movwf UMinD MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 10 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00AB 1130 00470 bcf Display,LBlank ; disp both digits for now 00AC 11B0 00471 bcf Display,RBlank 00AD 301A 00472 NoHBlnk movlw HrsTim 00AE 00B1 00473 movwf DispTim ; set time to display hours 00AF 300C 00474 movlw PwrBlnk ; turn on HV but blank display 00B0 0085 00475 movwf PORTA 00B1 21F8 00476 call DispLpN ; display the hours 00B2 3030 00477 movlw PausTim 00B3 00B1 00478 movwf DispTim 00B4 2210 00479 HrMinLp call WtDigit ; pause between hrs, mins 00B5 0BB1 00480 decfsz DispTim,f 00B6 28B4 00481 goto HrMinLp 00B7 200E 00482 call LdMinD ; set display to saved minutes 00B8 3020 00483 movlw MinTim 00B9 00B1 00484 movwf DispTim ; set time to disp minutes 00BA 21F8 00485 call DispLpN ; display the minutes 00BB 3030 00486 movlw PausTim 00BC 00B1 00487 movwf DispTim 00BD 2210 00488 MinScLp call WtDigit ; pause between mins, secs 00BE 0BB1 00489 decfsz DispTim,f 00BF 28BD 00490 goto MinScLp 00C0 3014 00491 movlw SecTim 00C1 00C4 00492 movwf SecCnt ; set timeout for seconds display 00493 ; 00494 ; loop for seconds display till duty cycle reaches zero 00495 ; 00C2 1D0B 00496 SecLp btfss INTCON,T0IF ; test timer overflow 00C3 28C2 00497 goto SecLp ; loop till set (top of second) 00C4 221A 00498 call DoTime ; update time variables 00C5 2249 00499 call GetTilt ; read sensor 00C6 2263 00500 call ChkT45 ; See if tilt is still good 00C7 1C03 00501 skpc ; good tilt, do another second 00C8 28CF 00502 goto PwrDown ; bad tilt, exit seconds display 00C9 2002 00503 call LdSecs ; update seconds value to display 00CA 0844 00504 movfw SecCnt ; duty cycle is remaining loop index 00CB 00B1 00505 movwf DispTim ; set time to display them 00CC 21F8 00506 call DispLpN ; display the seconds 00CD 0BC4 00507 decfsz SecCnt,f ; count down seconds display timeout 00CE 28C2 00508 goto SecLp ; still active, do another second 00509 ; 00510 ; Finish up time display 00511 ; 00CF 0186 00512 PwrDown clrf PORTB ; shut off nixies 00D0 0187 00513 clrf PORTC 00D1 0185 00514 clrf PORTA ; turn off power 00D2 3006 00515 movlw HangTim 00D3 00B1 00516 movwf DispTim ; set up holdoff timer 00D4 2215 00517 HangLp call WaitOff 00D5 221A 00518 call DoTime 00D6 0BB1 00519 decfsz DispTim,f ; kill time between displayings 00D7 28D4 00520 goto HangLp 00D8 2894 00521 goto OffLoop ; ready to display again 00522 ; MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 11 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00523 ; TDispLp - diagnostic display of tilt values 00524 ; 00525 ; TDispLp displays X or Y tilt in hexadecimal on the nixies 00526 ; continuously for test purposes. 00527 ; It reads the tilt 2 times a second and updates the display at this 00528 ; rate. Power is shut down for tilt reading, causes display to wink. 00529 ; 00530 ; TDispLp is entered from OffLp when Adv button is pushed, 00531 ; causing TiltDig to be advanced to XTDisp. Adv steps through modes: 00532 ; off -> XTilt -> YTilt -> Done 00533 ; 00D9 00534 TDLoop 00D9 221A 00535 call DoTime ; keep timekeeping up to date 00DA 2249 00536 call GetTilt ; read tilt sensor 00DB 300C 00537 movlw PwrBlnk ; turn on HV but blank display 00DC 0085 00538 movwf PORTA 00DD 0832 00539 movfw XTilt 00DE 192D 00540 btfsc TDDig,YTDisp ; use Y instead of X when in Y mode 00DF 0833 00541 movfw YTilt 00E0 00A8 00542 movwf LDigit ; MSBs into left digit 00E1 0EA8 00543 swapf LDigit,f ; move MSBs to LSBs of left digit 00E2 00A9 00544 movwf RDigit ; LSBs to right digit 00E3 201A 00545 call LdDigs ; write digits to tubes 00E4 1130 00546 bcf Display,LBlank ; disp both digits 00E5 11B0 00547 bcf Display,RBlank 00E6 300E 00548 movlw TiltTim ; set time to display it 00E7 00B1 00549 movwf DispTim 00E8 21F8 00550 call DispLpN ; display tilt but don't check buttons 00E9 3000 00551 movlw PwrOff ; turn off HV 00EA 0085 00552 movwf PORTA 00EB 20EF 00553 call DoTD ; process Adv button for tilt modes 00EC 1C2D 00554 btfss TDDig,NotTD ; exit this loop if out of tdisp mode 00ED 28D9 00555 goto TDLoop ; pushed, so do it again 00EE 2894 00556 goto OffLoop ; else go back to being a clock 00557 ; 00558 ; DoTD detects if the Adv button is pushed, and debounces. 00559 ; If it's time for action, it sequences through the tilt display modes. 00560 ; 00EF 1E85 00561 DoTD btfss PORTA,AdvButt ; read the button - 0 is pushed 00F0 28F6 00562 goto IsTD 00F1 01AC 00563 clrf TDHist ; button not pressed - clear history 00F2 08BE 00564 tstf TDTim ; timed out? 00F3 1903 00565 skpnz 00F4 2905 00566 goto DoneT ; yes, turn off tilt display mode 00F5 2908 00567 goto NoTD 00F6 0AAC 00568 IsTD incf TDHist,f ; it is pushed - bump history counter 00F7 3004 00569 movlw 4 00F8 022C 00570 subwf TDHist,w 00F9 1903 00571 skpnz ; make hist stick at 4 to prevent autorepeat 00FA 03AC 00572 decf TDHist,f 00FB 3001 00573 GotTD movlw 1 00FC 022C 00574 subwf TDHist,w ; debounce time is 1 loop 00FD 1D03 00575 skpz MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 12 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00FE 2908 00576 goto NoTD 00FF 300F 00577 movlw TDTOut ; load tilt display timeout counter 0100 00BE 00578 movwf TDTim 0101 1003 00579 clrc 0102 0DAD 00580 rlf TDDig,f ; bump to next setting mode 0103 1DAD 00581 btfss TDDig,DoneTD ; are we done tilt displaying? 0104 2908 00582 goto NoTD 0105 01AD 00583 DoneT clrf TDDig ; turn off tilt display mode 0106 142D 00584 bsf TDDig,NotTD 0107 01BE 00585 clrf TDTim ; clear timeout counter 0108 0008 00586 NoTD return 00587 ; 00588 ; -------------------------------------------------------- 00589 ; 00590 ; Time setting code 00591 ; 00592 ; Setting procedure: 00593 ; 00594 ; Hold Set button till display lights, then release. 00595 ; Display is unblinking '12' or '24', indicating hours mode. 00596 ; Press Adv button to toggle between 12 hour and 24 hour modes. 00597 ; Press Set button and release. 00598 ; Both digits of Hours will flash. 00599 ; Press Adv button once per increment to set hours. 00600 ; Press Set button and release. 00601 ; Tens of Minutes will flash, units will be solid. 00602 ; Press Adv button once per increment to set tens minutes. 00603 ; Press Set button and release. 00604 ; Units of Minutes will flash, tens will be solid. 00605 ; Press Adv button once per increment to set units minutes. 00606 ; Press Set button and release. 00607 ; Display is incrementing seconds. 00608 ; Press Adv button once to reset seconds to 00. 00609 ; Press Set button and release. 00610 ; Display is unblinking '45'. 00611 ; Hold watch at best viewing angle, typically 45 degrees. 00612 ; Press Adv button to save tilt angle. Display will flash once. 00613 ; Press Set button and release. 00614 ; Display will blank. Setting is done. 00615 ; 00616 ; Set & Adv buttons are sampled once per mux iteration. 00617 ; Each button must be pressed then released for each action. 00618 00619 ; SetLoop is entered from OffLp when Set button is pushed, 00620 ; causing SetDig to be advanced to HrsSet. 00621 ; 00622 ; The setting state machine keeps its state in SetDig. 00623 ; SetHist is a count of how long the Set button has been held down. 00624 ; When the buton has been hjeld down long enough to debounce, then 00625 ; the state machine is advanced to the next state and the necessary 00626 ; variables are updated to make the display show the right stuff for 00627 ; that mode. Similarly, the Adv button's time pressed is AdvHist. 00628 ; When Adv is pressed, the appropriate vairable is incremented and MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 13 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00629 ; the display variables are updated. 00630 ; 00631 ; Display time with blinking digits, read buttons and act on them. 00632 ; 0109 300C 00633 SetLoop movlw BlnkTim ; set display duration 010A 00B1 00634 movwf DispTim 010B 1130 00635 bcf Display,LBlank ; Enable display for on phase of blink 010C 11B0 00636 bcf Display,RBlank 010D 21DE 00637 call DispLp ; Do display, read buttons 010E 300C 00638 movlw BlnkTim 010F 00B1 00639 movwf DispTim ; set duration 0110 1830 00640 btfsc Display,LBlink ; set L blanking flag per blink request 0111 1530 00641 bsf Display,LBlank 0112 18B0 00642 btfsc Display,RBlink ; set R blanking flag per blink request 0113 15B0 00643 bsf Display,RBlank 0114 21DE 00644 call DispLp ; do display, read buttons 0115 1C2A 00645 btfss SetDig,NotSet 0116 2909 00646 goto SetLoop ; loop if still setting 0117 0186 00647 clrf PORTB ; shut off nixies 0118 0187 00648 clrf PORTC 0119 0185 00649 clrf PORTA ; turn off power 011A 2894 00650 goto OffLoop 00651 ; 00652 ; DoSet detects if the Set button is pushed, and debounces. 00653 ; If it's time for action, it selects the digit being set in the order: 00654 ; 00655 ; This routine sets up the display mode to match the set function. 00656 ; 011B 1E05 00657 DoSet btfss PORTA,SetButt ; read the button - 0 is pushed 011C 2922 00658 goto IsSet 011D 01AB 00659 clrf SetHist ; button not pressed - clear history 011E 08BD 00660 tstf SetTim ; timed out? 011F 1903 00661 skpnz 0120 2961 00662 goto DoneS ; yes, turn off timesetting mode 0121 2967 00663 goto NoSet 0122 0AAB 00664 IsSet incf SetHist,f ; it is pushed - bump history counter 0123 3004 00665 movlw 4 0124 022B 00666 subwf SetHist,w 0125 1903 00667 skpnz ; make hist stick at 4 to prevent autorepeat 0126 03AB 00668 decf SetHist,f 0127 3002 00669 GotSet movlw 2 0128 022B 00670 subwf SetHist,w ; debounce time is 2 loops ~=40 millisec 0129 1D03 00671 skpz 012A 2967 00672 goto NoSet 012B 3040 00673 movlw SetTOut ; load time setting timeout counter 012C 00BD 00674 movwf SetTim 012D 1003 00675 clrc 012E 0DAA 00676 rlf SetDig,f ; bump to next setting mode 012F 18AA 00677 btfsc SetDig,H24Set ; is it 12/24 hour mode? 0130 293D 00678 goto H24S 0131 192A 00679 btfsc SetDig,HrsSet ; is it hours? 0132 2949 00680 goto HrsS 0133 19AA 00681 btfsc SetDig,TMinSet ; is it tens of minutes? MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 14 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0134 294D 00682 goto TMinS 0135 1A2A 00683 btfsc SetDig,UMinSet ; is it units of minutes? 0136 2951 00684 goto UMinS 0137 1AAA 00685 btfsc SetDig,SecSet ; is it seconds? 0138 2955 00686 goto SecS 0139 1B2A 00687 btfsc SetDig,T45Set ; is it tilt? 013A 2959 00688 goto Tilt45S 013B 1BAA 00689 btfsc SetDig,DoneSet ; are we done setting? 013C 2961 00690 goto DoneS 00691 ; 00692 ; Enter H24 setting mode 00693 ; 00694 ; This routine turns on the display when timesetting mode is entered. 00695 ; 013D 300C 00696 H24S movlw PwrBlnk ; turn on HV but blank display 013E 0085 00697 movwf PORTA 013F 0000 00698 nop 0140 0000 00699 nop 0141 0842 00700 movfw DispHrT ; get mode display value 0142 00A8 00701 movwf LDigit ; into display digits 0143 0843 00702 movfw DispHrU 0144 00A9 00703 movwf RDigit 0145 201A 00704 call LdDigs ; load it into disp storage 0146 1030 00705 bcf Display,LBlink ; no blinking 0147 10B0 00706 bcf Display,RBlink 0148 2967 00707 goto NoSet 00708 ; 00709 ; Enter Hours setting mode 00710 ; 0149 2014 00711 HrsS call LdHrs ; copy current hours into disp digits 014A 1430 00712 bsf Display,LBlink ; blink both digits 014B 14B0 00713 bsf Display,RBlink 014C 2967 00714 goto NoSet 00715 ; 00716 ; Enter TMins setting mode 00717 ; 014D 2008 00718 TMinS call LdMins ; copy current mins into disp digits 014E 1430 00719 bsf Display,LBlink ; blink only left digit 014F 10B0 00720 bcf Display,RBlink 0150 2967 00721 goto NoSet 00722 ; 00723 ; Enter UMins setting mode 00724 ; 0151 2008 00725 UMinS call LdMins ; load minutes into disp storage 0152 1030 00726 bcf Display,LBlink ; blink only right digit 0153 14B0 00727 bsf Display,RBlink 0154 2967 00728 goto NoSet 00729 ; 00730 ; Enter Secs setting mode 00731 ; 0155 2002 00732 SecS call LdSecs ; load seconds into disp storage 0156 1030 00733 bcf Display,LBlink ; No blink, but display advances 0157 10B0 00734 bcf Display,RBlink ; via code at TimeRet. MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 15 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0158 2967 00735 goto NoSet 00736 ; 00737 ; Enter Tilt45 setting mode 00738 ; 0159 3004 00739 Tilt45S movlw h'4' ; get a '45' for display 015A 00A8 00740 movwf LDigit 015B 3005 00741 movlw h'5' 015C 00A9 00742 movwf RDigit 015D 201A 00743 call LdDigs ; load it into disp storage 015E 1030 00744 bcf Display,LBlink ; no blinking 015F 10B0 00745 bcf Display,RBlink 0160 2967 00746 goto NoSet 00747 ; 00748 ; Finish up when exiting set mode 00749 ; 0161 01AA 00750 DoneS clrf SetDig ; leave setting mode 0162 142A 00751 bsf SetDig,NotSet 0163 01BD 00752 clrf SetTim ; clear timeout counter 0164 0186 00753 clrf PORTB 0165 0187 00754 clrf PORTC 0166 0185 00755 clrf PORTA ; Shut off display 0167 0008 00756 NoSet return 00757 ; 00758 ; DoAdv processes the Adv button. If it's pushed, we debounce 00759 ; via AdvHist. When it's time to advance the clock setting, 00760 ; the appropriate digit(s) are incremented without carrying into other 00761 ; digits. 00762 ; 0168 1E85 00763 DoAdv btfss PORTA,AdvButt ; read the button - 0 is pushed 0169 296C 00764 goto IsAdv 016A 01AE 00765 clrf AdvHist ; button not pressed - clear history 016B 2981 00766 goto AdvDone 016C 0AAE 00767 IsAdv incf AdvHist,f ; it is pushed - bump history counter 016D 3004 00768 movlw 4 016E 022E 00769 subwf AdvHist,w 016F 1903 00770 skpnz ; make hist stick at 4 to prevent autorepeat 0170 03AE 00771 decf AdvHist,f 0171 3002 00772 GotAdv movlw 2 0172 022E 00773 subwf AdvHist,w ; debounce time is 2 loops ~=40 millisec 0173 1D03 00774 skpz 0174 2981 00775 goto AdvDone 0175 18AA 00776 btfsc SetDig,H24Set ; is it 12/24 hour mode? 0176 2982 00777 goto H24A 0177 192A 00778 btfsc SetDig,HrsSet ; is it hours? 0178 29A5 00779 goto HrsA 0179 19AA 00780 btfsc SetDig,TMinSet ; is it Tenmins? 017A 29A8 00781 goto TMinA 017B 1A2A 00782 btfsc SetDig,UMinSet ; is it UnitsMins? 017C 29AF 00783 goto UMinA 017D 1AAA 00784 btfsc SetDig,SecSet ; is it seconds? 017E 29B6 00785 goto SecA 017F 1B2A 00786 btfsc SetDig,T45Set ; is it Tilt at 45? 0180 29BB 00787 goto Tilt45A MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 16 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0181 0008 00788 AdvDone return ; Nothing to do so return 00789 ; 00790 ; toggle 12/24 hour mode 00791 ; 0182 1FB0 00792 H24A btfss Display,Hrs24 ; In 24 hour mode? 0183 2986 00793 goto H24No 0184 218D 00794 call SetHr12 ; yes, go from 24 to 12 hour mode 0185 2987 00795 goto H24Got 0186 2199 00796 H24No call SetHr24 ; else go from 12 to 24 hour mode 0187 0842 00797 H24Got movfw DispHrT ; get mode display value 0188 00A8 00798 movwf LDigit ; into display digits 0189 0843 00799 movfw DispHrU 018A 00A9 00800 movwf RDigit 018B 201A 00801 call LdDigs ; load it into disp storage 018C 2981 00802 goto AdvDone 00803 ; 00804 ; Set timekeeping to 12 hour mode 00805 ; 018D 3001 00806 SetHr12 movlw FHr12 ; Set up for 12 hour mode 018E 00BF 00807 movwf FirstHr 018F 3001 00808 movlw LHrT12 0190 00C0 00809 movwf LastHrT 0191 3003 00810 movlw LHrU12 0192 00C1 00811 movwf LastHrU 0193 3001 00812 movlw DHrT12 0194 00C2 00813 movwf DispHrT 0195 3002 00814 movlw DHrU12 0196 00C3 00815 movwf DispHrU 0197 13B0 00816 bcf Display,Hrs24 0198 0008 00817 return 00818 ; 00819 ; Set timekeeping to 24 hour mode 00820 ; 0199 3000 00821 SetHr24 movlw FHr24 ; Set up for 24 hour mode 019A 00BF 00822 movwf FirstHr 019B 3002 00823 movlw LHrT24 019C 00C0 00824 movwf LastHrT 019D 3004 00825 movlw LHrU24 019E 00C1 00826 movwf LastHrU 019F 3002 00827 movlw DHrT24 01A0 00C2 00828 movwf DispHrT 01A1 3004 00829 movlw DHrU24 01A2 00C3 00830 movwf DispHrU 01A3 17B0 00831 bsf Display,Hrs24 01A4 0008 00832 return 00833 ; 00834 ; Advance hours 00835 ; 01A5 21CA 00836 HrsA call IncHrs ; increment hours (messy) 01A6 2014 00837 call LdHrs ; copy new hours into disp digits 01A7 2981 00838 goto AdvDone 00839 ; 00840 ; Advance tens of minutes MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 17 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00841 ; 01A8 0AA2 00842 TMinA incf TMins,f ; increment tens of minutes 01A9 3006 00843 movlw 6 01AA 0222 00844 subwf TMins,w ; did it hit 6? 01AB 1903 00845 skpnz 01AC 01A2 00846 clrf TMins ; yes, wrap from 5 to 0 01AD 2008 00847 call LdMins ; copy new minutes into disp digits 01AE 2981 00848 goto AdvDone 00849 ; 00850 ; Advance units minutes 00851 ; 01AF 0AA3 00852 UMinA incf UMins,f ; increment units of minutes 01B0 300A 00853 movlw h'A' 01B1 0223 00854 subwf UMins,w ; did it hit 10? 01B2 1903 00855 skpnz 01B3 01A3 00856 clrf UMins ; yes, wrap from 10 to 0 01B4 2008 00857 call LdMins ; copy new minutes into disp digits 01B5 2981 00858 goto AdvDone 00859 ; 00860 ; Reset seconds 00861 ; 01B6 01A4 00862 SecA clrf TSecs ; Set seconds to 0 01B7 01A5 00863 clrf USecs 01B8 0181 00864 clrf TMR0 ; set sub-seconds to 0 01B9 2002 00865 call LdSecs ; copy new seconds into disp digits 01BA 2981 00866 goto AdvDone 00867 ; 00868 ; Capture and save 45 deg tilt angle 00869 ; 01BB 3000 00870 Tilt45A movlw PwrOff 01BC 0085 00871 movwf PORTA ; cut off power now for stability 01BD 2215 00872 call WaitOff ; pause to flash display 01BE 2249 00873 call GetTilt ; find out current tilt angle 01BF 3001 00874 movlw XTMargin ; Get X tilt + XTMargin 01C0 0732 00875 addwf XTilt,w 01C1 00B5 00876 movwf XTLim45 ; save as X limit 01C2 30FF 00877 movlw YTMargin ; Get Y tilt + YTMargin 01C3 0733 00878 addwf YTilt,w 01C4 00B6 00879 movwf YTLim45 ; save as Y limit 01C5 0832 00880 movfw XTilt ; Get Y tilt - X tilt 01C6 0233 00881 subwf YTilt,w 01C7 00B7 00882 movwf DTLim45 ; save as D limit 01C8 03B7 00883 decf DTLim45,f ; make it Y - X - 1 01C9 2981 00884 goto AdvDone 00885 ; 00886 ; IncHrs increments the hours which is an ugly process 00887 ; (but it only happens once an hour, so what, me worry?) 00888 ; 01CA 0AA1 00889 IncHrs incf UHrs,f ; bump units hours 01CB 0840 00890 movfw LastHrT 01CC 0220 00891 subwf THrs,w ; Tens at last hour? 01CD 1D03 00892 skpz 01CE 29D7 00893 goto NoHWrap ; no, do carry MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 18 LOC OBJECT CODE LINE SOURCE TEXT VALUE 01CF 0841 00894 movfw LastHrU 01D0 0221 00895 subwf UHrs,w ; Units at last hour? 01D1 1D03 00896 skpz 01D2 29D7 00897 goto NoHWrap ; no, do carry 01D3 083F 00898 movfw FirstHr 01D4 00A1 00899 movwf UHrs ; yes, reset hours to 1 or 0 o'clock 01D5 0103 00900 clrw 01D6 00A0 00901 movwf THrs 01D7 300A 00902 NoHWrap movlw h'A' 01D8 0221 00903 subwf UHrs,w ; did it hit 10? 01D9 1D03 00904 skpz 01DA 29DD 00905 goto NoHrC 01DB 01A1 00906 clrf UHrs ; yes, wrap from 10 to 0 01DC 0AA0 00907 incf THrs,f ; and bump tens 01DD 0008 00908 NoHrC return 00909 ; 00910 ;-------------------------------------------------------- 00911 ; Display loop 00912 ; 00913 ; DispLp displays the cathodes stored in [L,R][B,C]Data. 00914 ; It uses the blanking bits LBlank and RBlank per digit. 00915 ; It runs for DispTim then returns. 00916 ; Also calls Set and Adv button routines for timesetting mode. 00917 ; 00918 ; This routine does multiplexing by lighting first left digit then right. 00919 ; 00920 ; Entered and returns with display dark via TiltEn bit of Port A 00921 ; Also clears Ports B and C to ensure blankness 00922 ; 01DE 221A 00923 DispLp call DoTime ; update time variables 01DF 0839 00924 movfw LBData 01E0 0086 00925 movwf PORTB ; Set ports B and C to left cathode codes 01E1 083A 00926 movfw LCData 01E2 0087 00927 movwf PORTC 01E3 3004 00928 movlw PwrDisp 01E4 1D30 00929 btfss Display,LBlank ; blank this digit? 01E5 0085 00930 movwf PORTA ; not blanked so let HV go high 01E6 2210 00931 call WtDigit ; Wait for it to display 01E7 211B 00932 call DoSet ; process the Set button while lit 01E8 300C 00933 movlw PwrBlnk 01E9 0085 00934 movwf PORTA ; blank display while changing cathodes 01EA 083B 00935 movfw RBData 01EB 0086 00936 movwf PORTB ; Set ports B and C to right cathode codes 01EC 083C 00937 movfw RCData 01ED 0087 00938 movwf PORTC 01EE 3004 00939 movlw PwrDisp 01EF 1DB0 00940 btfss Display,RBlank ; blank this digit? 01F0 0085 00941 movwf PORTA ; not blanked so let HV go high 01F1 2210 00942 call WtDigit ; Wait for it to display 01F2 2168 00943 call DoAdv ; process the Adv button while other digit lit 01F3 300C 00944 movlw PwrBlnk 01F4 0085 00945 movwf PORTA ; blank via HV control from TiltPwr 01F5 0BB1 00946 decfsz DispTim,f MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 19 LOC OBJECT CODE LINE SOURCE TEXT VALUE 01F6 29DE 00947 goto DispLp ; do it till count expires 01F7 0008 00948 return 00949 ; 00950 ; This version doesn't call DoSet or DoAdv. It's used for normal display. 00951 ; 01F8 221A 00952 DispLpN call DoTime ; update time variables 01F9 0839 00953 movfw LBData 01FA 0086 00954 movwf PORTB ; Set ports B and C to left cathode codes 01FB 083A 00955 movfw LCData 01FC 0087 00956 movwf PORTC 01FD 3004 00957 movlw PwrDisp 01FE 1D30 00958 btfss Display,LBlank ; blank this digit? 01FF 0085 00959 movwf PORTA ; not blanked so let HV go high 0200 2210 00960 call WtDigit ; Wait for it to display 0201 300C 00961 movlw PwrBlnk 0202 0085 00962 movwf PORTA ; blank display while changing cathodes 0203 083B 00963 movfw RBData 0204 0086 00964 movwf PORTB ; Set ports B and C to right cathode codes 0205 083C 00965 movfw RCData 0206 0087 00966 movwf PORTC 0207 3004 00967 movlw PwrDisp 0208 1DB0 00968 btfss Display,RBlank ; blank this digit? 0209 0085 00969 movwf PORTA ; not blanked so let HV go high 020A 2210 00970 call WtDigit ; Wait for it to display 020B 300C 00971 movlw PwrBlnk 020C 0085 00972 movwf PORTA ; blank via HV control from TiltPwr 020D 0BB1 00973 decfsz DispTim,f 020E 29F8 00974 goto DispLpN ; do it till count expires 020F 0008 00975 return 00976 ; 00977 ; WtDigit delays for one digit time - about six milliseconds 00978 ; 00979 ; Destroys W 00980 ; 0210 300A 00981 WtDigit movlw DigTim ; get constant delay number 0211 00B8 00982 movwf TimLeft ; copy to local storage 0212 0BB8 00983 WtLoop1 decfsz TimLeft,f 0213 2A12 00984 goto WtLoop1 ; loop that many times 0214 0008 00985 return 00986 ; 00987 ; WaitOff delays for about 1/8 second while power is off 00988 ; 00989 ; Destroys W 00990 ; 0215 30C0 00991 WaitOff movlw OffTim ; get constant delay number 0216 00B8 00992 movwf TimLeft ; copy to local storage 0217 0BB8 00993 WtOff1 decfsz TimLeft,f 0218 2A17 00994 goto WtOff1 ; loop that many times 0219 0008 00995 return 00996 ; 00997 ; DoTime checks timer, updates time vars accordingly 00998 ; 00999 ; The timer is set up to overflow once per second. This routine is called MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 20 LOC OBJECT CODE LINE SOURCE TEXT VALUE 01000 ; several times a second to poll the timer status to detect an overflow. 01001 ; If hte timer overflows, the overflow bit is reset and the time variables 01002 ; are incremented according to standard clock behavior. 01003 ; 01004 ; The reason that interrupts are not used is that the display flickers 01005 ; when the interrupt occurrs. Been there, done that. 01006 ; 021A 1D0B 01007 DoTime btfss INTCON,T0IF ; test timer overflow 021B 2A3C 01008 goto TimeNop ; no overflow, do nothing (equalize time) 021C 110B 01009 bcf INTCON,T0IF ; reset overflow flag 021D 08BD 01010 tstf SetTim ; Setting mode? 021E 1D03 01011 skpz 021F 03BD 01012 decf SetTim,f ; Yes, count down setting time left 0220 08BE 01013 tstf TDTim ; Tilt display mode? 0221 1D03 01014 skpz 0222 03BE 01015 decf TDTim,f ; Yes, count down display time left 0223 0AA5 01016 incf USecs,f ; bump units seconds 0224 300A 01017 movlw h'A' ; ten second overflow? 0225 0225 01018 subwf USecs,w 0226 1D03 2A46 01019 bnz TimeRet ; no, return 0228 01A5 01020 clrf USecs 0229 0AA4 01021 incf TSecs,f ; bump tens seconds 022A 3006 01022 movlw h'6' ; Minute overflow? 022B 0224 01023 subwf TSecs,w 022C 1D03 2A46 01024 bnz TimeRet ; no, return 022E 01A4 01025 clrf TSecs 022F 0AA3 01026 incf UMins,f ; bump units minutes 0230 300A 01027 movlw h'A' ; ten minute overflow? 0231 0223 01028 subwf UMins,w 0232 1D03 2A46 01029 bnz TimeRet ; no, return 0234 01A3 01030 clrf UMins 0235 0AA2 01031 incf TMins,f ; bump tens minutes 0236 3006 01032 movlw h'6' ; hourly overflow? 0237 0222 01033 subwf TMins,w 0238 1D03 2A46 01034 bnz TimeRet ; no, return 023A 01A2 01035 clrf TMins 023B 21CA 01036 call IncHrs ; bump the hour by one 023C 0000 01037 TimeNop nop 023D 0000 01038 nop ; equalize timing of routine to 023E 0000 01039 nop ; prevent display glitch once per second 023F 0000 01040 nop 0240 0000 01041 nop 0241 0000 01042 nop 0242 0000 01043 nop 0243 0000 01044 nop 0244 0000 01045 nop 0245 0000 01046 nop 0246 1AAA 01047 TimeRet btfsc SetDig,SecSet ; If we're setting seconds, update display 0247 2802 01048 goto LdSecs 0248 0008 01049 return 01050 ; 01051 ; Read the tilt sensor. 01052 ; Results are placed in XTilt and YTilt. MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 21 LOC OBJECT CODE LINE SOURCE TEXT VALUE 01053 ; 01054 ; Disp, Tilt power is turned off by this routine. 01055 ; 01056 ; Sensor needs 2 milliseconds from TiltPwr on to first A/D conversion. 01057 ; Code is interleaved to minimize power-on time of tilt sensor, 01058 ; which uses 300 uA. This saves battery drain. 01059 ; 01060 ; The remnants are from an attempt to use higher resolution on the ADC. 01061 ; It needed all 10 bits, so I didn't bother. Seems to work as is. 01062 ; 0249 3008 01063 GetTilt movlw PwrTilt ; turn on tilt sensor power 024A 0085 01064 movwf PORTA 024B 141F 01065 bsf ADCON0,ADON ; turn on the A/D converter module 024C 119F 01066 bcf ADCON0,CHS0 ; select A/D channel 0 = X 024D 0000 01067 nop 024E 0000 01068 nop ; wait one millisecond 024F 0000 01069 nop 0250 0000 01070 nop 0251 0000 01071 nop 0252 0000 01072 nop 0253 0000 01073 nop 0254 0000 01074 nop 0255 151F 01075 bsf ADCON0,GO ; Start A/D conversion at 2 milliseconds 0256 0000 01076 nop ; Wait for X conversion to complete 0257 159F 01077 bsf ADCON0,CHS0 ; select A/D channel 1 = Y 0258 081E 01078 movfw ADRESH ; get X tilt from A/D (use 8 MSBs) 01079 ;msb bsf STATUS,RP0 ; point to high bank 01080 ;msb movfw ADRESL ; get X tilt from A/D (use 8 LSBs) 01081 ;msb bcf STATUS,RP0 ; point to low bank 0259 00B2 01082 movwf XTilt ; save X tilt 025A 151F 01083 bsf ADCON0,GO ; Start second A/D conversion 025B 0000 01084 nop ; Wait for Y conversion to complete 025C 0000 01085 nop ; Wait for Y conversion to complete 025D 081E 01086 movfw ADRESH ; get Y tilt 01087 ;msb bsf STATUS,RP0 ; point to high bank 01088 ;msb movfw ADRESL ; get Y tilt 01089 ;msb bcf STATUS,RP0 ; point to low bank 025E 00B3 01090 movwf YTilt ; save Y tilt 025F 3000 01091 movlw PwrOff ; turn off tilt sensor power 0260 0085 01092 movwf PORTA 0261 101F 01093 bcf ADCON0,ADON ; turn off the A/D converter module 0262 0008 01094 return 01095 ; 01096 ; ChkT45 See if tilted to 45 degrees 01097 ; 01098 ; Returns NC if not tilted right, 01099 ; returns C if tilted right. 01100 ; 01101 ; We want: 01102 ; (YTilt - XTilt) > DTLim45 (h'18') 01103 ; XTilt < XTLim45 (h'74' ~-0.65g) 01104 ; YTilt > YTLim45 (h'8C' ~+0.65g) 01105 ; MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 22 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0263 0832 01106 ChkT45 movfw XTilt 0264 0233 01107 subwf YTilt,w 0265 00B4 01108 movwf DTilt ; calc YTilt - XTilt -> DTilt 0266 0837 01109 movfw DTLim45 0267 0234 01110 subwf DTilt,w ; D tilt minus D lim, pos is good tilt 0268 1C03 01111 skpc ; NC is bad 0269 2A70 01112 goto CT45Don ; bad Y-X tilt 026A 0832 01113 movfw XTilt 026B 0235 01114 subwf XTLim45,w ; X lim minus X tilt, pos is good tilt 026C 1C03 01115 skpc ; NC is bad 026D 2A70 01116 goto CT45Don ; bad X tilt 026E 0836 01117 movfw YTLim45 026F 0233 01118 subwf YTilt,w ; Y tilt minus Y lim, pos is good tilt 0270 0008 01119 CT45Don return ; NC is bad, C is good 01120 01121 end ; end of file MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 23 SYMBOL TABLE LABEL VALUE ACKDT 00000005 ACKEN 00000004 ACKSTAT 00000006 ADCON0 0000001F ADCON1 0000009F ADCS0 00000006 ADCS1 00000007 ADFM 00000007 ADIE 00000006 ADIF 00000006 ADON 00000000 ADRESH 0000001E ADRESL 0000009E AdvButt 00000005 AdvDone 00000181 AdvHist 0000002E BCLIE 00000003 BCLIF 00000003 BF 00000000 BLeft 00000027 BRight 0000003B BlnkTim 0000000C C 00000000 CCP1CON 00000017 CCP1IE 00000002 CCP1IF 00000002 CCP1M0 00000000 CCP1M1 00000001 CCP1M2 00000002 CCP1M3 00000003 CCP1X 00000005 CCP1Y 00000004 CCPR1H 00000016 CCPR1L 00000015 CHS0 00000003 CHS1 00000004 CHS2 00000005 CKE 00000006 CKP 00000004 CLeft 00000031 CRight 0000004D CT45Don 00000270 ChkT45 00000263 D 00000005 DATA_ADDRESS 00000005 DC 00000001 DHrT12 00000001 DHrT24 00000002 DHrU12 00000002 DHrU24 00000004 DTLim45 00000037 DTilt 00000034 D_A 00000005 MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 24 SYMBOL TABLE LABEL VALUE DigTim 0000000A DispHrT 00000042 DispHrU 00000043 DispLp 000001DE DispLpN 000001F8 DispTim 00000031 Display 00000030 DoAdv 00000168 DoSet 0000011B DoTD 000000EF DoTime 0000021A DoneS 00000161 DoneSet 00000007 DoneT 00000105 DoneTD 00000003 EEADR 0000010D EEADRH 0000010F EECON1 0000018C EECON2 0000018D EEDATA 0000010C EEDATH 0000010E EEIE 00000004 EEIF 00000004 EEPGD 00000007 F 00000001 FHr12 00000001 FHr24 00000000 FSR 00000004 FirstHr 0000003F GCEN 00000007 GIE 00000007 GO 00000002 GO_DONE 00000002 GetTilt 00000249 GotAdv 00000171 GotSet 00000127 GotTD 000000FB H24A 00000182 H24Got 00000187 H24No 00000186 H24S 0000013D H24Set 00000001 HangLp 000000D4 HangTim 00000006 HrMinLp 000000B4 Hrs24 00000007 HrsA 000001A5 HrsS 00000149 HrsSet 00000002 HrsTim 0000001A I2C_DATA 00000005 I2C_READ 00000002 I2C_START 00000003 MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 25 SYMBOL TABLE LABEL VALUE I2C_STOP 00000004 INDF 00000000 INTCON 0000000B INTE 00000004 INTEDG 00000006 INTF 00000001 IRP 00000007 IncHrs 000001CA IsAdv 0000016C IsSet 00000122 IsTD 000000F6 LBData 00000039 LBlank 00000002 LBlink 00000000 LCData 0000003A LDigit 00000028 LHrT12 00000001 LHrT24 00000002 LHrU12 00000003 LHrU24 00000004 LastHrT 00000040 LastHrU 00000041 LdDigs 0000001A LdHrs 00000014 LdMinD 0000000E LdMins 00000008 LdSecs 00000002 MinScLp 000000BD MinTim 00000020 NOT_A 00000005 NOT_ADDRESS 00000005 NOT_BO 00000000 NOT_BOR 00000000 NOT_DONE 00000002 NOT_PD 00000003 NOT_POR 00000001 NOT_RBPU 00000007 NOT_T1SYNC 00000002 NOT_TO 00000004 NOT_W 00000002 NOT_WRITE 00000002 NoHBlnk 000000AD NoHWrap 000001D7 NoHrC 000001DD NoSet 00000167 NoTD 00000108 NotSet 00000000 NotTD 00000000 OPTION_REG 00000081 OffLoop 00000094 OffTim 000000C0 P 00000004 PCFG0 00000000 MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 26 SYMBOL TABLE LABEL VALUE PCFG1 00000001 PCFG2 00000002 PCFG3 00000003 PCL 00000002 PCLATH 0000000A PCON 0000008E PEIE 00000006 PEN 00000002 PIE1 0000008C PIE2 0000008D PIR1 0000000C PIR2 0000000D PORTA 00000005 PORTB 00000006 PORTC 00000007 PR2 00000092 PS0 00000000 PS1 00000001 PS2 00000002 PSA 00000003 PausTim 00000030 PwrBlnk 0000000C PwrDisp 00000004 PwrDown 000000CF PwrOff 00000000 PwrTilt 00000008 R 00000002 RBData 0000003B RBIE 00000003 RBIF 00000000 RBlank 00000003 RBlink 00000001 RCData 0000003C RCEN 00000003 RD 00000000 RDigit 00000029 READ_WRITE 00000002 RP0 00000005 RP1 00000006 RSEN 00000001 R_W 00000002 S 00000003 SEN 00000000 SMP 00000007 SSPADD 00000093 SSPBUF 00000013 SSPCON 00000014 SSPCON2 00000091 SSPEN 00000005 SSPIE 00000003 SSPIF 00000003 SSPM0 00000000 SSPM1 00000001 MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 27 SYMBOL TABLE LABEL VALUE SSPM2 00000002 SSPM3 00000003 SSPOV 00000006 SSPSTAT 00000094 STATUS 00000003 SecA 000001B6 SecCnt 00000044 SecLp 000000C2 SecS 00000155 SecSet 00000005 SecTim 00000014 SetButt 00000004 SetDig 0000002A SetHist 0000002B SetHr12 0000018D SetHr24 00000199 SetLoop 00000109 SetTOut 00000040 SetTim 0000003D Start 0000005F T0CS 00000005 T0IE 00000005 T0IF 00000002 T0SE 00000004 T1CKPS0 00000004 T1CKPS1 00000005 T1CON 00000010 T1INSYNC 00000002 T1OSCEN 00000003 T1SYNC 00000002 T2CKPS0 00000000 T2CKPS1 00000001 T2CON 00000012 T45Set 00000006 TDDig 0000002D TDHist 0000002C TDLoop 000000D9 TDTOut 0000000F TDTim 0000003E THrs 00000020 TMR0 00000001 TMR1CS 00000001 TMR1H 0000000F TMR1IE 00000000 TMR1IF 00000000 TMR1L 0000000E TMR1ON 00000000 TMR2 00000011 TMR2IE 00000001 TMR2IF 00000001 TMR2ON 00000002 TMinA 000001A8 TMinD 00000026 MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 28 SYMBOL TABLE LABEL VALUE TMinS 0000014D TMinSet 00000003 TMins 00000022 TOUTPS0 00000003 TOUTPS1 00000004 TOUTPS2 00000005 TOUTPS3 00000006 TRISA 00000085 TRISB 00000086 TRISC 00000087 TSecs 00000024 Tilt45A 000001BB Tilt45S 00000159 TiltTim 0000000E TiltX 00000001 TiltY 00000000 TimLeft 00000038 TimeNop 0000023C TimeRet 00000246 TltHist 0000002F UA 00000001 UHrs 00000021 UMinA 000001AF UMinD 00000027 UMinS 00000151 UMinSet 00000004 UMins 00000023 USecs 00000025 W 00000000 WCOL 00000007 WR 00000001 WREN 00000002 WRERR 00000003 WaitOff 00000215 WtDigit 00000210 WtLoop1 00000212 WtOff1 00000217 XTDisp 00000001 XTLim45 00000035 XTMargin 00000001 XTilt 00000032 YTDisp 00000002 YTLim45 00000036 YTMargin 000000FF YTilt 00000033 Z 00000002 _BODEN_OFF 00003FBF _BODEN_ON 00003FFF _CPD_OFF 00003FFF _CPD_ON 00003EFF _CP_ALL 00000FCF _CP_HALF 00001FDF _CP_OFF 00003FFF MPASM 03.70 Released NWRD.ASM 5-18-2005 22:47:05 PAGE 29 SYMBOL TABLE LABEL VALUE _CP_UPPER_256 00002FEF _DEBUG_OFF 00003FFF _DEBUG_ON 000037FF _HS_OSC 00003FFE _LP_OSC 00003FFC _LVP_OFF 00003F7F _LVP_ON 00003FFF _PWRTE_OFF 00003FFF _PWRTE_ON 00003FF7 _RC_OSC 00003FFF _WDT_OFF 00003FFB _WDT_ON 00003FFF _WRT_ENABLE_OFF 00003DFF _WRT_ENABLE_ON 00003FFF _XT_OSC 00003FFD __16F872 00000001 MEMORY USAGE MAP ('X' = Used, '-' = Unused) 0000 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0040 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0080 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 00C0 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0100 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0140 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0180 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 01C0 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0200 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0240 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX X--------------- All other memory blocks unused. Program Memory Words Used: 625 Program Memory Words Free: 1423 Errors : 0 Warnings : 0 reported, 0 suppressed Messages : 5 reported, 0 suppressed