实验一MCS-51指令系统实验——数据排序一、实验目的熟悉MCS-51指令系统,掌握程序设计方法;加深对内部存储器读写的认识;熟悉仿真开发环境,学会源程序的编写、汇编/编译、调试;熟悉单片机硬件实验系统以及良好的实验习惯培养等;学会检查结果的正确性。二、实验内容将程序存储器的一个列表中的10个单字节无符号数据传送到内部RAM,然后用冒泡法对其按从小到大的次序重新排列,并送到外部RAM以8000H开始的地址单元内。三、实验说明有序的数列更有利于查找。本程序用的是“冒泡排序”法,算法是将一个数与后面的数相比较,如果比后面的数大,则交换,如此将所有的数比较一遍后,最大的数就会在数列的最后面。再进行下一轮比较,找出第二大数据,直到全部数据有序。四、程序流程图交换A,B数位置设置数据区地址设置数据区长度清除交换标志当前地址取数A地址加1当前地址取数B结束A<=B?设置交换标志数据比较完全部有序?是否否是是否开始五、调试程序;第一步:将程序存储器的一个列表中的10个单字节无符号数据传送到内部RAM40H~49H单元中。ORG0000HLJMPSTART1ORG0030HSTART1:MOVR0,#40H;设置R0为内部RAM首地址MOVR1,#10;设Rl为计数器MOVDPTR,#TAB1LOOP1:CLRA;累加器清零MOVCA,@A+DPTR;外部数据送累加器A中MOV@R0,A;送内部RAMINCR0;调整内部RAM指针,指向下一个数据INCDPTR;调整外部RAM指针DJNZR1,LOOP1;未完继续;第二步:排序。把片内RAM40H~49H单元中的10个无符号数逐一比较,并按从小到大的顺序依次排列在这片单元中。设置块的源地址设置块的目标地址设置移动长度从源地址取数保存到目标地址中源地址加1目标地址加1是否移动完结束是否开始START2:CLRF0;清除交换标志位F0MOVR3,#9;10个数据循环次数MOVR0,#40H;数据存放区首址MOVA,@R0;取前数L2:INCR0MOVR2,A;保存前数SUBBA,@R0;前数减后数MOVA,R2;恢复前数JCL1;顺序则继续比较SETBF0;逆序则建立标志位XCHA,@R0;前数与后数交换DECR0;指向前数单元XCHA,@R0INCR0;仍指向后数单元L1:MOVA,@R0;取下一个数DJNZR3,L2;依次重复比较JBF0,START2;交换后重新比较;第三步:将内部数据RAM中40H~49H单元的内容传送到外部数据存储器以8000H开始的连续单元中去。;40H~49H共计10个单元,需传送10次数据。将Rl作为循环计数器。具体程序如下。START3:MOVR0,#40H;设置R0为内部RAM首地址MOVDPTR,#8000H;设置外部RAM首地址MOVR1,#10;设Rl为计数器LOOP:MOVA,@R0;取内部RAM数MOVX@DPTR,A;送外部RAMINCR0;调整内部RAM指针,指向下一个数据INCDPTR;调整外部RAM指针DJNZR1,LOOP;未完继续SJMP$;暂停TAB1:DB09H,04H,02H,08H,00H;数0-9表DB00H,06H,07H,07H,0FHEND六、收获与体会第一次用汇编语言在伟福6000环境下运行,感觉和VC6.0稍有不同,伟福6000调试界面非常丰富,有片内RAM——DATE;片外RAM——XDATE;代码寄存器——CODE;特殊功能寄存器——SFR;并且可以单步调试,自己所编的程序一目了然;伟福6000果然是好东西;冒泡法存在的不足及改进方法:第一,在排序过程中,执行完最后的排序后,虽然数据已全部排序完备,但程序无法判断是否完成排序,为了解决这一不足,可设置一个标志单元flag,将其设置为OFF,表示被排序的表示是一个无序的表。在每一排序开始时,检查此标志,若此标志为0,则结束排序;否则进行排序;第二,当排序的数据比较多时排序的时间会明显延长。改进方法:快速排序:具体做法:任意选取某一记录(通常取第一个记录),比较其关键字与所有记录的关键字,并将关键字比它小的记录全部放在它的前面,将比它大的记录均存放在它的后面,这样,经过一次排序之后,可将所有记录以该记录所在的分界点分为两部分,然后分别对这两部分进行快速排序,直至排序完。实验二I/O口输入输出实验一、实验目的学习P1口作为输出/输入方式使用的方法;掌握延时子程序的编写和使用;二、实验内容(1)P1口做输出口,接8个发光二极管,编写程序,使发光二极管循环点亮。(2)P1.0~P1.3口做输入口,接4位拨码开关;P1.4~P1.7做输出口,接4个发光二极管。编写程序读取P1口低四位的开关量输入状态,输出到P1口的高四位,由二极管指示出来。三、实验流程图开始设置初始值数据输出左移一位延时设移位次数移位次数完成?否是(1)P1口循环点灯程序框图(2)P1口输入输出程序框图四、调试程序(1)、P1口循环点灯程序ORG0000HLJMPSTARTORG0030HSTART:MOVA,#01H;位初值LOOP:MOVP1,A;输出LCALLDELAY;延时RLA;左移下一位LJMPLOOPDELAY:MOVR5,#20;延时子程序,延时0.2秒D1:MOVR6,#20D2:MOVR7,#248DJNZR7,$DJNZR6,D2DJNZR5,D1RETEND(2)、P1口输入输出程序ORG0000HLJMPSTARTORG0030HSTART:MOVA,P1ANLA,#0FH;P1用作输入口时,必须置1,否则读入的数可能出错;可用半字节交换指令SWAPA再赋值给P1RRA;P1.0~P1.3口做输入口,接4位拨码开关RRA;P1.4~P1.7做输出口,接4个发光二极管RRARRAORLA,#0FH;P1用作输入口时,必须置1,否则读入的数可能出错MOVP1,ASJMPSTARTEND五、收获与体会这次试验做的是I/O口的输入输出,这个实验以以小见大的手法,将单片机的功能表现的淋漓尽致;只要我可以使它一个灯亮,我就可以控制全部外围设备;这样的感觉太爽了;果真是其乐无穷,“给我一个支点,我可以撬动整个地球”;P1口是准双向口。它作为输出口时与一般的双向口使用方法相同。由准双向口结构可知当P1口用为输入口时,必须先对它置“1”。若不先对它置“1”,读入的数据是不正确的。实验三定时器/计数器实验一、实验目的了解MCS-51单片机中定时器/计数器的基本结构、工作原理和工作方式,掌握工作在定时器和计数器两种方式下的编程方法。二、实验内容(1)定时器实验:在使用6MHz晶振的条件下,用定时器1产生10ms定时,由P1.0口输出周期为2s的方波信号,并通过发光二极管指示P1.0的输出波形。(2)定时器实验(选作):在使用6MHz晶振的条件下,用端口输出不同频率的脉冲(不同频率的脉冲用定时器实现),控制蜂鸣器发出“DoReMiFaSolLaSiDo”不同音调(这些音调的频率可以参考书中P142的表6-3)(3)计数器实验:按计数器模式和方式2工作,对P3.4(T0)引脚进行计数。将其数值按二进制数在P1口驱动LED灯上显示出来。三、实验说明1、关于内部计数器的编程主要是定时常数的设置和有关控制寄存器的设置。内部计数器在单片机中主要有定时器和计数器两个功能。本实验使用的是定时器。2、定时器有关的寄存器有工作方式寄存器TMOD和控制寄存器TCON。TMOD用于设置定时器/计数器的工作方式0-3,并确定用于定时还是用于计数。TCON主要功能是为定时器在溢出时设定标志位,并控制定时器的运行或停止等。3、内部计数器用作定时器时,是对机器周期计数。每个机器周期的长度是12个振荡器周期。因为实验系统的晶振是6MHZ,本程序工作于方式2,即8位自动重装方式定时器,定时器100us中断一次,所以定时常数的设置可按以下方法计算:机器周期=12÷6MHZ=2uS(256-定时常数)×2uS=100us定时常数=206.然后对100us中断次数计数10000次,就是1秒钟.4、在例程的中断服务程序中,因为中断定时常数的设置对中断程序的运行起到关键作用,所以在置数前要先关对应的中断,置数完之后再打开相应的中断。四、实验流程图开始置T0中断工作方式设置定时常数设置初始状态位设置秒计数值中断允许输出状态位等待中断定时中断入口保护现场秒计数值减1重新设置秒计数值是否到1秒状态位取反恢复现场中断返回YN主程序框图定时中断子程序框图五、调试程序(1)、定时器实验中断方式ORG0000HRESET:LJMPMAINORG001BHLJMPIT1PORG0100HMAIN:MOVSP,#60H;定义堆栈区MOVB,#100MOVTMOD,#10H;定时方式1MOVTL1,#78H;用定时器1产生10ms定时(初值)MOVTH1,#0ECH;用定时器1产生10ms定时(初值)SETBTR1;运行控制SETBET1;允许中断SETBEAHERE:SJMPHEREIT1P:MOVTL1,#78H;重新负初值MOVTH1,#0ECHDJNZB,LOOPCPLP1.0;P1.0口输出周期为2s的方波信号MOVB,#64H;P1.0口输出周期为2s的方波信号LOOP:RETIEND(2)查询方式ORG0000HLJMPMAINORG0100HMAIN:MOVB,#64HMOVTMOD,#10HMOVTL1,#78H;用定时器1产生10ms定时MOVTH1,#0ECH;用定时器1产生10ms定SETBTR1LOOP0:JBCTF1,LOOP1AJMPLOOP0LOOP1:MOVTL1,#78H;用定时器1产生10ms定时MOVTH1,#0ECHDJNZB,LOOP0CPLP1.0;P1.0口输出周期为2s的方波信号LJMPMAINSJMP$END(2)定时器实验(选作);蜂鸣器发出DoReMiFaSolLaSiDo不同音调ORG0000HLJMPMAINORG001BHLJMPINT1ORG0030HMAIN:MOVSP,#30HMOVTMOD,#10H;设T1工作方式1MOVIE,#88H;允许中断LOOP1:MOV40H,#00H;简谱码指针清0LOOP2:MOVA,40HMOVDPTR,#TABLE1MOVCA,@A+DPTR;取简谱码MOVR1,AJZFINISH;简谱码是00H,转移ANLA,#0FHMOVR2,AMOVA,R1SWAPAANLA,#0FHJNZSING;唱名码不是00H,转移CLRTR1;唱名码是00H,则不发音SJMPWY;SING:DECA;唱名码减1MOV50H,ARLAMOVDPTR,#TABLE2;取唱名码高8位MOVCA,@A+DPTRMOVTH1,AMOV51H,AMOVA,50HRLAINCAMOVCA,@A+DPTR;取唱名法低8位MOVTL1,AMOV52H,ASETBTR1WY:LCALLDELAY;调用基本单位时间(1/4拍)INC40HSJMPLOOP2;取下一个简谱码FINISH:CLRTR1SJMPLOOP1;重复播放ORG0100H;基本单位时间子程序DELAY:MOVR4,#200LP1:MOVR5,#232DJNZR5,$DJNZR4,LP1DJNZR2,DELAY;节拍数未到,转移RETORG0150HINT1:PUSHACCPUSHPSWMOVTL1,52H;重置定时器初值MOVTH1,51HCPLP1.0POPPSWPOPACCRETIORG0200HTABLE1:DB42H,53H,62H,73H,84H;简谱码表;高4位唱名码;低4位节拍码DB93H,0A4H,43HDB00HORG0250HTABLE2:DW0FD82H,0FDC8H,0FE06H;唱名码表DW0FE22H,0FE56H,0FE85HDW0FE9AH,0FEB2H,0FEE4HDW0FE03H,0FE11H,0FE2BHDW0FF42H,0FF4DH,0FF61HEND(3)计数器实验ORG0000H