Re: Binary to BCD conversion
I do believe there is an easier way. One question I have is, How is the original data retrieved or stored ie. LONG or WORD array elements?
Re: Binary to BCD conversion
Dave,
I would be interested to see how you would implement the binary/BCD conversion. The code I posted is my take on the shift and add 3/double dabble routine.
The original data will come from 4 74HC165 shift registers, I will shift in 4 bytes of data and store these as BBIN1...4. The program is part of a frequency counter I am working on. I am 4 using 74HC393 binary counters followed by the shift registers to give a 32 bit count. The PIC will only do the arithmetic and control the MAX7219 display driver. I will be using an external timebase.
I'm sure this isn't the simplest or most elegant way to implement a frequency counter, but I will learn more doing it this way. My first thought is that I may be able to reduce the number of 393/165 chips and count the number of overflows during the timing period to reduce chip count.
I could use 74HC390 to avoid having to do the binary/BCD conversion but this would need more chips due to the redundancy of bits in BCD
Regards,
John
Re: Binary to BCD conversion
How about
shift right 4 times (thus losing bottom 4 bits and shifting 0 into top 4 bits)
if 0-9 then add x30
else add x37
mask off the 4 msb's
if 0-9 then add x30
else add x37
so for example 3A
shifted becomes 3
3 + x30 = x33 ASCII for "3"
masked becomes x0A
x0A + x37= x47 ASCII for "F"
Re: Binary to BCD conversion
Well John, Here is the way I would do it. Assuming all 4, 8 bit counters are connected in series to get 32 bits:
BIGNUM VAR LONG
VALUE VAR BYTE
JUNK VAR BYTE
CHARPOS VAR BYTE
DIGVALUE VAR BYTE
MAIN:
'THIS ASSUMES ALL 4, 8 BIT COUNTERS ARE IN SERIES ON SAME DATA AND CLOCK LINE
'ADJUST DATA AND CLOCK LINE TO YOUR HARDWARE CONFIGURATION
SHIFTIN REGDATAPIN,REGCLKPIN,MSBFIRST,[BIGNUM.BYTE3,BIGNUM.BYTE2,BIGNUM.BYTE1,BIGNUM.BYTE 0]
'32 BIT VALUE IS CLOCKED IN TO LONG VARIABLE
JUNK = 7 'SET DIGIT POINTER FOR 8 DIGITS TOTAL
WHILE JUNK < 255
VALUE = BIGNUM DIG(JUNK) 'VALUE OF DIGIT
CHARPOS = JUNK + 1 'CALCULATED CHARACTER POSITION
low load
shiftout datapin,clockpin,MSBFIRST,[CHARPOS, VALUE] 'DATA SHIFTED TO DISPLAY
high load
JUNK = JUNK - 1 'NEXT DIGIT FROM MSBYTE TO LSBYTE
WEND
pause 1000
goto main
I hope this bit of code will help you.
Re: Binary to BCD conversion
Dave,
Thank you for sharing this, your method does seem a lot simpler. I don't have LONGS available but imagine this could be worked around. I would be interested in having a go with something based on your method and see if there is much difference in the size of the compiled program.
George,
Thanks for your reply. I am a little confused though, does this convert to ASCII rather than BCD?
John
Re: Binary to BCD conversion
Quote:
Thanks for your reply. I am a little confused though, does this convert to ASCII rather than BCD?
I think I misunderstood the question, I thought BCD was a way of expressing a binary value as ASCII characters. So for example a byte would become two ASCII chars, a word 4 ASCII chars etc.
Re: Binary to BCD conversion
John, If you limit the accumulated value to say 5 digits as in a word (65535 max) then you can use it without LONG's. I use this method to display MPH with 3 decimal places on a terminal thru a serial port by adding:
TX_BYTES(TX_OUTPUT) = $30 + VALUE DIG JUNK 'Turn decimal value into ASCII
Re: Binary to BCD conversion
Dave,
Interesting approach, seems like I got too bogged down in shifting and adding multiple times rather than using the more obvious arithmetic capabilities of PICBASIC.
George,
Thanks for the hint on conversion to ASCII, I'm sure it will come in useful at some stage.
For info, BCD represents the decimal digits 0-9 using a nibble of data. With BCD only the states 0-9 are valid. 0xA to 0xF are forbidden. Its used for seven segment displays, real time clock modules, etc.