HOODEY
Super Member
- Total Posts : 580
- Reward points : 0
- Joined: 2005/02/08 06:06:31
- Status: offline
16 bit Binary to 5 digit BCD
Am looking for a compact clealy documented routine to do this conversion. I have searched without success..
|
Ken_Pergola
Super Member
- Total Posts : 2252
- Reward points : 0
- Joined: 2003/11/07 12:48:48
- Status: offline
RE: 16 bit Binary to 5 digit BCD
2009/08/07 22:05:48
(permalink)
|
dan1138
Super Member
- Total Posts : 4246
- Reward points : 0
- Joined: 2007/02/21 23:04:16
- Location: 0
- Status: offline
RE: 16 bit Binary to 5 digit BCD
2009/08/07 22:20:15
(permalink)
ORIGINAL: HOODEY Am looking for a compact clearly documented routine to do this conversion. I have searched without success.. Ken has pointed out a routine that does the conversion you have asked for though the documenation is far from clear. It is likely that what you are looking for does not currently exist for the PIC 14-bit core processor. There may be several reasons why this is so but mainly there are two mutually exclusive goals at work here. The first is what you are asking for, a compact routine. The second is for a routine that executes quickly. In general the most compact routine will use the remainder of a divide by ten to produce a stream of BCD digits from least to most significant. This routine is inefficient because division of a 16-bit value is inefficient with the PIC 14-bit core processor. One of the faster methods uses binary weighted decimal constants to decompose the 16-bit integer into 5 BCD digits from most to least significant digit. For the MSD the constants are 40000 and 20000, for the next they are 8000, 4000, 2000, 1000 then 800, 400, 200, 100, then 80, 40, 20, 10. This method uses 14 comparisons, and up to 14 subtractions and bit sets to create 5 BCD digits. This will execute faster than even one call to a generic 16-bit division function. Hopefully this will give you an idea or two of how this problem may be solved.
|
BitWise
Super Member
- Total Posts : 1238
- Reward points : 0
- Joined: 2004/11/09 13:24:20
- Location: UK
- Status: offline
RE: 16 bit Binary to 5 digit BCD
2009/08/08 03:56:00
(permalink)
Try this. Relatively compact and whilst there are a number of adds/subs they only operate on 8-bits. include P12F683.inc errorlevel -312 udata BINL res .1 ; Binary value to convert BINH res .1 BCDL res .1 ; Resulting BCD value BCDH res .1 BCDU res .1 COUNT res .1 ; Counter .ResetVector code h'000' lgoto PowerOnReset code PowerOnReset: banksel BINL ; Set a test value movlw h'ff' movwf BINL movwf BINH call Bin2BCD ; Convert it goto $ ; Stop ;------------------------------------------------------------------------------- Bin2BCD: clrf BCDL ; Clear result clrf BCDH clrf BCDU movlw .16 ; Set bit counter movwf COUNT ConvertBit: movlw h'33' ; Correct BCD value so that addwf BCDL,F ; subsequent shift yields btfsc BCDL,.3 ; correct value. andlw h'f0' btfsc BCDL,.7 andlw h'0f' subwf BCDL,F movlw h'33' addwf BCDH,F btfsc BCDH,.3 andlw h'f0' btfsc BCDH,.7 andlw h'0f' subwf BCDH,F rlf BINL,F ; Shift out a binary bit rlf BINH,F rlf BCDL,F ; .. and into BCD value rlf BCDH,F rlf BCDU,F decfsz COUNT,F ; Repeat for all bits goto ConvertBit return end
Its a 'double dabble' algorithm the idea being that you can convert a binary number to decimal by doubling a running total using BCD arithmetic and adding the binary bits one at a time. The blocks at the start of the loop adjust the BCD value so that the subsequent doubling by the shift will yield a valid BCD digit. If you double 0, 1, 2, 3 or 4 then the result will always valid but if the digit was 5, 6, 7, 8 or 9 then doubling will yield an incorrect (hexadecimal) value a, b, c, d, e, 10 or 11. Adding an additional 6 to these values gives the correct result e.g. a + 6 = 10). The code tests which BCD nybbles can't be doubled by adding 3 to each digit. If the result is less than 8 (e.g. bit 3 or 7 clear) then it subtracts the 3 away again leaving be digit unchanged. If the 3 was not subtracted then when the value is shifted it becomes equivalent to adding 6 and corrects the result.
Throughout your life advance daily, becoming more skillful than yesterday, more skillful than today. This is never-ending. Yamamoto Tsunetomo (1659-1719)
|
HOODEY
Super Member
- Total Posts : 580
- Reward points : 0
- Joined: 2005/02/08 06:06:31
- Status: offline
RE: 16 bit Binary to 5 digit BCD
2009/08/08 07:39:20
(permalink)
Okay used the one form PIC list as I wanted 5 digits . I am trying to display RPM. E.g 7000rpm Thank you.
|
1and0
Access is Denied
- Total Posts : 12108
- Reward points : 0
- Joined: 2007/05/06 12:03:20
- Location: Harry's Gray Matter
- Status: offline
RE: 16 bit Binary to 5 digit BCD
2009/08/08 08:16:14
(permalink)
ORIGINAL: BitWise Its a 'double dabble' algorithm the idea being that you can convert a binary number to decimal by doubling a running total using BCD arithmetic and adding the binary bits one at a time. Very Nice !  This is better than the one in Microchip AN526 which has some BCD routines. @HOODEY: BitWise's routine returns 5 digits in packed BCD format (BCDU:BCDH:BCDL).
|
DougRice
Super Member
- Total Posts : 534
- Reward points : 0
- Joined: 2008/10/08 23:44:59
- Location: 0
- Status: offline
RE: 16 bit Binary to 5 digit BCD
2009/08/08 12:51:56
(permalink)
|
BitWise
Super Member
- Total Posts : 1238
- Reward points : 0
- Joined: 2004/11/09 13:24:20
- Location: UK
- Status: offline
RE: 16 bit Binary to 5 digit BCD
2009/08/08 13:20:28
(permalink)
ORIGINAL: DougRice This routine is fast and documented. Not sure I follow how it works. Doesn't really count as documented then ;-)
Throughout your life advance daily, becoming more skillful than yesterday, more skillful than today. This is never-ending. Yamamoto Tsunetomo (1659-1719)
|
ppater
Super Member
- Total Posts : 1002
- Reward points : 0
- Joined: 2006/08/26 10:33:06
- Location: Ivry, France
- Status: offline
RE: 16 bit Binary to 5 digit BCD
2009/08/08 22:33:38
(permalink)
|
DougRice
Super Member
- Total Posts : 534
- Reward points : 0
- Joined: 2008/10/08 23:44:59
- Location: 0
- Status: offline
RE: 16 bit Binary to 5 digit BCD
2009/08/15 00:00:43
(permalink)
BitWise, At this point I say "If you are trying to be clever with me, you are wasting your time." - The kipper family Like most people, I believe somebody else understood it, and it seems to work, so I will use it without further thought. Seriously, It is documented. I have tried to follow it and would like to understand it one day! I coded this, and my code took ages. BCD=1 BCDacc=0 binary= value for 16 bits do If lsb of binary is 1 add BCD to BCDacc then BCDacc = BCDacc + BCD BCDacc BCDadjust(BCDacc) end BCD = BCD + BCD BCD= BCDadjust(BCD) shiftright( binary ) BCDacc now contains the decimal digits. I used this code. It was fast. ; ;******************************************************************** ; Binary To BCD Conversion Routine ; This routine converts a 16 Bit binary Number to a 5 Digit ; This routine converts a 24 Bit binary Number to an 8 Digit ; BCD Number. This routine is useful since PIC16C55 & PIC16C57 ; have two 8 bit ports and one 4 bit port ( total of 5 BCD digits) ; ; The 16 bit binary number is input in locations H_byte and ; L_byte with the high byte in H_byte. ; The 5 digit BCD number is returned in R0, R1 and R2 with R0 ; containing the MSD in its right most nibble. ; ; Performance : 16 bit 24 bit ; Program Memory : 35 ; Clock Cycles : 885 2100 approx ; ; This file is based on the file BCD.ASM found on www.crownhill.co.uk ; ;*******************************************************************; ; ; B2_BCD bcf STATUS,0 ; clear the carry bit movlw .32 ; number of bits to convert. movwf BCDcount clrf BCDop0 clrf BCDop1 clrf BCDop2 clrf BCDop3 clrf BCDop4 BCDloop16 bcf STATUS,C btfsc BCDip3,7 bsf STATUS,C rlf BCDip0 rlf BCDip1 rlf BCDip2 rlf BCDip3 rlf BCDop0 rlf BCDop1 rlf BCDop2 rlf BCDop3 rlf BCDop4 ; decfsz BCDcount goto BCDadjDEC RETLW 0 ; BCDadjDEC ; movlw BCDop4 ; movwf FSR ; call BCDadjBCD movlw BCDop0 movwf FSR call BCDadjBCD movlw BCDop1 movwf FSR call BCDadjBCD ; movlw BCDop2 movwf FSR call BCDadjBCD ; movlw BCDop3 movwf FSR call BCDadjBCD ; goto BCDloop16 ; BCDadjBCD movlw 0x03 addwf 0,W movwf BCDtemp btfsc BCDtemp,3 ; test if result > 7 movwf 0 movlw 0x30 addwf 0,W movwf BCDtemp btfsc BCDtemp,7 ; test if result > 7 movwf 0 ; save as MSD RETLW 0
post edited by DougRice - 2009/08/15 00:15:49
|