A função toBCD16 funciona de maneira similar a função toBCD8. O algoritmo de conversão consiste na divisão sucessiva por 1000, 100 e 10. O número restante é o próprio dígito das unidades.
O código abaixo é destinado à conversão de 4 dígitos (de 0000 até 9999). Ele é compatível com todos os dispositivos da família PIC16.
Variáveis utilizadas:
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
;*********************************************************
;<FUNÇÃO>
; toBCD16
;{
; Converte um número de 16 bits em decimal para BCD
; <ARGUMENTOS>
; BCD_low = 8 bits menos significativos a serem convertido em BCD
; BCD_high = 8 bits mais significativos a serem convertido em BCD
; <RETORNO>
; BCD_unidades = dígito menos significativo
; BCD_dezenas = dígito das dezenas
; BCD_centenas = dígito das centenas
; BCD_milhares = dígito mais significativo
; BCD_low = dígitos menos significativos
; BCD_high = dígitos mais significativos
;*********************************************************
#ifdef DISPLAY_7SEGMENTOS
; 20 Mhz:
; melhor tempo: 11,65 us
; pior tempo: 73,6 us
toBCD16:
banksel BCD_high
movlw 0x27 ; verifica se o número é maior que .9999 = 0x270F
subwf BCD_high,w
btfsc STATUS, Z
goto verifica_nibble_inferior_toBCD16 ; igual a 0x27?
btfsc STATUS, C
goto apagar_BCD_toBCD16 ; maior que 0x27?
goto prosseguir_conversao_toBCD16 ; menor que 0x27?
verifica_nibble_inferior_toBCD16:
movlw 0x0F ; verifica se o número é maior que .9999 = 0x270F
subwf BCD_low,w
btfsc STATUS, Z ; igual a 0x000F?
goto prosseguir_conversao_toBCD16
btfsc STATUS, C ; maior que 0x000F?
goto apagar_BCD_toBCD16
goto prosseguir_conversao_toBCD16
apagar_BCD_toBCD16: ; caso o número seja maior que 9999
clrf BCD_low
clrf BCD_high
prosseguir_conversao_toBCD16:
clrf BCD_unidades ; apaga cálculos anteriores
clrf BCD_dezenas
clrf BCD_centenas
clrf BCD_milhares
; INÍCIO DO PROCESSO DE CONVERSÃO
milhares_toBCD16: ; dígito mais significativo
movlw 0x03
subwf BCD_high,f
btfsc STATUS,C
goto milhares_low_toBCD16 ; >= 0x03
movlw 0x03
addwf BCD_high,f
goto centenas_toBCD16
milhares_low_toBCD16:
movlw 0xE8
subwf BCD_low,f
btfsc STATUS,C
goto incrementa_milhares_toBCD16; >= 0xE8
movf BCD_high,w
btfsc STATUS,Z
goto milhares_retorna_toBCD16 ; não é possível
decf BCD_high,f ; empréstimo efetuado
goto incrementa_milhares_toBCD16
milhares_retorna_toBCD16:
movlw 0x03 ; restaura valor original
addwf BCD_high,f
movlw 0xE8 ; restaura valor original
addwf BCD_low,f
goto centenas_toBCD16 ; O número já não é maior que 1000
incrementa_milhares_toBCD16:
incf BCD_milhares,f ; milhar contabilizado
goto milhares_toBCD16
centenas_toBCD16:
movlw 0x64
subwf BCD_low,f
btfss STATUS,C ; BCD_low é menor que 0x64?
goto empresta_um_toBCD16 ; Sim, tenta empréstimo
incf BCD_centenas,f
goto centenas_toBCD16
empresta_um_toBCD16:
movlw 0x01
subwf BCD_high,f ; subwf seta o Carry
btfss STATUS,C
goto centenas_retorna_toBCD16 ; empréstimo impossível
incf BCD_centenas,f
goto centenas_toBCD16
centenas_retorna_toBCD16:
incf BCD_high,f
movlw 0x64
addwf BCD_low,f
goto dezenas_toBCD16
;copiado de toBCD8 ------------
dezenas_toBCD16: ; dígito mais significativo
movlw .10
subwf BCD_low, f
btfss STATUS, C
goto unidades_toBCD16
incf BCD_dezenas,f
goto dezenas_toBCD16
unidades_toBCD16: ; dígito menos significativo
movlw .10
addwf BCD_low, f
movf BCD_low, w
movwf BCD_unidades
;copiado de toBCD8 ------------
; O resutado pode ser obtido tanto no BCD_low e BCD_high ou
; nos quatro files referentes às unidades, dezenas, centenas e milhares
swapf BCD_milhares,w
iorwf BCD_centenas,w
movwf BCD_high ; retorna o resultado também em BCD_high
swapf BCD_dezenas,w
iorwf BCD_unidades,w
movwf BCD_low ; retorna o resultado também em BCD_low
return ; toBCD16
#endif
;}
;*********************************************************
|
|