微机原理与接口技术软件实验3451单片机算术运算比较和查表.docx
《微机原理与接口技术软件实验3451单片机算术运算比较和查表.docx》由会员分享,可在线阅读,更多相关《微机原理与接口技术软件实验3451单片机算术运算比较和查表.docx(17页珍藏版)》请在冰豆网上搜索。
微机原理与接口技术软件实验3451单片机算术运算比较和查表
本科实验报告
课程名称:
微机原理与接口技术
姓名:
陈肖苇
学院:
信息与电子工程学院
专业:
电子科学与技术
学号:
3140104580
指导教师:
黄凯
2016年11月17日
专业:
_电子科学与技术_
姓名:
陈肖苇
学号:
3140104580
日期:
2016.11.17
地点:
教十一400室
实验报告
课程名称:
微机原理与接口技术指导老师:
黄凯成绩:
__________________
实验名称:
单片机软件实验三四
实验三算术运算
1.基础型实验内容
①以下程序完成单字节的BCD码加法功能,完成空白处程序填写,并在WAVE环境
运行程序,观察寄存器及内存单元的变化。
代码:
RESULTEQU30H
ORG0000H
MOVA,#99H
MOVB,#99H
ADDA,B
DAA;BCD码相加并得到BCD码结果,即对结果进行十进制处理
MOVRESULT,A
MOVA,#00H
ADDCA,#00H;加上进位
MOVRESULT+1,A;高位处理
LJMP$
END
实验现象:
30H开始的内部单元中被放入了结果,低位在前,即9801。
图一:
单字节的BCD码加法结果,即99+99=0198
②下列程序完成多字节BCD码加法运算。
内部RAM30H开始的4字节长的BCD码和外
部RAM1000H开始的4字节长的BCD码相加,结果放在1100H开始的单元中(从
低字节到高字节)。
代码:
ORG0000H
CLRC
MOVR5,#04H
MOVR0,#30H
MOVR1,#10H
MOVR2,#00H
MOVR3,#11H
MOVR4,#00H
L0:
MOVDPH,R1
MOVDPL,R2
MOVA,#15H;1000H开始的外部RAM都写入15H
MOVX@DPTR,A
MOV@R0,#15H;30H开始的内部RAM都写入15H
INCR2
INCR0
DJNZR5,L0
MOVR0,#30H;重新初始化
MOVR2,#00H
MOVR5,#04H
L1:
MOVDPH,R1
MOVDPL,R2
MOVXA,@DPTR
ADDCA,@R0
DAA;十进制调整
MOVDPH,R3
MOVDPL,R4
MOVX@DPTR,A
INCR2
INCR4
INCR0
L2:
DJNZR5,L1
JNCL3
MOVDPTR,#1104H;有进位则结果的第五个字节置1
MOVA,#01H
MOVX@DPTR,A
SJMPEXIT
L3:
MOVDPTR,#1104H;若没有进位则置为00H
MOVA,#00H
MOVX@DPTR,A
EXIT:
END
代码分析:
L0部份为我自己单独加入的部份,原来的代码会使FFH+00H=66H的错误,因为DA指令只可对BCD码表示的数进行调整,即只能调整0~9,而F为16,不是十进制数,所以会产生调整错误。
加入L0段,使加法变为15H+15H=30H(BCD码加法)。
同时,源代码在产生进位的时候会将第1104H位置1,没有进位的时候为FFH,所以又将L3的NOP改为了若没有进位,则置为00H,使结果更加合理。
实验现象:
外部RAM的1100H开始的连续五个单元变为303030300
图二:
完成多字节BCD码加法运算之后,1100H单元开始的内存单元变为3030303000
2.设计型实验内容
①设计程序,实现任意字节压缩BCD码的相加,使用单步、断点方式调试程序,查
看结果。
代码:
MOVR0,#30H;BCD码的起点
MOVR2,#00H;写入值
MOVR1,#40H;BCD码的起点
MOVR3,#10H
MOVR4,#0AH;写入次数控制
L1:
MOVA,R2;30H开始的内部RAM写入00H~09H
MOV@R0,A
MOVA,R3;40H开始的内部RAM写入10H~19H
MOV@R1,A
INCR0
INCR1
INCR2
INCR3
DJNZR4,L1
MOVR0,#30H;重新初始化
MOVR1,#40H
MOVDPH,#10H;求和后的结果保存点1000H
MOVDPL,#00H
MOVR4,#0AH;求和次数控制
CLRC
L2:
MOVA,@R0;开始求和
ADDCA,@R1
DAA;十进制调整
MOVX@DPTR,A
INCR0
INCR1
INCDPL
DJNZR4,L2;循环求和十次
JNCL3;无进位则求和结果最后一位的下一个字节置0
MOVA,#01H;有进位则求和结果最后一位的下一个字节置1
MOVX@DPTR,A
SJMPEXIT
L3:
MOVA,#00H
MOVX@DPTR,A
EXIT:
END
实验现象:
外部RAM中存入了求和结果1012141618202224262800(低位在前)
图三:
初始化后内存中的BCD码值(低位在前)
图四:
求和后的结果
②设计程序,实现多字节十六进制数的减法123456H-005634H,使用单步、断点
方式调试程序,查看结果。
代码:
ORG0000H
MINEQU30H;被减数
SUBEQU40H;减数
RESEQU50H;结果存放
MOVMIN,#12H;初始化被减数
MOVMIN+1,#34H
MOVMIN+2,#56H
MOVSUB,#00H;初始化减数
MOVSUB+1,#56H
MOVSUB+2,#34H
CLRC
MOVA,MIN+2;从最后一位开始求差
SUBBA,SUB+2
MOVRES+2,A
MOVA,MIN+1;开始求差
SUBBA,SUB+1
MOVRES+1,A
MOVA,MIN;开始求差
SUBBA,SUB
MOVRES,A
END
实验结果:
30H和40H开始的单元处被存入被减数和减数123456和005634(高位在前),50H开始存入十六进制减法结果11DE22。
图五:
123456(30H)-005634(40H)=11DE22(50H)
实验四比较和查表
1.基础型实验内容
1以下程序完成共阴数码管数值显示译码的功能,在WAVE环境运行程序,观察寄存器及内存单元的变化,将变化结果注释于右侧。
代码:
ORG0000H
MOVR2,#10H;循环16次
MOVDPTR,#TBL;将表头地址存入DPTR
L0:
MOVA,#00H
MOVCA,@A+DPTR;变址寻址查表
INCDPTR;DPTR自增,查找下一个
DJNZR2,L0;循环16次
SJMP$
TBL:
DB3FH,06H,5BH,4FH,66H,6DH;表格
DB7DH,07H,7FH,6FH,77H,7CH
DB58H,5EH,79H,71H,00H,40H
END
实验结果:
ROM区从0013H开始存入表格3FH~40H。
对于内部寄存器,R2循环10H之后,最终值为0;A中最终值为71H,即TBL中的第16个数。
图六:
ROM区从0013H开始存入表格3FH~40H
图七:
对于REG,R2循环10H之后,最终值为0;A中最终值为71H,即TBL中的第16个数。
②以下子程序完成一个两位十六进制数到ASCII码的转换,数值存放在R2中,转换
结果地位存于R2,高位存于R3。
用PC做基址实现。
代码:
ORG0000H
HEXA:
MOVR2,#1BH;将1BH存入R2
MOVA,R2
ANLA,#0FH;取A的低4位
ADDA,#09H;以PC为基址的偏移量
MOVCA,@A+PC;以PC为基址寻址
XCHA,R2;交换A与R2中的内容
ANLA,#0F0H;得到A的高位
SWAPA;将高位换到地位
ADDA,#02H;以PC为基址的指令偏移量
MOVCA,@A+PC
MOVR3,A;高位结果写回R3
RET
TAB:
DB'0','1','2','3','4'
DB'5','6','7','8','9'
DB'A','B','C','D','E','F'
END
实验现象:
转换后的结果存入R2、R3,其中,R2中存入低位B的ASCII码,即42;R3中存入高位1的ASCII码,即31
图九:
R2中存入低位B的ASCII码,即42;R3中存入高位1的ASCII码,即31
图十:
ROM中从0012H开始存入0~F的ASCII码31~45
③以下程序完成256字节范围内程序散转的功能,根据R7的内容转向各个子程序,
在WAVE环境运行程序,观察寄存器及内存单元的变化,将变化结果注释于右侧。
代码:
ORG0000H
START:
MOVDPTR,#TAB;将表头地址传给DPTR
MOVA,R7
ADDA,R7;R7*2为了与JMP@A+DPTR的机器码匹配,若TAB
JMP@A+DPTR;中的AJMP换成LJMP则R7*3
ORG0100H
TAB:
AJMPPROG0;无条件跳转到对应地址
AJMPPROG1
AJMPPROG2
AJMPPROG3
SJMP$
PROG0:
MOVA,#00H;对应的给A赋值
SJMPRE
PROG1:
MOVA,#01H
SJMPRE
PROG2:
MOVA,#02H
SJMPRE
PROG3:
MOVA,#03H
RE:
NOP
END
代码解读:
先将R7中的值赋给A,再将A中数据扩大两倍当作指令的偏移量;DPTR作为散转表的起始地址;通过JMP@A+DPTR指令,寻找到对应的指令,然后跳转到相应指令对A赋值。
整个代码的功能是通过散转的方法,将R7中的值写入A。
实验现象:
代码执行后,R7中值为00,A中数据被写入00;修改代码,加入一条MOVR7,#01H,则代码执行之后,R7中值为01,A中数据被写入01。
图十:
R7中值为00,A中数据被写入00
图十一:
R7中值为01,A中数据被写入01
2.设计型实验内容
①分别用近程查表指令和远程查表指令,查找R3内容的平方值。
R3内容小于等于
0FH,即平方值为单字节数据。
代码:
近程查表:
ORG0000H
MOVR3,#15;取数
MOVA,R3
ADDA,#04H;偏移量
MOVCA,@A+PC;近程查表
MOV30H,A
SJMP$
TAB:
DB0,1,4,9,16;平方值表格构建
DB25,36,49,64,81
DB100,121,144,169,196,225
END
实验结果:
内部RAM的30H处写入E1(即14*16+1=225,即15的平方),完成设计目标。
图十一:
代码执行后,内部RAM的30H处写入E1
远程查表:
ORG0000H
MOVR3,#10;取出R3中的值
MOVA,R3
MOVDPTR,#TAB;将表头地址写入DPTR
MOVCA,@A+DPTR;远程查表
MOV30H,A
SJMP$
TAB:
DB0,1,4,9,16;平方值表格构建
DB25,36,49,64,81
DB100,121,144,169,196,225
END
实验现象:
内部RAM的30H处写入64(即6*16+4=100,即10的平方),完成设计目标。
图十二:
代码执行后,内部RAM的30H处写入64
②在外部RAM1000H开始处有10H个带符号数,请找出其中的最大值和最小值,分
别存入内部RAM的MAX、MIN单元。
代码:
MAXEQU30H
MINEQU31H
ORG0000H
MOVR7,#0FH;循环次数
MOVDPTR,#1000H;将外部RAM起始地址存入DPTR
MOVXA,@DPTR;将对应数据存入A
ADDA,#80H;加80H便于直接比较,将有符号数化为无符号数
MOVMAX,A;初始化MAX(即存入第一个数)
MOVMIN,A;初始化MIN(即存入第一个数)
L1:
INCDPTR;读入下一个数
MOVXA,@DPTR
ADDA,#80H
CLRC
CJNEA,MAX,S1;相减比较,若不想相等则跳转至S1,且若ASJMPNEXT;相等则跳到NEXT
S1:
JCS2;若C=1,则说明AMOVMAX,A;将MAX值更新
SJMPNEXT
S2:
CJNEA,MIN,S3;相减比较,若不想相等则跳转至S2,且若AS3:
JNCNEXT;若C=0,即A>MIN,则转入NEXT
MOVMIN,A;否则,将MIN更新
NEXT:
DJNZR7,L1;判断循环次数,若没到0FH次,则继续循环
MOVA,MAX
SUBBA,#80H
MOVMAX,A;得到最大值
MOVA,MIN
SUBBA,#80H
MOVMIN,A;得到最小值
SJMP$
END
实验结果:
内部RAM30H处,即MAX处,写入最大值7A;31H处,即MIN处,写入最小值00;同时,因为是有符号数,所以对含有负数的进行检测,也符合要求,完成设计目标。
图十三:
手动修改后的外部RAM值,其中最大值为7A,最小值为00
图十四:
内部RAM30H处,即MAX处,写入最大值7A;31H处,即MIN处,写入最小值00
图十五:
当有负数时的结果,最小值为9C(有符号数)
实验心得:
经过微机软件实验,自己可谓是收获颇丰。
首先,最重要的就是熟悉了各种各样的指令以及具体的使用方法。
课本上的学习难免会显得冰冷一点,而对一些存有疑问的地方(一个指令有几个操作的,比如DJNZ是先减一再判断,还是先判断再减一),通过具体的实验,基本上解决了存在的疑惑。
同时也发现了一些自己学习上的漏洞,比如:
关于访问不同存储区间的不同指令;比如对几种寻址模式的理解等等。
(在这里不得不吐槽一下51真的有点落后了,寄存器间接寻址只有R0,R1,对于一个对字节的加法,如果要用循环的话,两个加数就用掉了,和要存入的话就很麻烦,要来回倒腾)
其次,我觉得为实验指导书的模块还是划分的比较好的,基本上在课本上或者是课堂上所讲解的典型的应用程序都有涉及到,所以,对于典型的操作,现在已经基本上掌握了。
但是美中不足的是,实验指导书中也有一定的美中不足,比如有的填空题,要填多行,却只给了一行的空,有的地方还没有留空;还有一些细节的,就是有些观察现象的实验,没有初始化,导致00H+FFH=FFH,实际内容还是FFH,看不出来变化,还要自己来写入一些值才可以看到变化,希望可以修改一下。
最后,因为这个学期一直比较忙,参加了好多培训班。
。
。
所以交的有些迟,还望助教您能谅解,谢谢。
祝好!