更简单的算法:主要在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是12Bit的ADC
并行数据传送暂用IO口过多
ADC0832是8Bit的ADC
如果对AD采样精度不是很高,建议你采用ADC0809而且有许多参考程纯瞎序
下面给你一段ADC0809的C语言C51单片机的
使用参考程序
/**********【数字电压温度表】***********/
#include
<reg51.h>
#define
uchar
unsigned
char
#define
uint
unsigned
int
char
Code[10]
=
{0x3f,
0x06,
0x5b,
0x4f,
0x66,
0x6d,
0x7d,
0x07,
0x7f,
0x6f}
/*显示弯裤【0
1
2
3
4
5
6
7
8
9】数字的数码管的段码
*/
uchar
code
C[]
=
{0x0,
0xFE,
0xFD,
0xFB,
0xF7,
0xEF,
0xDF,
0xBF,
0x7F}
/*列扫描控制
LED1位
2位
3位
4位
5位
6位
7位
8位*/
uchar
disp[4]
//显示器数组
uint
temp,result
sbit
CLK=P3^3
//接时钟接口
为ADC0809提供时埋裤简钟
sbit
EOC=P3^2
sbit
ST=P3^0
sbit
OE=P3^1
/*************延时1MS函数*************/
void
delay1ms(uchar
x)
{
uchar
i,j
for(i=0i<xi++)
for(j=0j<120j++)
}
/**************显示函数***************/
void
display(void)
{
P0=Code[disp[0]]
P2=C[1]
delay1ms(10)
P0=Code[disp[1]]|0x80
P2=C[2]
delay1ms(10)
P0=Code[disp[2]]
P2=C[3]
delay1ms(10)
P0=Code[disp[3]]
P2=C[4]
}
/*********T0定时器的初始化函数***************/
void
init(void)
{
EA=1
ET0=1
TMOD=0x01
TH0=(65536-200)/256
TL0=(65536-200)%256
TR0=1
}
/**************T0中断服务,提供时钟信号***************/
void
timer0(void)
interrupt
1
{
TH0=(65536-200)/256
TL0=(65536-200)%256
CLK=~CLK
}
/*************主函数***************/
main()
{
init()
ST=0
while(1)
{
ST=1
ST=0
while(EOC==0)
OE=1
temp=P1
result=temp*1.0/255*500
disp[0]=result/1000
disp[1]=result/100%10
disp[2]=result/10%10
disp[3]=result%10
display()
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)