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