Binary to Decimal Converter for Microchip PIC18f
This is a very simple program for the Microchip PIC18f that makes a good programming project. Once I figured out what many of the code samples were doing, it became very clear and easy to understand. It’s too bad that all the code samples I ran across were not (or at least very poorly) ‘documented’.
[stextbox id=”info”]In my opinion, “Documented” means a LOT more than throwing a few vague words after a semicolon, scattered sparsely throughout your code. If you can’t read the steps somewhere in plain-English, then others can’t follow, and it ain’t documented.[/stextbox]
DAW – Decimal Adjust W Register
Since we will be adding two BCD numbers, the DAW command will take care of ‘adjusting’ the resulting the result back into a BCD number. I believe this DAW command is only on the PIC18 family (may be on higher families, I don’t know). Note this only works when adding two BCD numbers – it won’t work for squat with a regular binary add.
From the Microchip PIC18 instruction set. Under “Operation” you can see the steps the DAW command executes. If your processor does not have this feature, you could easily create some code to do this same thing.
This command assumes that the register you are using was the result of the addition of two BCD numbers. It will only make a mess of a ‘normal’ binary number, with one exception.
We can ‘get away with’ using this command because, for numbers less than or equal to 0x09, binary and BCD are the same. And our first operation will always result in a number less than 0x09. So we start converting to BCD then, and doubling the BCD number each time from then onward.
Double and add carry
The code uses the double and add carry approach. Below is a fragment that explains the process: this is repeated for each BCD output ‘pair’. (each byte holds two BCD numbers)
Start by rotating the binary number to the left, putting the MSB into the carry bit
RCLF Bin0, f ; for first byte to convert
Move the BCD byte from memory into the W register, then add it to itself (double) with carry, from the above command.
MOVF BCD0, w ; move first BCD pair into Wreg ADDWFC BCD0, w ; add it to itself (double) and add carry from rotate of binary
Decimal Adjust Wreg (re-align & correct BCD numbers
DAW ; Decimal adjust BCD word
Store the result back where you got it from
movwf BCD0 ; Save result back to BCDx register
Repeat this for each “BCD pair”. If there is a carry to the next BCD byte, it will be handled via the Add-and-carry for the next byte.
Binary to BCD code for PIC18
;******************************************************************************* ;* Filename: Bin2BCD.asm ;* Date: 5/15/15 ;* File Version: 0.0 ;* Author: Brian Volken ;* Company: Brady Volken Enterprises ;* Description: Convert binary number into BCD string ;******************************************************************************* ;* Revision History: ;* 0.0 Initial Version ;******************************************************************************* ;******************************************************************************* ; Processor Inclusion ;******************************************************************************* #include p18f4580.inc UDATA_ACS BCD0 RES 1 ; holder for lowest BCD pair BCD1 RES 1 ; holder for next BCD pair BCD2 RES 1 ; continue as necessary to hold answer ;BCD3 RES 1 Bin0 RES 1 ; holder for binary number to convert, lowest byte Bin1 RES 1 ; holder for binary number higher byte ;Bin2 RES 1 ; repeat as necessary BitCtr RES 1 ; counter of number of bits to convert ;******************************************************************************* ;* Defines ;******************************************************************************* #define bcount .16 ; number of binary bits to be converted to BCD ;******************************************************************************* ; "Exposed" sub routine elements (variables & code) ; GLOBAL is used to make a lable visible to other files. ; EXTERN must be used in the file that uses (calls) the lable to make it visible ;******************************************************************************* Bin2BCD CODE ; Init variables, load BitCtr with number of bits in binary source BinToBCD: CLRF BCD0 CLRF BCD1 CLRF BCD2 MOVLW bcount MOVWF BitCtr ;******************************************************************************* ;* ConvertBit ;******************************************************************************* ConvertBit: ; rotate binary word(s) left one bit RCLF Bin0, f ; for first byte to convert RCLF Bin1, f ; for 2nd byte to convert ; RCLF Bin2, f ; for 3rd byte to convert movf BCD0, w ; move first BCD pair into Wreg addwfc BCD0, w ; add it to itself (double) and add carry from ; rotate of binary daw ; Decimal adjust BCD word movwf BCD0 ; Save result back to BCDx register movf BCD1,W ; repeat for BCDx+1 as many times as necessary addwfc BCD1,W daw movwf BCD1 ; add more BCD 'holders' for longer binary strings ; movf BCD2,W ; addwfc BCD2,W ; daw ; movwf BCD2 decfsz BitCtr ; decrement Bit Counter bra ConvertBit ; keep going until last bit rotated out of binary source return END