ad574的数据转换51汇编程序

ad574的数据转换51汇编程序,第1张

12位数按照你的格式,最低字节为0,我先将其除以16,转换成ABC后完成的运算。关于HEX转BCD,方法很多,我采用的是加权值查表法,16进制的每一位根据该位数据累加相应次数,也算是一种思路吧,也比较容易理解。加法运算采用的是4字节。结果放在内部RAM中30H开始的4个字节中(高到低顺序,十位、个位存在33H)。最小初值0010H、最大初值FFF0H和部猛培吵份中间值已验证过没有问题。结果看明白程序后可自己调整一下。

更简单的算法:主要在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()

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12558308.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-26
下一篇 2023-05-26

发表评论

登录后才能评论

评论列表(0条)

保存