单片机实用程序Word格式.docx
《单片机实用程序Word格式.docx》由会员分享,可在线阅读,更多相关《单片机实用程序Word格式.docx(23页珍藏版)》请在冰豆网上搜索。
差在[r0]中,最高位借位在cy中。
psw、a、r2、r3堆栈需求:
6字节
bcdb:
lcallneg1;
减数[r1]十进制取补
lcallbcda;
按多字节bcd码加法处理
cplc;
将补码加法的进位标志转换成借位标志
movf0,c;
保护借位标志
lcallneg1;
恢复减数[r1]的原始值
movc,f0;
恢复借位标志
neg1:
mova,r0;
[r1]十进制取补子程序入口
xcha,r1;
交换指针
xcha,r0
lcallneg;
通过[r0]实现[r1]取补
mova,r0
换回指针
ret
(3)标号:
neg功能:
多字节bcd码取补
字节数在r7中,操作数在[r0]中。
结果仍在[r0]中。
neg:
取(字节数减一)至r2中
deca
mova,r0;
保护指针
movr3,a
neg0:
clrc
mova,#99h
subba,@r0;
按字节十进制取补
存回[r0]中
incr0;
djnzr2,neg0;
处理完(r2)字节
mova,#9ah;
最低字节单独取补
subba,@r0
mov@r0,a
mova,r3;
恢复指针
(4)标号:
brln功能:
多字节bcd码左移十进制一位(乘十)
结果仍在[r0]中,移出的十进制最高位在r3中。
brln:
movr3,#0;
工作单元初始化
brl1:
mova,@r0;
取一字节
swapa;
交换十进制高低位
存回
取低字节移出的十进制高位
xchda,@r0;
换出本字节的十进制高位
movr3,a;
保存本字节的十进制高位
djnzr2,brl1;
(5)标号:
muld功能:
双字节二进制无符号数乘法
被乘数在r2、r3中,乘数在r6、r7中。
乘积在r2、r3、r4、r5中。
psw、a、b、r2~r7堆栈需求:
muld:
mova,r3;
计算r3乘r7
movb,r7
mulab
movr4,b;
暂存部分积
movr5,a
计算r3乘r6
movb,r6
adda,r4;
累加部分积
movr4,a
clra
addca,b
mova,r2;
计算r2乘r7
mova,r3
rlca
xcha,r2;
计算r2乘r6
adda,r3;
(6)标号:
mul2功能:
双字节二进制无符号数平方
待平方数在r2、r3中。
结果在r2、r3、r4、r5中。
psw、a、b、r2~r5堆栈需求:
mul2:
计算r3平方
movb,a
计算r2平方
xcha,r3;
暂存部分积,并换出r2和r3
xcha,b
xcha,r2
mulab;
计算2×
r2×
r3
jncmu20
incr2;
累加溢出量
mu20:
xcha,b;
adda,r4
addca,r2
(7)标号:
divd功能:
双字节二进制无符号数除法
被除数在r2、r3、r4、r5中,除数在r6、r7中。
ov=0时,双字节商在r2、r3中,ov=1时溢出。
psw、a、b、r1~r7堆栈需求:
divd:
clrc;
比较被除数和除数
subba,r7
subba,r6
jcdvd1
setbov;
溢出
dvd1:
movb,#10h;
计算双字节商
dvd2:
部分商和余数同时左移一位
mova,r5
mova,r4
保存溢出位
subba,r7;
计算(r2r3-r6r7)
anlc,/f0;
结果判断
jcdvd3
movr2,a;
够减,存放新的余数
mova,r1
incr5;
商的低位置一
dvd3:
djnzb,dvd2;
计算完十六位商(r4r5)
mova,r4;
将商移到r2r3中
clrov;
设立成功标志
(8)标号:
d457功能:
双字节二进制无符号数除以单字节二进制数
被除数在r4、r5中,除数在r7中。
ov=0时,单字节商在r3中,ov=1时溢出。
psw、a、r3~r7堆栈需求:
d457:
jcdv50
商溢出
dv50:
movr6,#8;
求平均值(r4r5/r7-→r3)
dv51:
mova,r5
movf0,c
anlc,/f0
jcdv52
dv52:
cplc
djnzr6,dv51
四舍五入
jcdv53
jcdv54
dv53:
incr3
dv54:
clrov
(9)标号:
dv31功能:
三字节二进制无符号数除以单字节二进制数
被除数在r3、r4、r5中,除数在r7中。
ov=0时,双字节商在r4、r5中,ov=1时溢出。
dv31:
jcdv30
dv30:
movr2,#10h;
求r3r4r5/r7-→r4r5
dm23:
jcdm24
incr5
dm24:
djnzr2,dm23
adda,r3
jcdm25
jcdm26
dm25:
incr5
jnzdm26
incr4
dm26:
ret;
商在r4r5中
(10)标号:
muls功能:
双字节二进制有符号数乘法(补码)
4字节
muls:
movr4,#0;
清零r4r5
movr5,#0
lcallmds;
计算结果的符号和两个操作数的绝对值
lcallmuld;
计算两个绝对值的乘积
sjmpmdse;
用补码表示结果
(11)标号:
divs功能:
双字节二进制有符号数除法(补码)
ov=0时商在r2、r3中,ov=1时溢出。
5字节
divs:
lcallmds;
pushpsw;
保存结果的符号
lcalldivd;
计算两个绝对值的商
jnbov,dvs1;
溢出否?
popacc;
溢出,放去结果的符号,保留溢出标志
dvs1:
poppsw;
未溢出,取出结果的符号
movr4,#0
mdse:
jbf0,mds2;
结果为正,原码即补码,计算成功
mds:
clrf0;
结果符号初始化
mova,r6;
判断第二操作数的符号
jnbacc.7,mds1;
为正,不必处理
cplf0;
为负,结果符号取反
xcha,r7;
第二操作数取补,得到其绝对值
cpla
adda,#1
xcha,r7
addca,#0
movr6,a
mds1:
mova,r2;
判断第一操作数或运算结果的符号
jnbacc.7,mds3;
mds2:
mova,r5;
求第一操作数的绝对值或运算结果的补码
mds3:
clrov;
运算成功
(12)标号:
sh2功能:
双字节二进制无符号数开平方(快速)
被开方数在r2、r3中。
平方根仍在r2、r3中,整数部分的位数为原数的一半,其余为小数。
sh2:
mova,r2
orla,r3
jnzsh20
被开方数为零,不必运算
sh20:
movr7,#0;
左规次数初始化
sh22:
anla,#0c0h;
被开方数高字节小于40h否?
jnzsqrh;
不小于40h,左规格化完成,转开方过程
clrc;
每左规一次,被开方数左移两位
movacc.7,c
movc,f0
incr7;
左规次数加一
sjmpsh22;
继续左规
(13)标号:
sh4功能:
四字节二进制无符号数开平方(快速)
被开方数在r2、r3、r4、r5中。
平方根在r2、r3中,整数部分的位数为原数的一半,其余为小数。
sh4:
orla,r4
orla,r5
jnzsh40
sh40:
sh41:
不小于40h,左规格化完成
movr6,#2;
sh42:
被开方数左移一位
djnzr6,sh42;
被开方数左移完两位
sjmpsh41;
sqrh:
规格化后高字节按折线法分为三个区间
adda,#57h
jcsqr2
adda,#45h
jcsqr1
adda,#24h
movb,#0e3h;
第一区间的斜率
movr4,#80h;
第一区间的平方根基数
sjmpsqr3
sqr1:
movb,#0b2h;
第二区间的斜率
movr4,#0a0h;
第二区间的平方根基数
sqr2:
movb,#8dh;
第三区间的斜率
movr4,#0d0h;
第三区间的平方根基数
sqr3:
mulab;
与区间基点的偏移量乘区间斜率
mova,b
累加到平方根的基数上
求当前平方根的幂
求偏移量(存放在r2r3中)
subba,r3
subba,b
sqr4:
setbc;
用减奇数法校正一个字节的平方根
当前平方根的两倍加一存入r5r6中
偏移量小于该奇数否?
subba,r5
jcsqr5;
小于,校正结束,已达到一个字节的精度
incr4;
不小于,平方根加一
保存新的偏移量
movr3,b
sjmpsqr4;
继续校正
sqr5:
mova,r4;
将一个字节精度的根存入r2
rrca
保存最终偏移量的最高位
movr5,a;
将最终偏移量的低八位存入r5中
movr4,#8;
通过(r5r6/r2)求根的低字节
sqr6:
subba,r2
jbf0,sqr7
jcsqr8
sqr7:
movr5,a
incr3
sqr8:
djnzr4,sqr6;
根的第二字节计算完,在r3中
mova,r7;
取原被开方数的左规次数
jzsqre;
未左规,开方结束
sqr9:
按左规次数右移平方根,得到实际根
djnzr7,sqr9
sqre:
ret
(14)标号:
hasc功能:
单字节十六进制数转换成双字节ascii码
待转换的单字节十六进制数在累加器a中。
高四位的ascii码在a中,低四位的ascii码在b中。
psw、a、b堆栈需求:
hasc:
movb,a;
暂存待转换的单字节十六进制数
lcallhas1;
转换低四位
xcha,b;
存放低四位的ascii码
准备转换高四位
has1:
anla,#0fh;
将累加器的低四位转换成ascii码
adda,#90h
daa
addca,#40h
(15)标号:
asch功能:
ascii码转换成十六进制数
待转换的ascii码(30h~39h或41h~46h)在a中。
转换后的十六进制数(00h~0fh)仍在累加器a中。
psw、a堆栈需求:
asch:
subba,#30h
jnbacc.4,ash1
subba,#7
ash1:
MCS-51单片机实用子程序
(2)
(16)标号:
hbcd功能:
单字节十六进制整数转换成单字节bcd码整数
待转换的单字节十六进制整数在累加器a中。
转换后的bcd码整数(十位和个位)仍在累加器a中,百位在r3中。
psw、a、b、r3堆栈需求:
hbcd:
movb,#100;
分离出百位,存放在r3中
divab
mova,#10;
余数继续分离十位和个位
swapa
orla,b;
将十位和个位拼装成bcd码
(17)标号:
hb2功能:
双字节十六进制整数转换成双字节bcd码整数
待转换的双字节十六进制整数在r6、r7中。
转换后的三字节bcd码整数在r3、r4、r5中。
psw、a、r2~r7堆栈需求:
hb2:
clra;
bcd码初始化
movr2,#10h;
转换双字节十六进制整数
hb3:
从高端移出待转换数的一位到cy中
movr7,a
mova,r6
mova,r5;
bcd码带进位自身相加,相当于乘2
addca,r5
addca,r4
addca,r3
双字节十六进制数的万位数不超过6,不用调整
djnzr2,hb3;
处理完16bit
(18)标号:
hbd功能:
单字节十六进制小数转换成单字节bcd码小数
待转换的单字节十六进制小数在累加器a中。
cy=0时转换后的bcd码小数仍在a中。
cy=1时原小数接近整数1。
hbd:
原小数扩大一百倍
rlca;
余数部分四舍五入
movb,#10;
分离出十分位和百分位
adda,b;
拼装成单字节bcd码小数
调整后若有进位,原小数接近整数1
(19)标号:
hbd2功能:
双字节十六进制小数转换成双字节bcd码小数
待转换的双字节十六进制小数在r2、r3中。
转换后的双字节bcd码小数仍在r2、r3中。
psw、a、b、r2、r3、r4、r5堆栈需求:
6字节
hbd2:
movr4,#4;
四位十进制码
hbd3:
原小数扩大十倍
movb,#10
movr5,b
adda,r5
pushacc;
保存溢出的一位十进制码
djnzr4,hbd3;
计算完四位十进制码
取出万分位
取出千分位
orla,r3;
拼装成低字节bcd码小数
取出百分位
取出十分位
orla,r2;
拼装成高字节bcd码小数
(20)标号:
bcdh功能:
单字节bcd码整数转换成单字节十六进制整数
待转换的单字节bcd码整数在累加器a中。
转换后的单字节十六进制整数仍在累加器a中。
psw、a、b、r4堆栈需求:
bcdh:
分离十位和个位
暂存个位
将十位转换成十六进制
按十六进制加上个位
(21)标号:
bh2功能:
双字节bcd码整数转换成双字节十六进制整数
待转换的双字节bcd码整数在r2、r3中。
转换后的双字节十六进制整数仍在r2、r3中。
psw、a、b、r2、r3、r4堆栈需求:
4字节
bh2:
将低字节转换成十六进制
lcallbcdh
将高字节转换成十六进制
lca