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.

converting binary number to ASCII code

Status
Not open for further replies.

david_mora

New Member
hi people, here is my problem: y do mathematic operations y binary (microcontrollers code) but i need to print the result in an LCD. I kown that having a BCD code plus 0x30 is equal to ASCII, but i don't know how to convert binary code to BCD (i know it in paper, but no in assembler way)..... can you help me please????
 
This routine is copied from the piclist and modified a bit - Takes a 8 bit binairy value in BinDisplay and coverts it to BCD into Val1, Val2 and Val3

If you need a 16 bit routine then go to nigels tutorials (www.winpicprog.cu.uk) and look at the LCD tutor, it has a 16bit routine

Code:
Bin2BCD

		CLRF    Val1 
        SWAPF   BinDisplay, W			;w  = A0*16+A1
        ADDWF   BinDisplay, W 			;w  = A0+A1
        ANDLW   b'00001111' 			;w  = A0+A1 % 16

        SKPNDC 							;if A0+A1 > 16
        ADDLW  	0x16 					;  w  += 16

        SKPNDC 							;if w % 16 > 10
        ADDLW 	0x06 					;  w  += 6

        ADDLW   0x06 					;w  += 6

        SKPDC 							;if w < 10
        ADDLW  	-0x06 					;  w  -= 6

        BTFSC   BinDisplay,4 
        ADDLW   0x16 - 1 + 0x6 

        SKPDC 
        ADDLW  -0x06 

        BTFSC   BinDisplay, 5 
        ADDLW  	0x30 

        BTFSC   BinDisplay, 6 
        ADDLW  	0x60 

        BTFSC   BinDisplay, 7 
        ADDLW  	0x20 

        ADDLW   0x60 
        RLF     Val1, F 

        BTFSS   Val1, 0 
        ADDLW   -0x60 

        MOVWF   Val3 
        BTFSC   BinDisplay, 7 
        INCF   	Val1, F

		  SWAPF	  Val3, W					
		  ANDLW	  b'00001111'			
		  MOVWF	  Val2					
		
		  MOVLW	  b'00001111'
		  ANDWF	  Val3, F				
		  RETURN
 
For my LCD purposes, I use the follow code to convert Hex to Dec. I am sure others may be more optimized, but this is just my own example.

Code:
HEX_TO_DEC
;CONVERTERING HEX TO DEC.
         CLRF     HUNDREDS
         CLRF     TENS
         CLRF     ONES
CHECK_H       
         MOVF     HEXNUM, W
         MOVWF    TEMP
         MOVLW    0X64
         SUBWF    TEMP, F
         BTFSS    STATUS, C
         BTFSC    STATUS, Z	 
         GOTO     $ + 2
         GOTO     CHECK_T
	 
         INCF     HUNDREDS, F
         MOVF     TEMP, W
         MOVWF    HEXNUM
         GOTO     CHECK_H
CHECK_T
         MOVF     HEXNUM, W
         MOVWF    TEMP
         MOVLW    0X0A
         SUBWF    TEMP, F
         BTFSS    STATUS, C
         BTFSC    STATUS, Z	 
         GOTO     $ + 2
         GOTO     CHECK_O
       
         INCF     TENS, F
         MOVF     TEMP, W
         MOVWF    HEXNUM
         GOTO     CHECK_T
CHECK_O
         MOVF     HEXNUM, W
         MOVWF    TEMP
         MOVLW    0X01
         SUBWF    TEMP, F
         BTFSS    STATUS, C
         BTFSC    STATUS, Z	
         GOTO     $ + 2
         GOTO     ENDHEXDEC
       
         INCF     ONES, F
         MOVF     TEMP, W
         MOVWF    HEXNUM
         GOTO     CHECK_O
       
ENDHEXDEC
         RETURN


Here is for 16 bits. I hope this does not exceed a single posting limit.
Shut, the bottom half of the display is misbehaving.

Code:
;---------------------------------------
;PREREQUISITE:	LOADF	HIGH_BYTE
;		LOADF	LOW_BYTE	
HEX_TO_DEC
	;0X2710=10,OOO,  0X3E8=1,000,  0X64=100,  0X0A=10,  0X01=1
	;0X270F = 9999

	MOVF_F	LOW_BYTE, TEMP_LOW
	CLRF	THOUSANDS
         CLRF     HUNDREDS
         CLRF     TENS
         CLRF     ONES
CHECK_H       
         MOVF_F   TEMP_LOW, TEMP
         MOVLW    .100
         SUBWF    TEMP, F
         BTFSC    STATUS, C
         GOTO     $ + 2
         GOTO     CHECK_T
	 
         INCF     HUNDREDS, F
         MOVF_F   TEMP, TEMP_LOW
         GOTO     CHECK_H
CHECK_T  MOVF_F   TEMP_LOW, TEMP
         MOVLW    .10
         SUBWF    TEMP, F
         BTFSC    STATUS, C
         GOTO     $ + 2
         GOTO     CHECK_O
       
         INCF     TENS, F
         MOVF_F   TEMP, TEMP_LOW
         GOTO     CHECK_T
CHECK_O  MOVF_F   TEMP_LOW, TEMP
         MOVLW    .1
         SUBWF    TEMP, F
         BTFSC    STATUS, C
         GOTO     $ + 2
         GOTO     HEXDEC2
       
         INCF     ONES, F
         MOVF_F   TEMP, TEMP_LOW
         GOTO     CHECK_O
HEXDEC2


HI_0	BTFSC	HIGH_BYTE, 0
	GOTO	$ + 2
	GOTO	HI_1

	MOVLW	.2
	ADDWF	HUNDREDS, F
	MOVLW	.5
	ADDWF	TENS, F
	MOVLW	.6
	ADDWF	ONES, F
HI_1	BTFSC	HIGH_BYTE, 1
	GOTO	$ + 2
	GOTO	HI_2

	MOVLW	.5
	ADDWF	HUNDREDS, F
	MOVLW	.1
	ADDWF	TENS, F
	MOVLW	.2
	ADDWF	ONES, F
HI_2	BTFSC	HIGH_BYTE, 2
	GOTO	$ + 2
	GOTO	HI_3

	MOVLW	.1
	ADDWF	THOUSANDS, F
	MOVLW	.2
	ADDWF	TENS, F
	MOVLW	.4
	ADDWF	ONES, F
HI_3	BTFSC	HIGH_BYTE, 3
	GOTO	$ + 2
	GOTO	HI_4

	MOVLW	.2
	ADDWF	THOUSANDS, F
	MOVLW	.4
	ADDWF	TENS, F
	MOVLW	.8
	ADDWF	ONES, F
HI_4	BTFSC	HIGH_BYTE, 4
	GOTO	$ + 2
	GOTO	HI_5
	
	MOVLW	.4
	ADDWF	THOUSANDS, F
	MOVLW	.9
	ADDWF	TENS, F
	MOVLW	.6
 	ADDWF	ONES, F
HI_5	BTFSC	HIGH_BYTE, 5
	GOTO	$ + 2
	GOTO	ENDBITSUM

	MOVLW	.8
	ADDWF	THOUSANDS, F
	MOVLW	.1
	ADDWF	HUNDREDS, F
	MOVLW	.9
	ADDWF	TENS, F
	MOVLW	.2
	ADDWF	ONES, F
ENDBITSUM


	;PROCESS OVERFLOW	
ONES_OVER
	MOVLW	.9
	SUBWF	ONES, W
	BTFSC	STATUS, Z
	GOTO	TENS_OVER
	BTFSS	STATUS, C
	GOTO	TENS_OVER

	INCF	TENS, F
	MOVLW	.10
	SUBWF	ONES, F

TENS_OVER
	MOVLW	.9
	SUBWF	TENS, W
	BTFSC	STATUS, Z
	GOTO	HUNDREDS_OVER
	BTFSS	STATUS, C
	GOTO	HUNDREDS_OVER

	INCF	HUNDREDS, F
	MOVLW	.10
	SUBWF	TENS, F
	
HUNDREDS_OVER
	MOVLW	.9
	SUBWF	HUNDREDS, W
	BTFSC	STATUS, Z
	GOTO	ENDHEX_TO_DEC
	BTFSS	STATUS, C
	GOTO	ENDHEX_TO_DEC

	INCF	THOUSANDS, F
	MOVLW	.10
	SUBWF	HUNDREDS, F


ENDHEX_TO_DEC
         RETURN
 
Here is an 8-bit routine that I use on the enhanced core 18F series of PICs. It can very easily be adapted to handle 16 bit numbers.

The value being converted is stored in "convertbuf." The converted value is stored in "decl, decm, dech".

Code:
;*************************************
; This function takes an 8 bit hex   *
; value and converts it into 3 ASCII *
; values for display purposes        *
;*************************************

hextodec
	clrf	decl
	clrf	decm
	clrf	dech

loop100
	movlw	D'100'			; Check to see if value is 100 or greater
	cpfslt	convertbuf, 1		; if 100 or higher bra 100 handler
	bra	handler100		; otherwise check the 10s

loop10
	movlw	D'10'			; Check to see if value is 10 or greater
	cpfslt	convertbuf, 1		; if 10 or higer bra 10 handler
	bra	handler10

	movff	convertbuf, decl	; otherwise move remainder to 1s
	bra	makeascii		; and then make into ASCII

handler100
	incf	dech, 1, 1		; increment dech, store in dech, banked
	movlw	D'100'			; subtract 100 from
	subwf	convertbuf, 1, 1     	;  convertbuf, store it convertbuf, banked
	bra	loop100			; start process over again
		
handler10
	incf	decm, 1, 1      	; increment decm, store in decm, banked
	movlw	D'10'			; subtract 10 from
	subwf	convertbuf, 1, 1	;  convertbuf, store in convertbuf, banked
	bra	loop10

makeascii
	movlw	0x30			; Add 30h to:  (Adding 30h converts hex to ASCII)
	addwf	decl, 1, 1		;  decl - stored in decl - banked
	addwf	decm, 1, 1		;  decm - stored in decm - banked
	addwf	dech, 1, 1		;  dech	- stored in dech - banked

	return



-Bill
 
thanks but i need a little more help

well thanks a lot to all people who answer my question, i think i must be more clearly.... so here it is, my number is only an 8 bit number, but i need to print in the lcd 4 digits. the idea is to make a stepper motor controller using pic 16f877 with keypad and lcd, so the degrees go from 0 º to 360º, but because of the motor resolution (0.9 º) i'm supposed to print decimal values, but i do not know how to do it so i am printing dDEG, i mean instead of printing 360 DEG i will print 3600 dDEG, instead of pirnting 1,8 DEG i will print 18 dDEG, got the idea????????, so as you saw 3600 is a 4 digit number, so i will be more thanfull if you have a routin that converts a number to a 4 digit ASCII code, or maybe you can explain how to do it, so i will do the asm code, the problem is that i have no idea how toi do it!!!!!!!! thanks a lot :)
 
If you are only using a byte to store the angle, then I assume that:
0º = 0
360º = 256

Is that your internal representation of the motor position? If so then your internal precision is actually 1.40625º, not 0.9. So what will happen is that in some cases a single increment of your internal value will result in two steps of the motor. In other words it will be impossible to put the motor into every position it can physically achieve, if that will be an issue.

If you are still going to use a byte to represent the motor position, then you could simply use tables to store the preculcated ASCII representations of the position. You have 256 values times 4 characters. However your value will only be from 0 to 9, so you can pack 2 characters into a single byte. So you would need 512 bytes for the table.

Just put one value (0 to 9) in the low nibble and the other in the high nibble. To extract the ascii value mask (ANDF) the byte by 0x0f, then add d'48' to convert it to ASCII. Then swap the nibbles (SWAPF) and do the mask / add again to get the second character.

Dan East
 
yeah now i realized, you are right, well, as i wrote before, i do not konw to handle decimal values, so instead of printing 360 GED in the LCD i'll print 3600 dDEG. and now the problem is that the nember entered must be stored in 2 registers, and then, after multiplying, substracting, adding, etc etc, i must convert the binary number (2 registers) into 4 BDC digits and then adding 0x30 i finally will obtain ASCII code. thank you Dan East.
by the case, did somebody know how to operate a number of 2 bytes???
now my problem has increased..... help is needed, the operations i must do are:
multiplication (16 bits X 8 bits)
substraction(16 bits - 16 bits)
convertion from binary to BCD (16 bits to 4 BCD digits)

thans a lot people.
 
david_mora said:
yeah now i realized, you are right, well, as i wrote before, i do not konw to handle decimal values, so instead of printing 360 GED in the LCD i'll print 3600 dDEG. and now the problem is that the nember entered must be stored in 2 registers, and then, after multiplying, substracting, adding, etc etc, i must convert the binary number (2 registers) into 4 BDC digits and then adding 0x30 i finally will obtain ASCII code. thank you Dan East.
by the case, did somebody know how to operate a number of 2 bytes???
now my problem has increased..... help is needed, the operations i must do are:
multiplication (16 bits X 8 bits)
substraction(16 bits - 16 bits)
convertion from binary to BCD (16 bits to 4 BCD digits)

thans a lot people.

Look on the PICList, everything you need is there!.
http://www.piclist.com
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top