A função toBCD16 funciona de maneira similar a função toBCD8. O algoritmo de conversão consiste na divisão sucessiva por 1000, por 100, por 10 e o número restante é o próprio dígito das unidades. O código abaixo é destinado a conversão de 4 dígitos (de 0000 até 9999). O código-fonte deve funcionar em qualquer PIC da família PIC16 sem nenhuma alteração.
Variáveis utilizadas:
;********************************************************* ;<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 ;} ;*********************************************************
Post new comment