Hex2Bin - Hexadecimal to Binary conversion for easier viewing of control registers

While playing with the highly recommended DS3231 RTC board (a sample of which costing all of 82p inc P&P has just arrived from China), I was finding it messy to work out which bits in the various control registers were set (or not set) when reading the registers and outputting via SERTXD. Ideally there would be the opposite of e.g. regval = %10100101 but so far as I can see, it doesn't exist in PicAxe basic.

So, I quickly wrote this and found it really useful for seeing instantly which bits in the DS3231's control registers were set, and which weren't.
Code:
SYMBOL temp_byte = b0         ; b0 used as a temporary counter etc. 
SYMBOL temp_wrd1 = w1         ; Symbol for holding word 1
SYMBOL temp_wrd2 = w2         ; Symbol for holding word 2


main:

LET temp_byte = control
GOSUB hex2bin     	      ; Convert the control value to binary. 
SERTXD ("Reg.14 control ",#temp_wrd2," ",#temp_wrd1,LF,CR)

GOTO main

END

hex2bin:
; Byte value to be converted should be in temp_byte.
; Output as two words in temp_wrd2 & temp_wrd1.
; Convert low nibble
LET temp_wrd1 = temp_byte & %00000001 
LET temp_wrd1 = temp_byte & %00000010 / 2  * 10   + temp_wrd1
LET temp_wrd1 = temp_byte & %00000100 / 4  * 100  + temp_wrd1
LET temp_wrd1 = temp_byte & %00001000 / 8  * 1000 + temp_wrd1
; Convert high nibble
LET temp_wrd2 = temp_byte & %00010000 /16 
LET temp_wrd2 = temp_byte & %00100000 /32  * 10   + temp_wrd2
LET temp_wrd2 = temp_byte & %01000000 /64  * 100  + temp_wrd2
LET temp_wrd2 = temp_byte & %10000000 /128 * 1000 + temp_wrd2
;
RETURN
I daresay that it can be improved on/shortened, etc, and would welcome such improvements from the gurus (my programming skills are very limited).

It does have one particular limitation in that a value such as %10111001 will display as "1011 1001" okay, but because decimal numbers are displayed with leading zeroes blanked, %00110001 displays as "11 1".

I expect this could easily be corrected by converting to text rather than word values, but I haven't bothered so far as it was sufficiently useful for me to work out what the registers were set to.
 

westaust55

Moderator
Only suitable for X1 and X2 PICAXE parts but here is an alternative:

Code:
SYMBOL bitptr = b0
SYMBOL newbit = b1
SYMBOL value = w1 ; w1 = b3:b2


value = %1001100011100001


SERTXD ("Reg.14 control %")
GOSUB Hexdisplay
SERTXD (cr,lf)
END

Hexdisplay:
FOR bitptr = 15 to 0 STEP -1
  newbit = "0"
  IF value BIT bitptr SET THEN
    newbit = "1"
  ENDIF
  SERTXD (newbit)
NEXT bitptr
RETURN
 

hippy

Technical Support
Staff member
One common trick is to keep 'b0' free for any use in your program, move the data you want to show as binary into 'b0' then use SERTXD to show the bit values -

Code:
b0 = %10111010
Gosub ShowBin
End

ShowBin:
  SerTxd( #bit7, #bit6,#bit5, #bit4, #bit3, #bit2, #bit1, #bit0 )
  Return
You can in-line the SERTXD, even put it in a macro ...

Code:
#Macro ShowBin( description, value )
  b0 = value
  SerTxd( description, TAB, #bit7, #bit6,#bit5, #bit4, #bit3, #bit2, #bit1, #bit0, CR, LF )
#EndMacro

b11 = %10111010
ShowBin( "Year", b11 )
 
Thanks Hippy & Westaust. That's excellent, I guessed that there would be better ways of doing this, but hadn't found anything in the forum or code snippets.
 
Having now tried the macro, the output looks great and saves code in the body of the program, and has taught me a new skill: the use of macros, which I hadn't tried before. Thanks again.

One tiny addition though:
Code:
#Macro ShowBin( description, value )
  b0 = value
  SerTxd(description,TAB,#bit7,#bit6,#bit5,#bit4," ",#bit3,#bit2,#bit1,#bit0,CR,LF)
#EndMacro

b11 = %10111010
ShowBin( "Year", b11 )
Adding a space between the nibbles makes it so much easier to read the output.
 

hippy

Technical Support
Staff member
Adding a space between the nibbles makes it so much easier to read the output.
You are absolutely right, and that's an especially good recommendation when dealing with BCD. I don't know why but with just 4-digit groups 'it's obvious', with more than that one always ends up counting bits!

If you do start to get low on program memory you can replace the SERTXD within the #MACRO to be a GOSUB to a routine which just has the SERTXD and a RETURN outside the #MACRO.
 
Top