单片机实验指导书版.docx
《单片机实验指导书版.docx》由会员分享,可在线阅读,更多相关《单片机实验指导书版.docx(54页珍藏版)》请在冰豆网上搜索。
单片机实验指导书版
实验一8051简单编程与调试
实验目的
通过简单小程序的输入和调试,熟悉并掌握Keil的使用。
学会Proteus与Keil的整合调试。
实验基本要求
建立三个项目,分别输入存储块清零、二进制BCD码及二进制ASCII码转换的汇编源程序,并进行仿真调试。
画出实验程序的流程框图。
实验步骤
采用KeilCx51开发8051单片机应用程序一般需要经过下面几个步骤:
1、在Vision2集成开发环境中创建一个新项目(Project),并为该项目选定合适的单片机CPU器件。
在菜单栏中选择“Project”→“NewProject”,弹出“CreateNewProject”对话框,选择目标路径,在“文件名”栏中输入项目名后,单击“保存(S)”按钮,弹出“SelecteDeviceforTarget”对话窗口。
在此对话窗口的“Database”栏中,单击“Atmel”前面的“+”号,或者直接双击“Atmel”,在其子类中选择“AT89C51”,确定CPU类型。
如图所示。
点击“确定”按钮后,弹出如下的对话框
如果是进行汇编语言编程选择“否”。
2、利用Vision2的文件编辑器编写C语言(或汇编语言)源程序文件,并将文件添加到项目中去。
一个项目可以包含多个文件,除源程序文件外还可以有库文件或文本说明文件。
在Vision2的菜单栏中选择“File”→“New”命令,新建文档,然后在菜单栏中选择“File”→“Save”命令,保存此文档,这时会弹出“SaveAs”对话窗口,在“文件名(N)”一栏中,为此文本命名,注意要填写扩展名“.asm”。
单击“保存(S)”按钮,这样在编写汇编代码时,Keil会自动识别汇编语言的关键字,并以不同的颜色显示,以减少输入代码时出现的语法错误。
程序编写完后,再次保存。
在Keil中“ProjectWorkspace”子窗口中,单击“Target1”前面的“+”号,展开此目录。
在“SourceGroup1”文件夹上单击鼠标右键,在右键菜单中选择“AddFileto‘GroupSource1’”,弹出“AddFiletoGroup”对话窗口,在此对话窗口的“文件类型”栏中,选择“AsmSourceFile”,并找到刚才编写的.asm文件,双击此文件,将其添加到SourceGroup中,此时“ProjectWorkspace”子窗口如图所示。
3、通过Vision2的各种选项,配置Cx51编译器、Ax51宏汇编器、BL51/.Lx51连接定位器以及Debug调试器。
在“ProjectWorkspace”窗口中的“Target1”文件夹上单击鼠标右键,在弹出的右键菜单中选择“OptionforTarget”选项,这时会弹出“OptionsforTarget”对话窗口,在此对话窗口中选择“Output”选项卡,选中“CreateHEXFile”选项,如图所示。
4、利用Vision2的构造(Buid)功能对项目中的源程序文件进行编译连接,生成绝对代码和可选的HEX文件,如果出现编译连接错误则返回到第2步,修改源程序中的错误后重新构造整个项目。
在Keil的菜单栏中选择“Project”→“BuildTarget”命令,编译汇编源文件。
如果编译成功,则在“OutputWindow”子窗口中会显示如图所示的信息;如果编译不成功,双击“OutputWindow”窗口中的错误信息,则会在编辑窗口中指示错误语句。
5、将没有错误的绝对代码装入Vision2调试器进行仿真调试,调试成功后将HEX文件写入到单片机应用系统的EPROM中。
在Keil的菜单栏中,选择“Debug”→“Start/StopDebugSession”选项,进入程序调试环境,如图所示。
按“F11”键,单步运行程序。
在“ProjectWorkspace”窗口中,可以查看累加器、通用寄存器及特殊功能寄存器的变化。
在“Memory”窗口中,可以看到每执行一条语句后存储空间的变化。
在“Address”栏中,输入“D:
30H”,查看AT89C51的片内直接寻址空间。
程序调试完毕后,再次在菜单栏中选择“Debug”→“Start/StopDebugSession”选项,退出调试环境。
在Proteus中调试程序
打开ProteusISIS编辑环境,在菜单栏中选择“File”→“LoadDesign”弹出“LoadISISDesignFile”对话窗口,选择要打开的Proteus的.DSN设计文件。
在本实验中,设计文件为本实验子目录下的Basic.DSN
单击鼠标右键选中AT89C51并单击鼠标左键,打开“EditComponent”对话窗口,在此窗口中的“ProgramFile”栏中,选择先前用Keil生成的.HEX文件,如图所示。
单击ProteusISIS界面左下角的
按钮,进入程序调试状态,并在“Debug”菜单中打开“8051CPURegisters”、“8051CPUInternal(IDATA)Memory”及“8051CPUSFRMemory”三个观察窗口,按“F11”键,单步运行程序。
在程序运行过程中,可以在这三个窗口中看到各寄存器及存储单元的动态变化。
Proteus与Keil整合调试及电路仿真
在Proteus的“Debug”菜单中选择“UseRemoteDebugMonitor”选项,如图所示。
选择Keil的“Project”→“OptionsforTarget‘Target1’”,在弹出的对话框中,单击Debug选项卡,单击右上部的下三角按钮选择“ProteusVSMMonitor-51Driver”如图所示。
单击“Setting”进入对话框填写如图所示的IP地址和端口号。
在Keil中,在菜单栏中选择“Debug”→“Start/StopDebugSession”选项,Keil系统进入调试状态。
同时Proteus也进入调试状态。
这时可以调整这两个软件窗口的大小,使它们同时出现在桌面上,这样就可以同时观察这两个软件运行的情况了。
在Proteus的调试状态下,在“Debug”菜单中打开“8051CPURegisters”、“8051CPUInternal(IDATA)Memory”、“8051CPUSFRMemory”三个观察窗口,在单步运行程序的过程中,可以在这三个窗口中看到各寄存器以及存储单元的动态变化。
实验内容1
Porteus模型为BASIC.DSN如下图所示。
一、存储块置全“1”源代码:
汇编语言源程序:
ORG00H
STARTEQU30H
MOVR1,#START;起始地址
MOVR7,#32;Rn中设置32字节计数值
MOVA,#0FFH
LOOP:
MOV@R1,A
INCR1;指向下一个地址
DJNZR7,LOOP;计数值减1,不为零继续
SJMP$
END
在下划线处填入适当指令。
输入源程序,编译无误后,用单步执行的方法,观察各个相应存储单元和寄存器中内容的变化。
解释STARTEQU30H。
【答】将30H定义为START
二、二进制BCD码转换源代码:
汇编语言源程序:
RESULTEQU30H
ORG00H
LJMPSTART
START:
MOVSP,#40H;堆栈指针指向40H
MOVA,#123
LCALLBINTOBAC
SJMP$
BINTOBAC:
MOVB,#100
DIVAB;除以100得百位数
MOVRESULT,A
MOVA,B
MOVB,#10
DIVAB;余数除以10得十位数
MOVRESULT+1,A
MOVRESULT+2,B;余数为个位数
RET
END
在下划线处填入适当指令。
用单步执行的方法,观察子程序调用过程中堆栈指针的变化。
三、二进制ASCII码转换源代码:
汇编语言源程序:
RESULTEQU30H
ORG00H
START:
MOVA,#1AH
LCALLBINTOHEX;调用BINTOHEX子程序
LJMP$
BINTOHEX:
MOVDPTR,#ASCIITAB;表的首址ASCIITAB送DPTR
MOVB,A;暂存A
SWAPA
ANLA,#0FH;取A的高四位
MOVCA,@A+DPTR;查ASCII表
MOVRESULT,A
MOVA,B;恢复A
ANLA,#0FH;取低四位
MOVCA,@A+DPTR;查ASCII表
MOVRESULT+1,A
RET
ASCIITAB:
DB'0123456789ABCDEF';定义数字对应的ASCII表
END
在下划线处填入适当指令。
单步运行程序观察查表指令的执行过程。
把LJMP$这条指令注释掉,然后全速运行该程序,然后让其停止观察程序执行到哪里?
【答】一直重复调用不停止
实验内容2
输入、汇编、调试下列四个程序,通过信息窗口观察并回答问题。
1、程序a.asm
ORG0000H
MOV30H,#87H
MOVA,#69H
ADDA,30H
NOP
END
问:
CY=0,(A)=F0H,OV=0,P=0
将程序中的指令NOP改为指令DAA后
问:
CY=1,(A)=56H,OV=0,P=0
2、程序b.asm
ORG0000H
MOVSP,#60H
MOVDPTR,#0A679H
PUSHDPH
PUSHDPL
MOVA,#80H
PUSHACC
POPB
POP30H
POP31H
NOP
END
问:
(SP)=60H,(A)=80H,(30H)=79H,(31H)=A6H,
(B)=80H,(DPH)=A6H,(DPL)=79H
3、程序c.asm
ORG0000H
MOVDPTR,#TAB
MOVA,#05H
MOVCA,@A+DPTR
NOP
ORG1000H
TAB:
DB6FH,30H,96H,75H,0A8H,0FEH
DB49H,8AH,5FH,0B6H,7FH,0C4H
END
问:
执行完MOVCA,@A+DPTR以后,(A)=FEH
4、程序d.asm
ORG0000H
MOVA,#02H
MOVB,A
RLA
ADDA,B
MOVDPTR,#TAB
JMP@A+DPTR
NOP
ORG0800H
TAB:
LJMP1000H
LJMP2000H
LJMP3000H
LJMP4000H
END
问:
执行完JMP@A+DPTR以后,PC=0806H
实验二汇编语言程序设计
(一)
实验目的
通过上机实验掌握单片机汇编语言程序的编写和调试。
实验基本要求
按实验内容上机输入并调试实验程序。
画出实验程序的流程框图。
实验内容
Proteus模型为BASIC.DSN。
一、内存块移动
汇编语言源程序:
ORG00H
START:
MOVR0,#30H
MOVR1,#00H;设置源地址
MOVR2,#40H
MOVR3,#00H;设置目标地址
MOVR7,#0;设置计数值
LOOP:
MOVDPH,R0
MOVDPL,R1;将源地址(3000H)赋DPTR
MOVXA,@DPTR;取源地址中的数据
MOVDPH,R2
MOVDPL,R3;将目标地址(4000H)赋DPTR
MOVX@DPTR,A;将源地址中的数据送到目标地址
INCR1;源地址加1
INCR3;目标地址加1
DJNZR7,LOOP
LJMP$
END
输入源程序,编译无误后,用单步执行的方法,观察各个相应存储单元和寄存器中内容的变化。
二、程序转跳表
汇编语言源程序:
ORG00H
START:
MOVA,#0;设置地址偏移量
CALLFUNCENTER
MOVA,#1;设置地址偏移量
CALLFUNCENTER
MOVA,#2;设置地址偏移量
CALLFUNCENTER
MOVA,#3;设置地址偏移量
CALLFUNCENTER
LJMP$
FUNCENTER:
ADDA,ACC;AJMP为二字节指令,地址偏移量*2
MOVDPTR,#FUNCTAB;设置基址
JMP@A+DPTR;跳转到目标地址
FUNCTAB:
AJMPFUNC0
AJMPFUNC1
AJMPFUNC2
AJMPFUNC3
FUNC0:
MOV30H,#0
RET
FUNC1:
MOV31H,#1
RET
FUNC2:
MOV32H,#2
RET
FUNC3:
MOV33H,#3
RET
END
输入源程序,编译无误后,用单步执行的方法,观察各个相应存储单元和寄存器中内容的变化。
三、数据排序
汇编语言源程序:
ORG00H
SIZEEQU10;数据个数
ARRAYEQU50H;数据起始地址
FLAGBIT00H;交换标志
SORT:
MOVR0,#ARRAY;首地址输入到R0
MOVR7,#SIZE-1;数据个数减一输入到R7
CLRFLAG;交换标志置零
COON:
MOVA,@R0;将首地址中的内容读到A
MOVR2,A;将数据写入到R2中
INCR0;首地址加一
MOVB,@R0;将首地址中的内容读到B
CJNEA,B,NOTEQUAL;不相等则跳转
SJMPNEXT
NOTEQUAL:
JCNEXT;前小后大,不交换
SETBFLAG;前大后小,置交换标志
XCHA,@R0;交换
DECR0;R0减1
XCHA,@R0
INCR0
NEXT:
DJNZR7,COON;R7不等于0时转到GOON(即没有交换完)
JBFLAG,SORT;FLAG=1时转到SORT使FLAG清零
SJMP$
END
把数据按从小到大排序
四、调试程序S1.asm
程序:
S1.asm
ORG0000H
MOVR0,#30H
MOVR7,#20H
MOVDPTR,#1000H
LOOP1:
CLRA
MOVCA,@A+DPTR
MOV@R0,A
INCR0
INCDPTR
DJNZR7,LOOP1
NOP
NOP
LJMP$
ORG1000H
DB23H,45H,0A5H,7FH,8DH,0CDH,33H,0BFH
DB0FH,66H,9AH,8CH,33H,69H,50H,2DH
DB6DH,45H,0FEH,90H,0ABH,3CH,67H,88H
DB0EDH,0FFH,00H,21H,63H,9DH,77H,45H
END
思考题:
1、在这个程序中的32个数据原来在哪里?
这个程序完成了什么操作?
【答】在片内程序存储区;把程序存储区的32个数据传送到内部30H数据区
2、如果把MOVCA,@A+DPTR改成MOVXA,@A+DPTR会发生什么情况?
【答】把数据区相应寻址地址里存的数据传送到累加器A
3、程序中的ORG指令起什么作用?
【答】用于定位,把ORG之后的程序放在指定的地址里
4、将上述程序修改成将32个数据传送到外部数据区2050H开始的单元中去。
【答】
ORG0000H
MOVR7,#20H
MOVR0,#10H
MOVR1,#00H
MOVR2,#20H
MOVR3,#50H
LOOP:
CLRA
MOVDPH,R0
MOVDPL,R1
MOVCA,@A+DPTR
MOVDPH,R2
MOVDPL,R3
MOVX@DPTR,A
INCR1
INCR3
DJNZR7,LOOP
ORG1000H
DB23H,45H,0A5H,7FH,8DH,0CDH,33H,0BFH
DB0FH,66H,9AH,8CH,33H,69H,50H,2DH
DB6DH,45H,0FEH,90H,0ABH,3CH,67H,88H
DB0EDH,0FFH,00H,21H,63H,9DH,77H,45H
END
实验三汇编语言程序设计
(二)
实验目的
通过上机实验掌握单片机汇编语言程序的编写和调试。
实验基本要求
按实验内容上机输入并调试实验程序。
画出实验程序的流程框图。
实验内容
一、调试S2.asm、S3.asm两个程序并完成思考题
程序:
S2.asm
ORG0000H
MOV30H,#68H
MOV31H,#0AFH
MOV40H,#9AH
MOV41H,#59H
MOVR0,#30H
MOVR1,#40H
MOVR7,#02H
CLRC
LOOP2:
MOVA,@R0
ADDCA,@R1
MOV@R0,A
INCR0
INCR1
DJNZR7,LOOP2
MOVA,#00H
ADDCA,#00H
MOV@R0,A
LJMP$
END
思考题:
1、程序运行结束时,(32H)=01H,(31H)=09H,(30H)=02H
2、观察程序运行时,CY,OV,P,AC标志位的变化。
3、修改原始数据为8421码(压缩BCD码),并把程序改成8421码(压缩BCD码)加法程序,并运行该程序。
ORG0000H
MOV30H,#68H
MOV31H,#82H
MOV40H,#51H
MOV41H,#69H
MOVR0,#30H
MOVR1,#40H
MOVR7,#02H
CLRC
LOOP:
MOVA,@R0
ADDCA,@R1
DAA
MOV@R0,A
INCR1
INCR0
DJNZR7,LOOP
MOVA,#00H
ADDCA,#00H
MOV@R0,A
SJMP$
END
程序:
S3.asm
ORG0000H
MOVSP,#60H
MOVA,#68H
MOVB,#7EH
MOVDPTR,#20A8H
MOVR0,#74H
MOVR1,#49H
MOV08H,#30H
MOV09H,#50H
SETBRS0
PUSHDPH
PUSHDPL
PUSHB
PUSHACC
MOV@R0,A
XCHA,B
MOV@R1,A
POPACC
POPDPL
CLRRS0
NOP
NOP
END
思考题:
1、(A)=68H,(B)=68H,(DPH)=20H,(DPL)=7EH,(SP)=62H,
2、(74H)=00H,(49H)=00H,(30H)=68H,(50H)=7EH
保护和恢复现场数据的规则是什么?
【答】通过使用堆栈
二、编程并调试B1.asm和B2.asm
B1.asm
已知(30H)=89H,(31H)=41H,编写并调试一个程序:
将30H,31H中的内容进行字节分离为四个字节,高四位为零,低四位为分离后的内容,存放在32H~35H的单元中。
ORG0000H
MOV30H,#89H
MOV31H,#41H
MOVR0,#30H
MOVR1,#32H
MOVR7,#02H
LOOP:
MOVA,@R0
MOVB,A
SWAPA
ANLA,#0FH
MOV@R1,A
INCR1
MOVA,B
ANLA,#0FH
MOV@R1,A
INCR1
INCR0
DJNZR7,LOOP
SJMP$
END
B2.asm
已知(30H)=89H,(31H)=41H,编写并调试一个程序:
将30H,31H中的内容进行循环右移五次。
实验四功能模块一(I/O口)
实验目的
通过实验掌握单片机的输入输出应用。
实验基本要求
按实验内容上机输入并调试实验程序。
画出实验程序的流程框图。
实验内容1
1、多路开关指示
AT89C51单片机的P1.0~P1.3接4个二极管,P1.4~P1.7接4个开关,编程读取开关状态,使得对应的发光二极管反映开关状态(开关闭合,对应的灯亮)。
Porteus模型为MultiSwitch.DSN如下图所示。
程序设计:
开关状态检测,对于单片机来说,是检测其I/O口的输入。
可以轮流检测每个开关状态。
根据每个开关的状态让相应的发光二极管指示。
汇编语言源程序:
ORG00H
START:
;读取P1口数据
;交换A中高四位与低四位的位置
;与0F0H相或
;将开关状态送LED显示
;转移到START
END
问题:
为什么A要与0F0H相或?
2、键盘显示
AT89C51的并行口P3上接4×4键盘,P3.0~P3.3为行线,P3.4~P3.7位2列线,在数码管上显示每个按键的序号。
Porteus模型为4X4KeyBoard.DSN如下图所示。
程序设计:
每个按键有它的行值和列值,行值和列值的组合就是识别这个按键的编码,计算公式为
键值=行号×行数+列号
假设9号键按下,它所在的行号为2,列号为1,该键的行数为4,则键值为2×4+1=9。
汇编语言源程序:
LINEEQU30H
ROWEQU31H
VALEQU32H
ORG00H
START:
MOVDPTR,#T