看你的十六进制数是几个字节的,
如果是单字节,则作两次除法:先除以100,商即百位数;再用余数除以10,商即十位数,余数为个位数;
如果是≥2字节,以上的运算则显得过于占用程序处理时间,要用到移位运算,设置数据寄存器区(2字节十六进制数则需4个寄存器区和一个循环计数器),每左移一位后进行数据调节:(以下给出一个样例程序,PIC中档单片机的汇编程序)
;###############################################
; 双字节16进制数据转换为5位BCD码数据程序
;###############################################
; Performance :
; Program Memory : 35
; Clock Cycles : 885
;
;**********************************
;源数据放在R0(L),R1(H)中
;输出数据放入R2(L),R3(M),R4(H)中
;R7: 循环次数计数器(VALUE=16)
;R5: 中间数据寄存器
;FSR
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
HEX16TOBCD:
BCF STATUS,C
MOVLW .16
MOVWF R7
CLRF R2
CLRF R3
CLRF R4
HEX16TOBCD_1:
RLF R0
RLF R1
RLF R2
RLF R3
RLF R4
DECFSZ R7
GOTO ADJ_DEC
RETURN
ADJ_DEC:
MOVLW R2
MOVWF FSR
CALL ADJ_BCD
MOVLW R3
MOVWF FSR
CALL ADJ_BCD
MOVLW R4
MOVWF FSR
CALL ADJ_BCD
GOTO HEX16TOBCD_1
;***************************
ADJ_BCD:
MOVLW 3
ADDWF INDF,W
MOVWF R5
BTFSC R5,3 ; test if result > 7
MOVWF INDF
MOVLW 30
ADDWF INDF,W
MOVWF R5
BTFSC R5,7 ; test if result > 7
MOVWF INDF ; save as MSD
RETURN
程序经过仿真调试通过,如下所示:
MOV R0, TL0
MOV R1, TH0
CLR A
MOV R2, A;先清零
MOV R3, A
MOV R4, A,
MOV R5, #16;共转换十六位数
LOOP:
CLR C
MOV A, R0;从待转换数的高端移出一位到Cy
RLC A
MOV R0, A
MOV A, R1
RLC A
MOV R1, A
MOV A, R4;送到BCD码的低端
ADDC A, R4;带进位加。自身相加,相当于左移一位
DA A ;十进制调整,变成BCD码
MOV R4, A
MOV A, R3
ADDC A, R3
DA A
MOV R3, A
MOV A, R2
ADDC A, R2
MOV R2, A
DJNZ R5, LOOP;共转换十六位数
;-------至此,已经把TH1 TL1中的数字,转换成BCD码,送到了R2 R3 R4。
;-------下面,分别存入R4 R3 R2 R1 R0。
MOV A, R4
MOV B, #16
DIV AB
MOV R1, A
MOV R0, B
MOV A, R2
MOV R4, A
MOV A, R3
MOV B, #16
DIV AB
MOV R3, A
MOV R2, B
RET
希望对你有所帮助!
用除法
例如 0xFF 转换成十进制数,百位十位个位分别存在R1、R2、R3中
在51单片机中寄存器A中的数除以寄存器B中的数,商存在A,余数存在B
MOV A,#0FFH
MOV B,#100
MUL A,B
MOV R1,A //存百位
MOV B,A
MOV B,#10
MUL A,B
MOV R2,A //存十位
MOV R3,B //存个位
你确定你要的是十六进制转换成十进制的程序?不是二进制转成十进制的吗?单片机中的数据可都是二进制的,只是通常用十六进制表示罢了,我以前也犯过这个错误
mov r6,#00h;存转化后的数的低位
mov r5,#00h;存转化后的数的高位
mov r7,#0ffh;为要转化的
mov a,r7
cjne a,#00h,loop;判断要转化的数是否为0
ajmp loop1
loop;mov a,r6
add a,#01h
da a
mov r6,a
addc a,#00h
da a
mov r5,a
djnz r7,loop
loop1:sjmp $