;*************************************************************************** ; ; BINARY to DECIMAL CONVERSION for LCD-Display for PIC 16XXX V1.02 ; ================================================================ ; ; written by Peter Luethi, 21.01.1999, Dietikon, Switzerland ; http://www.electronic-engineering.ch ; last update: 20.08.2004 ; ; V1.02: Changed labels such as to be able to use both, m_lcdv08.asm ; and m_lcdv16.asm simultaneously (24.06.2004) ; V1.01: Replaced register with #define statement for flag ; (16.02.2003) ; V1.00: Initial release (21.01.1999) ; ; This code and accompanying files may be distributed freely and ; modified, provided this header with my name and this notice remain ; intact. Ownership rights remain with me. ; You may not sell this software without my approval. ; ; This software comes with no guarantee or warranty except for my ; good intentions. By using this code you agree to indemnify me from ; any liability that might arise from its use. ; ; ; SPECIFICATIONS: ; =============== ; Processor: Microchip PIC 16XXX ; Decimal Range: 0 - 65'535 unsigned ; Binary Range: 16 Bit unsigned ; ; ; DESCRIPTION: ; ============ ; Developed and tested on PIC 16C84, but executeable on all PICs. ; Evaluates from 16 bit Binary Data in HI,LO the equivalent ; decimal output for the LCD-Display. Preceeding zeros are ; not displayed. ; ; Call of implemented procedure with: ; "LCDval_16", value in HI & LO ; ; LO & HI are NOT altered or cleared during operation and are ; still valid after termination of this routine. ; During the whole routine, LO_TEMP, HI_TEMP & BCflag must NOT ; be used by other routines ! ======== ; TEMP1 - TEMP3 can be used by the LCD routine during conversion ; (call of LCDw), because they will be re-defined again. ; ; ; DECLARATIONS needed in MAIN PROGRAM : ; ===================================== ; CONSTANT BASE = 0x0C ; Base address of user file registers ; LO equ BASE+? ; HI equ BASE+? ; LO_TEMP set BASE+? ; HI_TEMP set BASE+? ; #define BCflag ,0x00 ; blank checker for preceeding zeros ; ; can be any register, containing also ; ; other flags ; ; ; REQUIRED MEMORY: ; ================ ; 3 registers: @ BASE+0 - BASE+2 (temporary registers) ; 4 registers: LO, LO_TEMP, HI, HI_TEMP ; 1 flag: BCflag ; needs itself 2 stack levels, but LCDw needs some more ; ;*************************************************************************** ;***** INCLUDE FILES ***** IFNDEF M_LCD_ID ERROR "Missing include file: m_lcd.asm or similar" ENDIF ;***** REGISTER DECLARATION ***** IFNDEF BASE ERROR "ModuleError: Declare BASE (Base address of user file registers) in MAIN PROGRAM" ENDIF IFNDEF LO ERROR "ModuleError: Declare LO in MAIN PROGRAM" ENDIF IFNDEF HI ERROR "ModuleError: Declare HI in MAIN PROGRAM" ENDIF IFNDEF LO_TEMP ERROR "ModuleError: Declare LO_TEMP in MAIN PROGRAM" ENDIF IFNDEF HI_TEMP ERROR "ModuleError: Declare HI_TEMP in MAIN PROGRAM" ENDIF IFNDEF BCflag ERROR "ModuleError: #define BCflag FLAGreg,0x05 (Blank checker) in MAIN PROGRAM" ENDIF ; *** Universal Temporary Register *** TEMP1 set BASE+d'0' ; counter TEMP2 set BASE+d'1' ; Sub-LO TEMP3 set BASE+d'2' ; Sub-HI ;***** MACROS ***** LCDval_16 macro call LCDval16 endm ;***** SUB-ROUTINES ***** LCDval16 movfw LO ; LO -> LO_TEMP movwf LO_TEMP movfw HI ; HI -> HI_TEMP movwf HI_TEMP bcf BCflag ; Blank checker for preceeding zeros movlw b'00010000' ; check amount of 10000s movwf TEMP2 ; Sub-LO movlw b'00100111' movwf TEMP3 ; Sub-HI call _VALcnv16 ; call conversion sub-routine LCDw ; call LCD sub-routine with value stored in w movlw b'11101000' ; check amount of 1000s movwf TEMP2 ; Sub-LO movlw b'00000011' movwf TEMP3 ; Sub-HI call _VALcnv16 ; call conversion sub-routine LCDw ; call LCD sub-routine with value stored in w movlw b'01100100' ; check amount of 100s movwf TEMP2 ; Sub-LO clrf TEMP3 ; Sub-HI is zero call _VALcnv16 ; call conversion sub-routine LCDw ; call LCD sub-routine with value stored in w movlw b'00001010' ; check amount of 10s movwf TEMP2 ; Sub-LO clrf TEMP3 ; Sub-HI is zero call _VALcnv16 ; call conversion sub-routine LCDw ; call LCD sub-routine with value stored in w movlw b'00000001' ; check amount of 1s movwf TEMP2 ; Sub-LO clrf TEMP3 ; Sub-HI is zero bsf BCflag ; remove blank checker in case of zero call _VALcnv16 ; call conversion sub-routine LCDw ; call LCD sub-routine with value stored in w RETURN _VALcnv16 clrf TEMP1 ; clear counter _V16_1 movfw TEMP3 subwf HI_TEMP,w ; TEST: HI_TEMP-TEMP3 >= 0 ? skpc ; skip, if true goto _V16_LCD ; result negativ, exit bnz _V16_2 ; test zero, jump if result > 0 movfw TEMP2 ; Precondition: HI-TEST is zero subwf LO_TEMP,w ; TEST: LO_TEMP-TEMP2 >= 0 ? skpc ; skip, if true goto _V16_LCD ; result negativ, exit _V16_2 movfw TEMP3 subwf HI_TEMP,f ; STORE: HI_TEMP = HI_TEMP - TEMP3 movfw TEMP2 subwf LO_TEMP,f ; STORE: LO_TEMP = LO_TEMP - TEMP2 skpc ; skip, if true decf HI_TEMP,f ; decrement HI incf TEMP1,f ; increment counter bsf BCflag ; invalidate flag goto _V16_1 _V16_LCD movlw '0' ; writes number to LCD addwf TEMP1,w ; '0' is ascii offset, add counter btfss BCflag ; check flag movlw ' ' ; clear preceeding zeros ; return with data in w RETURN