Remove Text Formatting
Loading...

+ Reply to Thread
Results 1 to 9 of 9
  1. #1

    Default Binary to BCD conversion

    Hi all,

    I was recently in need of a program to convert binary to BCD to display the result of a binary counter on a MAX7219 7 segment LED display module. Couldn't find anything suitable on the forum so had a go at it myself.


    include "modedefs.bas"
    ADCON0=7 'MESSES UP SERIAL COMMS IF OMITTED
    ADCON1=7
    CNTR VAR BYTE'COUNTS THROUGH 32 SHIFT OPERATIONS

    DBYTE1 VAR BYTE'LOW 8 BITS OF SCRATCH SPACE BITS 7-0
    DBYTE2 VAR BYTE'NEXT BYTE BITS 15-8
    DBYTE3 VAR BYTE'NEXT BYTE BITS 23-16
    DBYTE4 VAR BYTE'NEXT BYTE BITS 31-24
    DBYTE5 var BYTE'HIGH 8 BITS OF SCRATCH SPACE BITS 39-32

    BBIN4 VAR BYTE'HIGH BYTE OF INPUT VARIABLE
    BBIN3 VAR BYTE
    BBIN2 VAR BYTE
    BBIN1 VAR BYTE'LOW BYTE OF INPUT VARIABLE
    'MAX7219 DISPLAY SETUP
    DataPin var PORTA.0
    ClockPin var PORTA.1
    Load var PORTA.2

    pause 500
    high load
    pause 1000

    LOW Load
    SHIFTOUT datapin,clockpin,MSBFIRST,[$0C, $01] 'shutdown mode off
    high load:low load
    SHIFTOUT datapin,clockpin,MSBFIRST,[$0A, $0F] 'set intensity to maximum
    high load:low load
    SHIFTOUT datapin,clockpin,MSBFIRST,[$09, $FF] 'BCD decode mode on
    high load:low load
    SHIFTOUT datapin,clockpin,MSBFIRST,[$0B, $07] 'scan limit 8 digits
    high load:low load
    SHIFTOUT datapin,clockpin,MSBFIRST,[$0f, $00] 'display test off
    high Load


    MAIN:
    PAUSE 2000
    DBYTE1=0:DBYTE2=0:DBYTE3=0:DBYTE4=0:DBYTE5=0

    CNTR=32'NUMBER OF BITS OF BINARY INPUT VARIABLE
    BBIN4=$00'MSB
    BBIN3=$FF
    BBIN2=$FF
    BBIN1=$FF'LSB

    CYCLE:
    GOSUB CHECK

    DBYTE5=DBYTE5<<1
    DBYTE5=DBYTE5+DBYTE4.7
    DBYTE4=DBYTE4<<1
    DBYTE4=DBYTE4+DBYTE3.7
    DBYTE3=DBYTE3<<1
    DBYTE3=DBYTE3+DBYTE2.7
    DBYTE2=DBYTE2<<1
    DBYTE2=DBYTE2+DBYTE1.7
    DBYTE1=DBYTE1<<1
    DBYTE1=DBYTE1+BBIN4.7
    BBIN4=BBIN4<<1
    BBIN4=BBIN4+BBIN3.7
    BBIN3=BBIN3<<1
    BBIN3=BBIN3+BBIN2.7
    BBIN2=BBIN2<<1
    BBIN2=BBIN2+BBIN1.7
    BBIN1=BBIN1<<1

    CNTR=CNTR-1
    IF CNTR>0 THEN GOTO CYCLE

    SEROUT2 PORTC.0,84,[BIN4 DBYTE5>>4,":",BIN4 DBYTE5&$0F,":",BIN4 DBYTE4>>4,":",BIN4 DBYTE4&$0F,":",BIN4 DBYTE3>>4,":",BIN4 DBYTE3&$0F,":",BIN4 DBYTE2>>4,":",BIN4 DBYTE2&$0F,":",BIN4 DBYTE1>>4,":",BIN4 DBYTE1&$0F,10,13]

    'DISPLAY RESULT ON MAX7219 DISPLAY MODULE


    low load
    shiftout datapin,clockpin,MSBFIRST,[$08, DBYTE4>>4] ' MSB DIGIT 7
    high load:low load
    shiftout datapin,clockpin,MSBFIRST,[$07, DBYTE4&$0F] ' DIGIT 6
    high load:low load
    shiftout datapin,clockpin,MSBFIRST,[$06, DBYTE3>>4] ' DIGIT 5
    high load:low load
    shiftout datapin,clockpin,MSBFIRST,[$05, DBYTE3&$0F] ' DIGIT 4
    high load:low load
    shiftout datapin,clockpin,MSBFIRST,[$04, DBYTE2>>4] ' DIGIT 3
    high load:low load
    shiftout datapin,clockpin,MSBFIRST,[$03, DBYTE2&$0F] ' DIGIT 2
    high load:low load
    shiftout datapin,clockpin,MSBFIRST,[$02, DBYTE1>>4] ' DIGIT 1
    high load:low load
    shiftout datapin,clockpin,MSBFIRST,[$01, DBYTE1&$0F] ' DIGIT 0
    high load
    pause 1000
    goto main
    END

    CHECK:
    IF (DBYTE1&$0F)>=5 THEN DBYTE1=DBYTE1+$03'+3 TO LOWER NIBBLE IF >= TO 5
    if (DBYTE1>>4)>=5 then DBYTE1=DBYTE1+$30'+3 TO UPPER NIBBLE IF >= TO 5
    IF (DBYTE2&$0F)>=5 THEN DBYTE2=DBYTE2+$03'+3 TO LOWER NIBBLE IF >= TO 5
    if (DBYTE2>>4)>=5 then DBYTE2=DBYTE2+$30'+3 TO UPPER NIBBLE IF >= TO 5
    IF (DBYTE3&$0F)>=5 THEN DBYTE3=DBYTE3+$03'+3 TO LOWER NIBBLE IF >= TO 5
    if (DBYTE3>>4)>=5 then DBYTE3=DBYTE3+$30'+3 TO UPPER NIBBLE IF >= TO 5
    IF (DBYTE4&$0F)>=5 THEN DBYTE4=DBYTE4+$03'+3 TO LOWER NIBBLE IF >= TO 5
    if (DBYTE4>>4)>=5 then DBYTE4=DBYTE4+$30'+3 TO UPPER NIBBLE IF >= TO 5
    IF (DBYTE5&$0F)>=5 THEN DBYTE5=DBYTE5+$03'+3 TO LOWER NIBBLE IF >= TO 5
    if (DBYTE5>>4)>=5 then DBYTE5=DBYTE5+$30'+3 TO UPPER NIBBLE IF >= TO 5
    RETURN

  2. #2
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,014

    Default 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?
    Dave Purola,
    N8NTA
    EN82fn

  3. #3

    Default 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

  4. #4

    Default 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"
    George

  5. #5
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,014

    Default 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.
    Dave Purola,
    N8NTA
    EN82fn

  6. #6

    Default 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

  7. #7

    Default Re: Binary to BCD conversion

    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.
    George

  8. #8
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,014

    Default 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
    Dave Purola,
    N8NTA
    EN82fn

  9. #9

    Default 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.

Similar Threads

  1. Trouble Reading Binary or BCD from a GPS
    By gavo in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 7th August 2011, 18:27
  2. Nice tutorial on BCD to Binary
    By lerameur in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 9th December 2010, 18:21
  3. PIC16F628 - Convert Binary to BCD?
    By steng in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 20th March 2009, 08:17
  4. BCD conversion
    By Macgman2000 in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 17th October 2005, 19:24
  5. HEX to BCD conversion
    By Don Mario in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 2nd February 2005, 14:39

Members who have read this thread : 18

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts