51单片机程序问题

0~5V对就0~300的数字
也就是00H~0FFH想转换成000~300的数字放在78H,79H,7AH当中,汇编程序怎么编?
我是这样编的,不过这样有点问题,有很多小的数字不能转成功
TUNBCD:
CLR A
MOV B,A
MOV A,@R0
MOV B,#085
DIV AB
MOV 78H,A
MOV A,B
MOV B,#09
DIV AB
MOV 79H,A
MOV 7AH,B
RET

Y = X * 300 / 255
约= X * 301 / 256
= X * ( 150 + 151) / 256

除以 256,就简单了,扔掉低八位即可。

MOV A, X
MOV B, #151
MUL AB
MOV R3, B
MOV R4, A ;R3R4=X * 151
;---------------------------------------
MOV A, X
MOV B, #150
MUL AB ;BA=X*150
;---------------------------------------
ADD A, R4
( MOV R4, A )
MOV A, R3
ADDC A, B
MOV R3, A
CLR A
ADDC A, #0
MOV R2, A ;R2R3R4=X * (151 + 150)

把 R4 抛弃,即为除以 256。
以 R2R3 为结果就行了。

R2R3:0~300,再分解成百位十位个位即可。
----------
;先分解R3:
MOV A, R3
MOV B, #100
DIV AB
MOV 78H, A ;百
MOV A, B
MOV B, #10
DIV AB
MOV 79H, A ;十
MOV 7AH, B ;个

;R2只有1、0两种数字
CJNE R2, #1, EXIT ;为零即结束

MOV A, 7AH ;为1则加上 256
ADD A, #6
MOV 7AH, A
MOV A, 79H
ADDC A, #5
MOV 79H, A
MOV A, 78H
ADDC A, #2
MOV 78H, A

EXIT:
RET追问

先对您回答我这个问题的态度表示我的敬意~
我用你的程序放入了我的主程序中,还是遇到了和我上面那个简陋的程序一样的问题,就是有一部分数会转化不了,变成三个000,比如说00h,会转成146,还有105,145这些数也会变成000,
我的qq是349902017,如果您有时间,也有这个兴趣,我们可以在qq上谈,如果您没空,那也没什么,再次感谢您回答我这个问题,谢谢~

追答

我写的程序,略有瑕疵。


但是,对于楼主给出的几个数字,变换,并没有出错。


00H,变换后是 00H 00H 00H。

255,变换后,是 02 09 09。

145,变成 170。


105,变换成了123,截图如下:


这些数字的变换,基本都符合 X * 300 / 255。


你说:00h,会转成146,怎么可能这样?

可以显示一下截图吗?


程序中缺点,还是有的。

当分别加上 2、5、6 时,和如果大于9,应该会产生进位,

但是,单片机是按照二进制计算,本应该进位,却也不会出现在 C 上。

加到下一位时,虽然用了 ADDC 指令,也会偶有遗漏。


只有个位加 6 时,有可能出现该进位却不进位的情况。

因为在加 256 时,前面的加数,不会超过 43。

所以,在加 5、加 2 时,都不会出现进位。


就是说,上述程序,出错的概率是很小的。


如下修正即可:


;R2只有1、0两种数字

    CJNE  R2, #1, EXIT  ;为零即结束


    MOV   A, 7AH    ;为1则加上 256

    ADD   A, #6     ;(0~9)+6

    MOV   7AH, A  ;(5~F)

    SUBB  A, #10  ;-10

    JC    NX1         ;不够减,转移到下一位

    MOV   7AH, A   ;保存(0~9)

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

NX1:

    CPL  C

    MOV   A, 79H

    ADDC  A, #5     ;(0~4)+5

    MOV   79H, A 

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

    MOV   A, 78H

    ADDC  A, #2     ;(0)+2

    MOV   78H, A

EXIT:

    RET


本程序,经过了全面的测试,正确无误。

本程序没有做多位数的除法,所以也没有任何的循环,

虽然看起来,好像有些长,但是执行的速度,却是最快的。

追问

我是用实物来做的,我用您这个新的程序再一次,结果还是一样,00H对就的还是146
32,86,121,这种小的数字还是不能换,显示的还是000。我提问的那个程序虽然粗糙,不过应该还是可以换出来数的对吧,可是它也是一些小的数字不能换,我不知道是什么原因,不知道您有没这方面的经验,我想把我的全部程序发上来给您看,可是百度有数限制。实在不行我只能用三个表格来查表了,这个是个笨方法,再次感谢您的回答~

追答

你的题目要求是:00H~0FFH想转换成000~300的数字放在78H,79H,7AH当中。

但是,给你提供程序之后,你好像,并没有查看78H,79H,7AH的内容,

而是用实物来做、以显示,为标准,对吧?

你还是按照你的题目要求,查看78H,79H,7AH当中的内容,把 00H 的变换,截图。

显示的事,以后再说。

可以把程序发到我的邮箱。
在我的百度空间留有邮箱地址。

追问

是没看,不过我直接可以显示,有的数字能转,有的不能转,不知道是什么原因,程序发你mail了,不胜感激~

追答

看到了邮件。

你的 AD 转换数据,是用自己输入的数字来代替的。
这样很好,可以避免现场进行 AD 转换的不确定性。

但是,下列程序,每一行,都很明显的,缺少了《井号》。

;*************************************
;* ? 测量(A/D)子程序 *
;*************************************
; 一次测量数据8个,依次放入70H-77H单元中
;
TEST:
MOV 77H, 00
MOV 76H, 32
MOV 75H, 86
MOV 74H, 121
MOV 73H, 159
MOV 72H, 188
MOV 71H, 210
MOV 70H, 255
RET
;

这就不是数了,而是地址。其中的数,并不明确。

追问

好吧,原来我犯了一个低级错误,改好之后就好了,我那个程序也可以用,哈哈,谢谢了,您的那个我还是不能用,不知道为什么,和我那个按键程序有冲突,我把您的那三个寄存器成了R5R6R7,还是有冲突,这个问题您能看出来么~冲突是在单路循环的时候会自动跳到0路,我的那个简单的就没问题~
对了,我的那个程序要按两下才能在单路的时候+1,不知道为什么~
您已经解决了我一个问题,再次感谢~

追答

呵呵,能找到毛病就好了。

寄存器使用时,和你原有程序,有冲突的地方,改改即可,这不算毛病。

要按两下才能在单路的时候+1,不知道为什么~
--你的程序挺长,还没有细看。

追问

那等您有时间再看看吧,要是没时间就算了,感谢您帮我一个问题~

温馨提示:答案为网友推荐,仅供参考
第1个回答  2013-12-27
0-0ff转换成0-300,从数学上就是把AD数据乘 1.1764(300/255)
为避免浮点运算可以用 X151 / 128 来代替


先把采样数据X 152
MOV A,@R0
MOV B,#151
MUL AB

然后在AB中的积(16位)右移7位即可

注意
DIV在汇编里是除法指令,例如DIV A,B;意思是将累加器A中的无符号8位二进制数除以寄存器B中的无符号8位二进制数,商的整数部分存放在累加器A中,余数部分存放在寄存器B中。
你要求的结果300已超出8位,不可能使用该指令追问

不是很懂的样子
我是想把00~FFH转成000~300
百位放在78h,十位放在79h,个位放在7ah
这样也要先乘再除么

第2个回答  2013-12-27
这样好像不行,你将原数乘100,除以85,这样算就可以了,所以先乘再除。追问

完全没理解,能给个程序么~求帮助~

追答

255/300=0.85
所以0~255转换为0~300,将转换的数除以0.85就可以了。但没有浮点,所以都扩大100倍。
CHGDAT:
MOV B,#100
MUL AB
MOV 11H,A
MOV 12H,B
MOV B,#85
LCALL DIV16
MOV 78H,A
MOV 79H,B ;两个字节就可以存下了,最大300
RET
;12H:11H/B=12H:11HDIV16: MOV R7,#08HDIV1: CLR C MOV A,11H RLC A MOV 11H,A MOV A,12H RLC A MOV 12H,A CLR C SUBB A,B JC DIV2 MOV 12H,A INC 11HDIV2: DJNZ R7,DIV1 RET

追问

其实我是想把00~FFH转成000~300百位放在78h,十位放在79h,个位放在7ah
不过还是谢谢你~
这样子能给个程序么,我的那个不行……

追答

;入口 A
CHGDAT:
MOV B,#100
MUL AB
MOV 11H,A
MOV 12H,B
MOV B,#85
LCALL DIV16
MOV B,#100
LCALL DIV16
MOV 78H,11H
MOV A,12H
MOV B,#10
DIV AB
MOV 79H,A
MOV 7AH,B
RET
DIV16:
MOV R7,#8
DIV1:
CLR C
MOV A,11H
RLC A
MOV 11H,A
MOV A,12H
RLC A
MOV 12H,A
CLR C
SUBB A,B
JC DIV2
MOV 12H,A
INC 11H
DIV2:
DJNZ R7,DIV1
RET

相似回答
大家正在搜