Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Convert hex to ascii - need good explanation of principle

Status
Not open for further replies.

bbiandov

Member
Hello, despite this being a super popular subject I still can not find a simple asm routine that explains how exactly the conversion works. The examples that I have found use special instructions and I find the explanation insufficient (or the usual.. well use gcc answer)

Is there a well written primer on the subject and preferbly with Atmel asm examples? Ideally the examples will run on 90S2313.

Thank you
Boyan
 
Hi

I don't have any code for you but I can give you a general idea of what you need to do. I assume you want to convert a hex number (eg. 3fh) to ascii characters (eg. for display). Each Hex digit coresponds to 4 bits. So to convert an 8 bit number you mask (and with 0Fh)to get the first 4 bits. you then need to check if the number is 0 to 9 or A to F. If its 0 - 9 you add the ascii value of '0' to get the ascii character. Similarly you add 'A' for A-F. Right bitshift the original value 4 to get the next 4 bits and repeat.

Hope this helps
Brent
 
bmcculla, this is very helpful thank you. however what i really want to do is read a register and then print its value into ascii. so i should have asked how do you convert binary to ascii, sorry my bad. for example how do you read the value 01h (one) and then send 31h (the ascii code for one) to the LCD? things get complicated when the ascii has to be two and three digits?
 
Well do it like bmcculla says...

Take the lowest nibble of the number you need to convert, if it is from 0 to 9 just add 30h to get the ascii code and do the same for the next nibble. If the first number is from A to F, then add this value to the next nibble of the number you need to convert, and repeat the entire procedure again, until you reach the upper nibble.
 
hmm that does not seem to work or may be I cant get it. Lets use an example. Register x= binary 01100110 or decimal 102

how would you send to LCD three ascii codes as a result of your calculations? Namely those must be the codes for (1=49) (0=48) and (2=50) so how does 102 produce 49,48 & 50?
 
It is done in the following way
1) Declare a 16-bit variable (unsigned integer) for BCD result
2) Divide the binary number by hundred and store the quotient in Upper Byte of result
3) Again divide the binary number by 10. Store the quotient in Upper Nibble of Lower 8-bits of result. And store remainder in lower nibble of lower 8-bits of result.
4) You now have 3-digit BCD number in your 16-bit result variable.
Now take each BCD digit and convert it to ASCII character equivalent using following steps.
1) Add 144 to the digit and save result in one register.
2) Decimal Adjust the result
3) Once again add 64 to the result
4) and Decimal Adjust the result

See the following 8051 code for doing above tasks:
Code:
;****************************************************************************
;
;  Description:
;	Convert Value In Acc From Hex To BCD.  
;
;  Entry Requirements:
;	Acc Has Value To Convert To BCD
;
;  On Exit:
;	DPTR Has Value Of Acc In BCD
;
;  Affected:
;	PSW.CY, PSW.Z, PSW.P, Acc, DPTR
;
;  Stack:
;	2 Bytes, Not Including Space Used By Called Routines
;
;  Comments:
;	Values Greater Than 255 Will Not Work Properly.  If Acc == 12, DPTR
;	== 0012.  If Acc = 255, DPTR = 0255.
;
UTIL_BINTOBCD12	proc
		push	b			; Save B
		push	acc			; Save Acc
		mov	b,#100			; Divide By 100
		div	ab			; Do Divide
		mov	dph,a			; Store In DPH
		pop	acc			; Recover Acc
		mov	b,#10			; Divide By 10
		div	ab			; Do Divide
		swap	a			; Move Result To High Of A
		orl	a,b			; OR In Remainder
		mov	dpl,a			; Move To DPL
		pop	b			; Recover B
		ret				; Return To Caller
		endproc
;
;****************************************************************************

;****************************************************************************
;
;  Description:
;	Convert Value In Low 4 Bits Of Acc To A Hex Digit
;
;  Entry Requirements:
;	Low 4 Bits Of Acc Have Value To Convert To '0'..'9', 'A'..'Z'
;
;  On Exit:
;	Value Of Low 4 Bits In ASCII
;
;  Affected:
;	PSW.CY, PSW.Z, PSW.P, Acc
;
;  Stack:
;	0 Bytes, Not Including Space Used By Called Routines
;
;  Comments:
;	Near Trick From A Z80 Book Circa 1982.  Don't Know Who The Original
;	Author Is.
;
UTIL_BINTOASC	proc
		anl	a,#00fh 		; Keep Only Low Bits
		add	a,#090h 		; Add 144
		da	a			; Decimal Adjust
		addc	a,#040h 		; Add 64
		da	a			; Decimal Adjust
		ret				; Return To Caller
		endproc
;
;****************************************************************************

The author of this code is John C. Wren
 
Thanks kinjalgp,

I was able to write the code in Atmel asm but I did have to make modifications in the logic. This is because I do not have decimal adjust instructions for dealing with BCDs. The modification of the logic was as follows. After dividing by 100 and 10 I end up with those values: (we are conveting the value of decimal 102 into ascii using 3 8-bit registeres for clarity of the example):

x=1; y=10; z=2

This is all well because now you just need to add 48 but y can be from 0 to 19 and its a sticking point. I have to test whether y>9 and if true subtract 10 in order for the ascii math to come out correctly. So in this particular example I need to subtract 10 so that y=0 and then 0+48=48 which is the ascii of "0". Is there a better, more efficient way to do this? Thanks
 
I don't know any better way of doing this. If anyone knows it please come ahead.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top