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.

hex to decimal conversion code

Status
Not open for further replies.

esconele

New Member
hello,
i want a simple assembly code for conversion of hex values to decimal values if anybody having ideas pls help me . i'm using at89c51 microcontroller.
 
I'm not familiar with the at89c51 microcontroller but the principle is independent of the processor. I did this with a PIC 16F84.

To convert an 8 bit byte to BCD, I started by subtracting 100 (ie. ox64).
test if the remainder is negative, if so then the 100s digit is 0, if not test if it is <100, if so the 100s digit is 1 if not, subtract 100 again & make the 100s digit = 2. Now subtract 10 from the remainder and test if the remainder negative, if so the 10s digit is 0, if not, test if it is <10, if so, then the 10s digit = 1, if it is >= 10, then subtract 10 again, etc. When the remainder is <10 then use it as the units digit.

I'll see if I can find the code and post later.
 
Here is the code. I used a 16F628, not a 16F84. The variable tmr_u is the time measured in tenths of microseconds. The code converts this into BCD for display on a LCD display.

Code:
	movfw	tmr_u		;convert tmr_u to BCD
	movwf	nv		;nv is tenths of micro sec.

	clrf	tv		;tv represents micro sec tens
	clrf	uv		;uv represents micro sec units

	movlw	d'100'		;
tens	subwf	nv, f		;nv = nv - 100
	btfss	STATUS, C	;is nv < 0
	goto	ee		;yes, so restore nv 
	incf	tv, f		;no, increment tv
	goto	tens		;

ee	addwf	nv, f		;nv = nv + 100

	movlw	d'10'		;
units	subwf	nv, f		;nv = nv - 10
	btfss	STATUS, C	;is nv < 0
	goto	ff		;yes, so restore nv
	incf	uv, f		;no, increment uv
	goto	units

ff	addwf	nv, f		;nv = nv + 10
 
Last edited:
Since the 8051 has a hardware divide instruction you can use that to compute the quotient digits. The result also gives the remainder so you can chain the caluclation.
 
hex to decimal conversion

hi,

I dont know assembly much...but u can try in keilC.

just declare an array say a[3];

a[2]=hexnumber%10; //single digit
hexnumber=hexnumber/10;
a[1]=hexnumber%10; //10th digit
a[0]=hexnumber/10; //100th digit
 
at24c16a eeprom problem

hello,
i'm using at24c16a with at89c51 but problem is that its not giving the data which i'm writing to it where i'm doing wrong pls help me here i've attached schematic and code in which i'm displaying some data on lcd but it should be stored in eprom first and whenever power fails on next reset it should give the last data stored in eprom .
thank you
$MOD51
ORG 0000H
LJMP MAIN
SCL BIT P3.5
SDA BIT P3.4


LASTREAD BIT FLAGS.0
RD_WR_ROM BIT FLAGS.4
ACK BIT FLAGS.5
BUS_FLT BIT FLAGS.6
_2W_BUSY BIT FLAGS.7
BITCNT DATA 21H
BYTECNT DATA 22H

ADDHI DATA 050H ; ADDRESS LOCATION FOR 24C16 SERIAL-
; EEPROM
ADDLO DATA 051H
COUNT DATA 052H ; STORES THE VALUE OF NO OF INTERRUPT
TDATA DATA 053H
RWDATA DATA 054H


SCL_HIGH MACRO
SETB SCL ; SET SCL HIGH
JNB SCL,$ ; LOOP UNTIL STRONG 1 ON SCL
ENDM


MAIN:

CLR RS0
CLR RS1

CLR P3.6 ;RESET LOW
LCALL DELAY
SETB P3.6
LCALL BEGIN

SETB SDA ; ENSURE SDA HIGH
SCL_HIGH ; ENSURE SCL HIGH
CLR ACK ; CLEAR STATUS FLAGS
CLR BUS_FLT
CLR _2W_BUSY
LCALL SEND_START
MOV A,#00H ;READING FROM LOCATION 0000H FOR COUNT
RL A
ORL A,#0A0H
LCALL SEND_BYTE
MOV A,#00H
LCALL SEND_BYTE
MOV A,#00H
LCALL SEND_BYTE
LCALL SEND_STOP


WER:

LCALL NUMBER1



JNB P0.1,SET12
SJMP WER



SET12:LCALL ESCCLEAR
LJMP SETDATA




BEGIN:
LCALL LCD_INIT
MOV 66H,#00H
MOV R3,#04H
MOV R1,#064H
;MOV R2,#010H
MOV 99H,#00H
MOV 90,#00H ;TO SCROLL ESCON
MOV 91,#01H ;ESC1
MOV 92,#02H ;ESC2
MOV 93,#02H ;ESC3
MOV 94,#02H ;ESC4
MOV 95,#08H ;ESC5
MOV 96,#02H
RET
READ_BYTE:
MOV BITCNT,#08H; SET COUNTER FOR 8-BITS DATA
MOV A,#00H
SETB SDA ; SET SDA HIGH TO ENSURE LINE
; FREE
READ_BITS:
SCL_HIGH ; TRANSITION SCL LOW-TO-HIGH
MOV C,SDA ; MOVE DATA BIT INTO CARRY
RLC A ; ROTATE CARRY-BIT INTO ACC.0
CLR SCL ; TRANSITION SCL HIGH-TO-LOW
DJNZ BITCNT,READ_BITS
; LOOP FOR 8-BITS
JB LASTREAD,ACKN
; CHECK TO SEE IF THIS IS
; THE LAST READ
CLR SDA ; IF NOT LAST READ SEND ACK-BIT

ACKN:
SCL_HIGH ; PULSE SCL TO TRANSMIT ACKNOWLEDGE
CLR SCL ; OR NOT ACKNOWLEDGE BIT
RET

SEND_START:
SETB SCL
LCALL DELU
SETB SDA
LCALL DELU
CLR SDA
CLR SCL
RET

DELU:MOV 23H,#02H
TU:DJNZ 23H,TU
RET

SEND_STOP:
SETB SCL
LCALL DELU
CLR SDA
LCALL DELU
SETB SDA ; DELAY FOR BUS TIMING
RET
DELAY_1:

NOP
RET
SEND_BYTE:
MOV BITCNT,#08H; SET COUNTER FOR 8-BITS
SB_LOOP:
JNB ACC.7,NOTONE; CHECK TO SEE IF BIT-7 OF
SETB SDA ; ACC IS A 1, AND SET SDA HIGH
JMP ONET
NOTONE:
CLR SDA ; CLR SDA LOW
ONET:
SCL_HIGH ; TRANSITION SCL LOW-TO-HIGH
RL A ; ROTATE ACC LEFT 1-BIT
CLR SCL ; TRANSITION SCL LOW-TO-HIGH
DJNZ BITCNT,SB_LOOP; LOOP FOR 8-BITS
SETB SDA ; SET SDA HIGH TO LOOK FOR
SCL_HIGH ; ACKNOWLEDGE PULSE
CLR ACK
JNB SDA,SB_EX ; CHECK FOR ACK OR NOT ACK
SETB ACK ; SET ACKNOWLEDGE FLAG FOR
; NOT ACK
SB_EX:
ACALL DELAY_1 ; DELAY FOR AN OPERATION
CLR SCL ; TRANSITION SCL HIGH-TO-LOW
ACALL DELAY_1 ; DELAY FOR AN OPERATION
RET



NUMBER1:

SETDATA:LCALL ESCCLEAR

MOV 23H,#00H
LCALL SKIP
MOV R2,#01H
MOV A,2FH
MOV R0,A
LCALL ETWRITE

MOV 23H,#010H
LCALL SKIP
MOV R2,#02H
MOV A,2FH
MOV R0,A
LCALL ETWRITE

LJMP WER


SKIP:
TSZ: JB P0.2,WTZ
LCALL DRT1
RET
WTZ: JB P0.3,TSZ
MOV DPTR,#AA
MOV 2FH,#01H
ACALL DISPLAY
LCALL DRT1
RET




SAVEDATA:CJNE A,#01H,ANS1
MOV DPTR,#AA
RET
ANS1: CJNE A,#02H,ANS2
MOV DPTR,#BB
RET
TRIGR: MOV B,#03H
MOV A,90
MUL AB
MOV DPTR,#TRIGRG
JMP @A+DPTR
TRIGRG: LJMP TRIGR1
LJMP TRIGR2
LJMP TRIGR3
LJMP TRIGR4
LJMP TRIGR5
LJMP TRIGR6
LJMP TRIGR7
LJMP TRIGR8
LJMP TRIGR9
LJMP TRIGR10
LJMP TRIGR11
LJMP TRIGR12
LJMP TRIGR13
LJMP TRIGR14
LJMP TRIGR15

TRIGR1:
MOV R5,#01H
LCALL EEREAD
MOV A,2EH
LCALL SAVEDATA
CLR A
LCALL WRITESCRN
RET

TRIGR2:
MOV R5,#02H
LCALL EEREAD
MOV A,2EH
LCALL SAVEDATA
CLR A
LCALL WRITESCRN
RET


;---------------------------------------------------------------------------------------------------------------------------------------------------

ETWRITE:

LCALL SEND_START
MOV A,#0A0H
LCALL SEND_BYTE
MOV A,R2
LCALL SEND_BYTE
MOV A,R0 ;DATA
LCALL SEND_BYTE
LCALL SEND_STOP

RET
;-----------------------------------------------------------------------------------------------------------------------------

EEREAD:

LCALL SEND_START
MOV A,#0A0H
LCALL SEND_BYTE
MOV A,R5 ;EITHER TH/TL COMMAND BYTE
LCALL SEND_BYTE
LCALL SEND_START ; REPEATED START COMMAND
MOV A,#0A1H
LCALL SEND_BYTE
LCALL READ_BYTE ; READ A BYTE OF DATA
MOV 2EH,A
SETB SDA ; MOVE DATA IN SCRATCHPAD MEMORY
LCALL SEND_STOP

RET



END
 
I sure wish people would use code tags. Put "[ code ]" (remove spaces) before source code and place "[ /code ]" (remove spaces) after the source code. It will be nicely indented. if you go advanced, there is a menu item for code.

on some micros, division and mod can be a very time consuming operations. If the value is the result of simple counting or similar, you might want to maintain the it as BCD. BCD addition/subtraction is pretty easy and formatting it for output is trivial. each nibble represents a digit and has values of 0 to 9.
 
philba is absolutely correct in his observation. The original question was about an 8051 variant which has a very efficient hardware divide instruction which gives both the quotient and the remainder in a single 1-byte instruction.
 
philba said:
I sure wish people would use code tags. Put "[ code ]" (remove spaces) before source code and place "[ /code ]" (remove spaces) after the source code. It will be nicely indented. if you go advanced, there is a menu item for code.
Thanks for this hint. I guess many posters are like me and do not know that this option is available. I editied my post above to try this option, but I could not see the menu item for code in the "go advanced" so I inserted the [ code ] and [ /code ] manually.
 
ljcox said:
Thanks for this hint. I guess many posters are like me and do not know that this option is available. I editied my post above to try this option, but I could not see the menu item for code in the "go advanced" so I inserted the [ code ] and [ /code ] manually.

I just type (without the . in there, needed that to make it readable)

[code.] "without the . and press ENTER"
paste your code here
[/code.] "without the . and press ENTER"
 

Attachments

  • electro.png
    electro.png
    2 KB · Views: 196
Last edited:
Test
Code:
	movfw	tmr_u		;convert tmr_u to BCD
	movwf	nv		;nv is tenths of micro sec.

	clrf	tv		;tv represents micro sec tens
	clrf	uv		;uv represents micro sec units
This would also be useful for inserting tables ie. to retain the format.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top