1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; Program: DS18B20 Digital Thermometer with .1 Degree Increments ;
; Author: Jake Sutherland ;
; Start Date: Sunday 16th May 2010 ;
; Finish Date: Wednesday 20th October 2010 ;
; Comments: June 2011 Revised program ;
; ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LIST P=PIC16F628A
INCLUDE P16F628A.INC
__config _CP_OFF & DATA_CP_OFF & _LVP_OFF & _BODEN_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
errorlevel -302 ;Eliminate bank warning
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; PIC16F628A Microcontroller ;
; ____ ____ ;
; LED 7 Segment 10's CC VREF/AN2/RA2 -| 1 - 18 |- RA1/AN1 LED 7 Segment 1's CC ;
; LED 7 Segment 100's CC CPM1/AN3/RA3 -| 2 17 |- RA0/AN0 LED 7 Segment .1's CC ;
; DS18B20 I/O CMP2/T0CKI/RA4 -| 3 16 |- RA7/OSC1/CLKIN ;
; VPP/MCLR/RA5 -| 4 15 |- RA6/OSC2/CLKOUT ;
; VSS -| 5 14 |- VDD ;
; Segment DP INT/RB0 -| 6 13 |- RB7/T1OSC1/ICSPDAT Segment B ;
; Segment C DT/RX/RB1 -| 7 12 |- RB6/T1OSCO/T1CLKI/ICSPCLK Segment A ;
; Segment D CK/TX/RB2 -| 8 11 |- RB5 Segment F ;
; Segment E CCP1/RB3 -|_9____10_|- RB4/PGM Segment G ;
; ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CBLOCK H'20'
HUNS ; Jump pointer for Hundreds digit
TENS ; Jump pointer for Tens digit
ONES ; Jump pointer for Ones digit
DECI ; Jump pointer for Decimal digit
THOU_COL ; 7 Segment Display Thousands Column, used within ISR
HUNS_COL ; 7 Segment Display Hundreds Column, used within ISR
TENS_COL ; 7 Segment Display Tens Column, used within ISR
ONES_COL ; 7 Segment Display Ones Column, used within ISR
COLSEL ; Stores COLUMN SELECT information
DIGIT ; Used for Indirect Addressing in Interrupt Service Routine
TEMPLO_C ; BS18B20 Celsius Temperature Result Low Byte
TEMPHI_C ; BS18B20 Celsius Temperature Result High Byte
COUNT ; For counting execution times in various routines
SHIFT ; For storing data to shift into and out of the DS18B20
DELAYGPR1 ; Used in delay subroutines
FLAGS ; -------X Unused
; ------0- Celsius Temperature Negative Flag (0 = False 1 = True)
; -----X-- Unused
; ----X--- Unused
; ---X---- Unused
; --X----- Unused
; -X------ Unused
; X------- Unused
ENDC
W_ISR EQU H'70' ; For context saving. Ensures GPR is accesible from any Bank. See Memory Map of 628A
S_ISR EQU H'71' ; For context saving. Ensures GPR is accesible from any Bank. See Memory Map of 628A
P_ISR EQU H'72' ; For context saving. Ensures GPR is accesible from any Bank. See Memory Map of 628A
F_ISR EQU H'73' ; For context saving. Ensures GPR is accesible from any Bank. See Memory Map of 628A
ORG H'000' ; Processor reset vector location. On power up, the program jumps here
GOTO SETUP ;
ORG H'004' ; Interrupt vector location. When an Interupt occurs, the program jumps here
; (Thanks Mike, K8LH for help with this ISR routine. Contact via Electro-Tech-Online.com)
; Save
MOVWF W_ISR ; Save W to W_ISR
SWAPF STATUS, W ; Use SWAPF instruction so status bits don't change
MOVWF S_ISR ; Save Status to S_ISR
CLRF STATUS ; Switch to Bank 0
MOVF PCLATH, W ; Move PCLATH to W register
MOVWF P_ISR ; Save PCLATH to P_ISR
CLRF PCLATH ; Force page 0
MOVF FSR, W ; Move FSR to W register
MOVWF F_ISR ; Save FSR to F_ISR
; Refresh display
CLRF PORTB ; Blank the display
MOVF PORTA, W ; Move PORTA's current state to W
ANDLW B'11100000' ; Clear ONLY Column Select Bits & leave upper nibble unchanged
IORWF COLSEL, W ; Inclusive OR above with COLSEL register
MOVWF PORTA ; Leave upper nibble of PORTA unchanged & select new column
MOVF DIGIT, W ; Column number (DIGIT is initialised to 0. Used for Indirect Addressing)
ADDLW THOU_COL ; Add 'DIGIT' to 'THOU_COL' GPR address
MOVWF FSR ; FSR = THOU_COL + (0forTHOUS, 1forHUNS, 2forTENS & 3forONES) as they are in sequencial order in RAM
MOVF INDF, W ; W register now holds the jump pointer for the corresponding digit to be displayed
CALL SEGMENT_TABLE ; Get 7 segment arrangement from SEGMENT_TABLE for corresponding digit
BTFSC COLSEL, 1 ; Is TENS Column active
IORLW B'00000001' ; Yes, so activate TEN's column deciaml point
MOVWF PORTB ; NO, hide deciaml point and display new column
; Prepare for next column interrupt
INCF DIGIT, F ; Increment DIGIT jump pointer (used when indirect addressing above)
BCF STATUS, C ; Clear C bit of STATUS register
RRF COLSEL, F ; Advance column select bit
BTFSS STATUS,C ; Was that the last column? (or, Is Carry Flag Set?)
GOTO $+D'3' ; NO, do not reset DIGIT and COLumnSELect
CLRF DIGIT ; Reset DIGIT jump pointer
BSF COLSEL, 3 ; Reset column select to THOU_COL (1XXX) (00001000)
; RESTORE
BCF PIR1, TMR2IF ; Clear TMR2 interrupt flag while still in Bank 0
MOVF F_ISR, W ; MOVE F_ISR to W
MOVWF FSR ; Restore FSR
MOVF P_ISR, W ; MOVE P_ISR to W
MOVWF PCLATH ; Restore PCLATH
SWAPF S_ISR, W ; Undo previous SWAPF, place result in W
MOVWF STATUS ; Restore STATUS
SWAPF W_ISR, F ; Use SWAPF instruction so status bits don't change
SWAPF W_ISR, W ; Undo previous SWAPF and restore W register
RETFIE ; Return From Interrupt
; 7 Segment Display Arrangement Lookup
SEGMENT_TABLE ; This routine assigns on/off arrangement to the 7 Segment Display
ADDWF PCL, F
; BAFGEDCp JUMP B|A|F|G|E|D|C|p DISPLAY
RETLW B'11101110' ; 0 B|A|F|-|E|D|C|- 0
RETLW B'10000010' ; 1 B|-|-|-|-|-|C|- 1
RETLW B'11011100' ; 2 B|A|-|G|E|D|-|- 2
RETLW B'11010110' ; 3 B|A|-|G|-|D|C|- 3
RETLW B'10110010' ; 4 B|-|F|G|-|-|C|- 4
RETLW B'01110110' ; 5 -|A|F|G|-|D|C|- 5
RETLW B'01111110' ; 6 -|A|F|G|E|D|C|- 6
RETLW B'11000010' ; 7 B|A|-|-|-|-|C|- 7
RETLW B'11111110' ; 8 B|A|F|G|E|D|C|- 8
RETLW B'11110110' ; 9 B|A|F|G|-|D|C|- 9
RETLW B'00000000' ; 10 -|-|-|-|-|-|-|- BLANK
RETLW B'00010000' ; 11 -|-|-|G|-|-|-|- -
RETURN
; Program Orgiginates Here
SETUP ; This rountine sets up the Microcontroller's Inputs and Outputs
MOVLW H'07' ; Turn Comparators off and enable pins for I/O functions
MOVWF CMCON ;
BSF STATUS, RP0 ; Bank 1
MOVLW B'01010000' ; RA<7><5><3:0> Output, RA<6><4> Input
MOVWF TRISA ;
CLRF TRISB ; RB<7:0> Outputs
BCF STATUS, RP0 ; Bank 0
CLRF PORTA
CLRF PORTB
ONE_OFF_INITIALISE
; Clear ALL Bank 0 RAM from 0X20 - 0X7F (96 bytes)
BCF STATUS, IRP ; Indirect addressing Bank 0/1
MOVLW H'20' ; Initialise pointer to RAM
MOVWF FSR ; (File Select Register)
CLRF INDF ; Clear Register indirectly
INCF FSR, F ; Increment pointer
BTFSS FSR, 7 ; All done?
GOTO $-D'3' ; No, Clear next byte
; Initialise Column Select
BSF COLSEL, 3 ; Set column select to THOU_COL (1XXX) (00001000)
; Setup TMR2 for 0.0005s or 500uS Interrupts
CLRF TMR2 ; Clear TMR2 register
BSF STATUS, RP0 ; Bank 1
MOVLW B'00000010' ; 00000010
MOVWF PIE1 ; -------0 Disable TMR1IE - TMR1 Overflow Interrupt Enable bit
; ------1- Enable TMR2IE - TMR2 to PR2 Match Interrupt Enable bit
; -----0-- Disable CCP1IE - CCP1 Interrupt Enable bit
; ----X--- Unused
; ---0---- Disable TXIE - USART Transmit Interrupt Enable bit
; --0----- Disable RCIE - USART Receive Interrupt Enable bit
; -0------ Disable CMIE - Comparator Interrupt Enable bit
; 0------- Disable EEIE - EE Write Complete Interrupt Enable bit
BCF STATUS, RP0 ; Bank 0
CLRF PIR1 ; Clear Peripheral Interrupt Flags
MOVLW B'00000001' ; 00000001
MOVWF T2CON ; ------01 Prescale 1:4
; -----0-- TMR2 OFF
; -0000--- Postscale 1:1
; 0------- Unused
BSF STATUS, RP0 ; Bank 1
MOVLW D'250' ;
MOVWF PR2 ; Interrupt every 0.001s or 1mS
BCF STATUS, RP0 ; Bank 0
BSF INTCON, GIE ; Enable Global Interrupts
BSF INTCON, PEIE ; Enable Peripheral Interrupts
BSF T2CON, TMR2ON ; Start TMR2
GOTO GET_TEMP
; Dallas DS18B20 Temperature Sensor 'One Wire' Communication Routines
DS18B20_RESET ; This routine Resets the DS18B20
CALL DQ_LL ; Force the DQ Line to Logic Low
MOVLW (D'480'-5)/5 ; Reset pulse must be held a minimum of 480uS.
CALL DELAY ; For delays from 10uS to 1285uS. Example, MOVLW D'10' for 10uS, MOVLW D'500' for 500uS. (D'n'-5)/5; n must be divisable by 5
CALL DQ_HIZ ; Release DQ Line
MOVLW (D'60'-5)/5 ; Wait for recovery
CALL DELAY ;
BTFSC PORTA, 4 ; Test for 'Presence Pulse'
GOTO DS18B20_RESET ; If not present, Reset
MOVLW (D'420'-5)/5 ; Must wait a minmum of 480uS from when DQ line is released before moving on
CALL DELAY ;
RETURN ;
DS18B20_READ_BYTE ; This routine reads a byte of data from the DS18B20
MOVLW H'08' ; Amount of bits to shift out
MOVWF COUNT ; Store in COUNT GPR
CALL DS18B20_READ_BIT ; Read bit
RRF SHIFT, F ; Rotate bit out of carry into SHIFT GPR
DECFSZ COUNT, F ; Decrement COUNT
GOTO $-D'3' ; If not zero, read next bit
MOVF SHIFT, W ; If zero, move SHIFT GPR to W
RETURN ;
DS18B20_READ_BIT ; This routine reads one bit of data from the DS18B20
BCF INTCON, GIE ; Disable Global Interrupts
CALL DQ_LL ; Force the DQ Line to Logic Low
CALL DQ_HIZ ; Release DQ Line
BSF STATUS, C ; Preset Carry Flag
BTFSS PORTA, 4 ; Test DQ Line
BCF STATUS, C ; If zero, Clear Carry Flag
BSF INTCON, GIE ; Enable Global Interrupts
MOVLW (D'60'-5)/5 ; Wait for Time Slot to end
CALL DELAY ;
RETURN ;
DS18B20_WRITE_BYTE ; This routine writes a byte of data to the DS18B20
MOVWF SHIFT ; Move data to shift into DS18B20 to SHIFT GPR
MOVLW D'08' ; Amount of bits to shift in
MOVWF COUNT ; Store in COUNT GPR
RRF SHIFT, F ; Rotate valid data into Carry Flag
CALL DS18B20_WRITE_BIT ; Write bit
DECFSZ COUNT, F ; Decrement COUNT
GOTO $-D'3' ; If not zero, read next bit
RETURN ; If zero, RETURN
DS18B20_WRITE_BIT ; This routine writes one bit of data to the DS18B20
BCF INTCON, GIE ; Disable Global Interrupts
CALL DQ_LL ; Force the DQ Line to Logic Low
BTFSS STATUS, C ; Test Carry Flag
GOTO $+D'2' ; If zero, leave DQ Line Logic Low
CALL DQ_HIZ ; If not zero, release DQ Line to Logic High
MOVLW (D'60'-5)/5 ; Hold Logic Low, write 0
CALL DELAY ;
CALL DQ_HIZ ; If not zero, release DQ Line to Logic High, write 1
BSF INTCON, GIE ; Enable Global Interrupts
RETURN ;
DQ_HIZ ; This routine forces the DQ Line to an Input / High Impedance state
BSF STATUS, RP0 ; Bank 1
BSF TRISA, 4 ; Make Pin 3 an input, Pullup resistor forces line to logic 1, unless DS18B20 pulls it low
BCF STATUS, RP0 ; Bank 0
RETURN
DQ_LL ; This routine forces the DQ Line to Logic Low
BCF PORTA, 4 ; Clear output latch
BSF STATUS, RP0 ; Bank 1
BCF TRISA, 4 ; Make Pin 3 an output
BCF STATUS, RP0 ; Bank 0
RETURN
DELAY ; This routine can provide delays from 10uS to 1285uS depending on the number moved to the Working register prior to calling the delay
MOVWF DELAYGPR1 ; Move integer to GPR
NOP ; No Operation
NOP ; No Operation
DECFSZ DELAYGPR1, F ; Decrement GPR and place back in itself
GOTO $-D'3' ; Not finished, GOTO here - 3 instructions
RETURN ; Finished, Return
GET_TEMP
CALL DS18B20_RESET ; Reset
MOVLW H'CC' ; Skiprom
CALL DS18B20_WRITE_BYTE ; Skiprom
MOVLW H'44' ; Convert T
CALL DS18B20_WRITE_BYTE ; Convert T
CALL DS18B20_READ_BIT ; Initiate Read Time Slots
BTFSS STATUS, C ; DS18B20 transmits a 0 while the temperature conversion is in progress and a 1 when the conversion is done
GOTO $-D'2' ; Transmitting 0 therefore NOT done
CALL DS18B20_RESET ; Reset
MOVLW H'CC' ; Skiprom
CALL DS18B20_WRITE_BYTE ; Skiprom
MOVLW H'BE' ; Read Scratchpad
CALL DS18B20_WRITE_BYTE ; Read Scratchpad
CALL DS18B20_READ_BYTE ; Move Scrachpad Byte 0 to W
MOVWF TEMPLO_C ; Store in Celsius TEMPLO GPR
CALL DS18B20_READ_BYTE ; Move Scrachpad Byte 1 to W
MOVWF TEMPHI_C ; Store in Celsius TEMPHI GPR
DISPLAY_TEMP
BCF FLAGS, 1 ; Clear Negative Flag
BTFSS TEMPHI_C, 7 ; Test if Temperature is negative (2's complement format)
GOTO REARRANGE_DATA ; NOT Negative, skip 'Undo 2's Complement'
BSF FLAGS, 1 ; Set Negative Flag; used later
; Undo 2's Complement. When the Temperature is Negative, the DS18B20 outputs the 2's Complement. This routine converts the negative data into its positive equivalent
; Example Negative Temperature TEMPHI = 1111 1110 TEMPLO = 0110 1110 = -25.1250 (see datasheet)
COMF TEMPLO_C, F ; Invert TEMPLO
COMF TEMPHI_C, F ; Invert TEMPHI
INCFSZ TEMPLO_C, F ; Increment TEMPLO once; After inverting the data, add one to acheive equivalent positive number (see 2's complement)
GOTO $+D'2' ; No overflow skip next instruction
INCF TEMPHI_C, F ; Overflow occured, increment upper byte
; Example Negative Temperature AFTER undo TEMPHI = 0000 0001 TEMPLO = 1001 0010 = +25.1250
REARRANGE_DATA ; This routine rearranges the 2 Temperature result bytes into useable data.
; EXPLANATION:
; * After the DS18B20 finishes a Temperature Conversion, the 12-bit result is stored in two 8-bit
; registers as a 16-bit sign-extended two?s complement number.
; * The 5 MSb's of the MSB (TEMPHI_C) indicate a negative or positive temperature.
; * The output data follows this format (12-bit resolution; 0.0625 degrees celsius increments);
;
; SSSS SNNN : NNNN FFFF Where S = Sign (0 = Positive 1 = Negative)
; N = Number, &
; F = Fraction (16 X 0.0625 increments = 1)
;
; After communication with the DS18B20 the output data is held in two 8 bit registers called
; TEMPHI_C & TEMPLO_C in the following format TEMPHI_C = SSSS SNNN : TEMPLO_C = NNNN FFFF
;
; Example; 0000 0011 1001 0001 = (D'913' X 0.0625) = 57.0625 Degrees Celsius
;
; * This 6 instruction routine below rearranges the 4 nibbles of TEMPHI_C & TEMPLO_C so the data
; is easy to work with.
; * The MSB (TEMPHI_C) will be used for the 'whole' number i.e. 1's, 10's & 100's digits (57);
; and the LSB (TEMPLO_C) will be used for the decimal digit (.1's) with the upper nibble of the
; LSB masked. (These are infact the sign bits, but we have already handled negative data and
; created a Flag (FLAGS, 1) for negative temperatures.
;
; Example above, after rearrangement 0011 1001 0000 0001 (see below)
;
; Example before; TEMPHI_C = 0000 0011 TEMPLO_C = 1001 0001 = 57.0625 Degrees Celsius
MOVLW B'11110000' ; W = 1111 0000
ANDWF TEMPLO_C, W ; F = 1001 0001 W = 1001 0000
IORWF TEMPHI_C, F ; F = 0000 0011 F = 1001 0011
SWAPF TEMPHI_C, F ; F = 1001 0011 F = 0011 1001 (New TEMPHI_C)
MOVLW B'00001111' ; W = 0000 1111
ANDWF TEMPLO_C, F ; F = 1001 0001 F = 0000 0001 (New TEMPLO_C)
; Example after; TEMPHI_C = 0011 1001 TEMPLO_C = 0000 0001
; = D'57' (X 1.0) = 57 = D'1' (X 0.0625) = 0.0625 = 57.0625 Degrees Celsius
BIN_TO_DEC_C ; This routine converts the 8-bit number held in TEMPHI_C to Decimal and stores it in 3 GPR's; HUNS, TENS & ONES
; Example 225;
; HUNS holds amount of hundreds (i.e. 0000 0010 = 2x100)
; TENS holds amount of tens (i.e. 0000 0010 = 2x10)
; ONES holds amount of ones (i.e. 0000 0101 = 5x1)
; These registers are then used as jump pointers when calling digits to display
INCF TEMPHI_C ; Preload TEMPHI + 1
CLRF HUNS ; HUNS = 0000 0000
MOVLW D'246' ; MOVE Decimal'246' to W
MOVWF TENS ; TENS GPR = 1111 0101
MOVWF ONES ; ONES GPR = 1111 0101
DECFSZ TEMPHI_C, F ; Decement TEMPHI register
GOTO $+D'2' ; NOT 0, skip next instruction
GOTO $+D'7' ; IS 0, TEMPHI = 0000 0000, skip next 6 instructions and calculate how many tens and hundreds
INCFSZ ONES, F ; Increment ONES register, skip if 0
GOTO $-D'4' ; NOT 0, GOTO here - 4 instructions
INCFSZ TENS, F ; IS 0, Increment TENS register skip if 0
GOTO $-D'7' ; GOTO here - 7 instructions & reset the ONES register to D'246'
INCF HUNS, F ; TENS overflowed, Increment HUNS
GOTO $-D'10' ; GOTO here - 10 instructions & reset the ONES and TENS registers to D'246'
SUBWF TENS, F ; W still holds D'246 so subract it from TENS register to determine how many 'TENS'
SUBWF ONES, F ; W still holds D'246 so subract it from ONES register to determine how many 'ONES'
FRACTION_ROUND ; This routine rounds the fraction portion of the Temperature data to the nearest .1
; Provided by & used with his permission from 'Pommy'. Contact via Electro-Tech-Online.com
; Examples
; TENTHS = Fraction * 10 / 16
; TENTHS = 00000100 ( D'4' * 0.0625 = 0.2500 Degrees C) * 10 / 16 = 3
; TENTHS = 00001001 ( D'9' * 0.0625 = 0.5625 Degrees C) * 10 / 16 = 6
; TENTHS = 00001101 (D'13' * 0.0625 = 0.8125 Degrees C) * 10 / 16 = 8
MOVLW B'00001111' ;
ANDWF TEMPLO_C, F ;
MOVF TEMPLO_C, W ;
ADDWF TEMPLO_C, F ; *2, C=0
RLF TEMPLO_C, F ; *4, C=0
ADDWF TEMPLO_C, F ; *5, C=0
RLF TEMPLO_C, F ; *10
MOVLW B'00001000' ;
ADDWF TEMPLO_C, F ; Rounding
SWAPF TEMPLO_C, W ; Pseudo divide by 16
ANDLW B'00001111' ;
MOVWF DECI ;
; Leading zero suppression & minus (-) sign if Temperature Negative
MOVF HUNS, W ; MOVF instruction affects Z bit of STATUS register
BTFSC STATUS, Z ; Does HUNS = 0?
MOVLW B'00001010' ; Yes, jump Pointer for blank arrangement
BTFSC FLAGS, 1 ; Is Temperature Negative?
MOVLW B'00001011' ; Yes, jump Pointer for '-' arrangement
MOVWF HUNS ;
BTFSS STATUS, Z ; Does HUNS = not 0?
GOTO $+D'5' ; Yes, do not blank TENS
MOVF TENS, W ; MOVF instruction affects Z bit of STATUS register
BTFSC STATUS, Z ; Does TENS = 0?
MOVLW B'00001010' ; Yes, jump Pointer for blank arrangement
MOVWF TENS ;
; This routine would not be needed if interrupts were disabled for the whole BIN_TO_DEC routine. So this is added to minimise the amount of time interrupts are disabled to minimise flicker.
BCF INTCON, GIE ; Disable Interrupts
MOVF HUNS, W
MOVWF THOU_COL
MOVF TENS, W
MOVWF HUNS_COL
MOVF ONES, W
MOVWF TENS_COL
MOVF DECI, W
MOVWF ONES_COL
BSF INTCON, GIE ; Enable Interrupts
GOTO GET_TEMP
END
|