更简单的算法:主要在HEX至BCD码转换上肯定有,映像中见过一个通用程序,还是多字节不定长的,只有40、50行指令,记得当时感觉算法挺好,只是没记住。
你设想的算法可能不对,不知你考虑到没有,比如ABC0H,A转换成10进制数是10,A0则是160,A00是2560,A000是40960。比如最后一个40960,既便不算最后一个0,也需要4位有效数字空间。所以16进制不同的位置上的数不能简单的转换。这种思路主要错误原因是无意中算法中默认了比如A000中后面3个0为10进制的。
BUFFER1 EQU 30H 运算缓冲区1起始地址
BUFFER1_L EQU 33H 4字节运算缓冲区1截止地址
BUFFER2 EQU 38H 运算缓冲区2起始地址
BUFFER2_L EQU 3BH 4字节运算缓冲区2截止地址
ORG 0000H
LJMP Main
ORG 0100H
main:
MOV SP, #60H
MOV R2, #0ABH
MOV R3, #0C0H
LCALL DIV_10H R2R3除以16变为0ABCH,仍存在R2R3中
LCALL MUL_24 R2R3乘以24,结果保存在R5R6R7中
LCALL CLR_BCDMEMORY 清除最终结果存放缓冲区
LCALL HEXTOBCD_5 结果转换成BCD码,结果放在BUFFER1开始的4个字节中
JMP $ 原地循环
--------------------------------------------
子程序CLR_BCDMEMORY
功能: 4字节运算结果缓冲区清0
--------------------------------------------
CLR_BCDMEMORY:
MOV R0, #BUFFER1
MOV R2, #04H
CLR A
C_LOOP1:
MOV @R0, A
INC R0
DJNZ R2, C_LOOP1
RET
--------------------------------------------
子程序HEXTOBCD_5
功能: 5位16进制数转换成BCD码
入口: 原数存放在R5R6R7中,R5高8位不考虑
出口: 结果放在:BUFFER1中开始的4个字节
说明: 最大转换值0FFFFFH
--------------------------------------------
HEXTOBCD_5:
MOV A,#04H 16进制万位标志
LCALL GET_MOD 得到此位对应的10进制加权值并保存到BUFFER1中
MOV A, R5 万位数值为累加次数
LCALL MUL_4BYTE 累加相应次数,结果保存到BUFFER1中
MOV A,#03H 16进制千位标志
LCALL GET_MOD
MOV A, R6
SWAP A
LCALL MUL_4BYTE
MOV A,#02H 16进制百位标志
LCALL GET_MOD
MOV A, R6
LCALL MUL_4BYTE
MOV A,#01H 16进制十位标志
LCALL GET_MOD
MOV A, R7
SWAP A
LCALL MUL_4BYTE
MOV A,#00H 16进制个位标志
LCALL GET_MOD
MOV A, R7
LCALL MUL_4BYTE
RET
--------------------------------------------
子程序MUL_4BYTE
功能: 4字节10进制累加子程序
入口: 被加数:放在BUFFER1开始的4个字节
加数:放在BUFFER2开始的4个字节
A:BUFFER2内容加到BUFFER1的次数,A<16
出口: 结果放在:BUFFER1中开始的4个字节
--------------------------------------------
MUL_4BYTE:
ANL A, #0FH
CJNE A, #00H, M_BEGIN
RET
M_BEGIN:
MOV R2, A
M_LOOP1:
MOV R0, #BUFFER1_L
MOV R1, #BUFFER2_L
MOV R3, #04H
CLR C
M_LOOP2: 从个位开始逐字节相加
MOV A, @R0
ADDC A, @R1
DA A 10进制调整
MOV @R0,A
DEC R0
DEC R1
DJNZ R3, M_LOOP2
DJNZ R2, M_LOOP1
RET
--------------------------------------------
子程序GET_MOD
功能: 取4字节16进制数某位的10进制BCD码权值
入口: A:位标志,16进制数个位为0,十位为1,类推,A<7
出口: 结果依次存放在:BUFFER2中,高位在低地址
说明: 16进制数有限制,最大05F5E0FFH
--------------------------------------------
GET_MOD:
PUSH PSW 压栈保护所有用到的寄存器内容
PUSH 00H
PUSH 01H
PUSH 02H
MOV PSW, #00H
MOV R0, #BUFFER2
MOV R2, #04H
MOV B, #04H
MUL AB
MOV R1, A
MOV DPTR, #H_TAB
G_LOOP1:
MOV A, R1
MOVC A, @A+DPTR
MOV @R0, A
INC R0
INC R1
DJNZ R2, G_LOOP1
POP 02H 出栈恢复所有用到的寄存器内容
POP 01H
POP 00H
POP PSW
RET
H_TAB:
DB 00H,00H,00H,01H 个位
DB 00H,00H,00H,16H
DB 00H,00H,02H,56H
DB 00H,00H,40H,96H
DB 00H,06H,55H,36H
DB 01H,04H,85H,76H
DB 16H,77H,72H,16H 第6位,百万位。
--------------------------------------------
子程序MUL_24
功能: 2字节(12位)16进制数乘以24
入口: R2:被乘数高8位,其中最高4位应为0
R3:被乘数低8位
出口: 结果依次存放在:R5R6R7中
R5:高8位,R6:中8位,R7:低8位
--------------------------------------------
MUL_24:
CLR C
MOV A, R3
MOV B, #24
MUL AB 被乘数低8位先乘24
MOV R7, A 积的低8位存到R7,最终结果的低8位终值
MOV R6, B 积的高8位暂存到R6
MOV A, R2
MOV B, #24
MUL AB 被乘数高字节乘24
ADD A, R6 积的低8位+R6,C中标志进位状态
MOV R6, A 存到R6,最终结果的中8位终值
CLR A
ADDC A, B 积的高8位+进位标志
MOV R5, A 存到R5,最终结果的高8位终值
RET
--------------------------------------------
子程序DIV_10H
功能: 2字节(12位)16进制数除以0x10
入口: R2:被乘数高8位,其中最高4位应为0
R3:被乘数低8位
出口: 结果依旧存放在R2R3中
R2:高8位,R3:低8位
算法说明:利用标志位C,将2字节作为一个整体的
16进制数循环右移4次。
--------------------------------------------
DIV_10H:
MOV R7, #04H
D_LOOP1:
CLR C 循环一次后清零保证下一次最高位补0
MOV A, R2
RRC A 循环右移,最高位补0,最低位进入C
MOV R2, A
MOV A, R3
RRC A C进入最高位,最低位进入C,可能是1,所以下次循环前清零
MOV R3, A
DJNZ R7, D_LOOP1
RET
END
不知道你怎么接的,估计是显示出错了,跟你说下我怎么显示的吧共阴数码管,也就是 要0才显示
先全送1,然后输入数据,再给要显示的那个 数码管送0,这时候他就显示了,注意
!!!!!!!!!!!!!!!!
延时,一定要先延时2MS以上,然后再全部送1
不然才显示几微秒,谁看的到啊。。。
然后就可以清数据了,做其它动作了。。。
看看 是不是这问题,,,试试吧
算法简洁,运行时间短。根据AD574的工作特性,12位转换遵循左对齐输出格式,输出数据与信号的实际值相比大16倍,输出数据必须经过数据处理程序进行下一步的标度变换、滤波和显示等程序。转换的数据是从0000H~0FFFH,数据从单字节到三字节,若均采用常用的多字节除法,势必延长运行时间。本文以单极性0~10V模拟信号,转换结果分高8位、低4位输出,单片机采用延时方式为例,介绍转换数据处理程序的设计方法,其算法简洁,运行时间短。欢迎分享,转载请注明来源:内存溢出
评论列表(0条)