第一篇:单片机io口控制实验报告
单片机实验报告
实验名称:
I/O 口控制
姓
名:
张昊 学
号:
110404247 班
级:
通信 2 班 时
间:
2013.11.19
南京理工大学紫金学院电光系
一、实验目的1、学习I/O 口的使用。
2、学习延时子程序的编写和使用。
3、掌握单片机编程器的使用和芯片烧写方法。
二、
实验原理
1、广告流水灯实验 (1)
做单一灯的左移右移,八个发光二极管 L1~L8 分别接在单片机的P1.0~P1.7 接口上,输出“0”的时候,发光二极管亮,开始时P1.0->P1.1->P1.2->P1.3->...->P1.7->P1.6->...P1.0 亮,重复循环。
(2)
系统板上硬件连线:把“单片机系统”A2 区的 J61 接口的 P1.0~P1.6端口与 D1 区的 J52 接口相连。要求:P1.0 对应着 L1,P1.1 对应L2,……,P1.7 对应着 L8。
P1 口广告流水灯实验原理图如下
程序设计流程:流程图如下
2、模拟开关实验 (1)
监视开关 K1(接在 P3.0 端口上),用发光二极管 L1(接在单片机P1.0 端口上)显示开关状态,如果开关合上,L1 亮,开关打开,L1 熄火。
(2)
系统板上硬件连线:把“单片机系统”A2 区的 P1.0 端口用导线连接到 D1 区的 LED1 端口上;把“单片机系统”A2 区的 P3.0 端口用导线连接到 D1 区的 KEY1 端口上; 实验原理图如下图
程序设计流程
否
是
二、实验内容
1、流水灯
#include
unsigned char count=0;bit flag;void main(){ 开始 开关闭合否 L1 灭 L1 亮
P1=0xff;TMOD=0x01;TH0=55536/256;TL0=55536%256;EA=1;ET0=1;TR0=1;while(1){ p10=0;while(flag==0);flag=0;p10=1;p11=0;while(flag==0);flag=0;p11=1;p12=0;while(flag==0);flag=0;p12=1;p13=0;while(flag==0);flag=0;p13=1;p14=0;while(flag==0);flag=0;p14=1;p15=0;while(flag==0);flag=0;p15=1;p16=0;while(flag==0);flag=0;p16=1;p17=0;while(flag==0);flag=0;p17=1;} } void t0_srv()interrupt 1 { TH0=55536/256;TL0=55536%256;count++;if(count==10){ flag=1;
count=0;} } 2、模拟开关
#include
while(1){ if(p30==0)
p10=0;else
p10=1;} }
三、小结与体会
通过本次实验学会了 I/O 口的使用,学会了延时子程序的编写和使用以及掌握了单片机编程器的使用和芯片烧写方法。通过 Proteus ISIS 和 Keil uvision软件的互相配合,使得单片机在电脑上的仿真轻松便捷。通过本次试验,利用简单的试验,2 种软件以及硬件的使用。
第二篇:51单片机IO口工作原理
51单片机I/O口工作原理
一、P0端口的结构及工作原理 P0端口8位中的一位结构图见下图:
由上图可见,P0端口由锁存器、输入缓冲器、切换开关、一个与非门、一个与门及场效应管驱动电路构成。再看图的右边,标号为P0.X引脚的图标,也就是说P0.X引脚可以是P0.0到P0.7的任何一位,即在P0口有8个与上图相同的电路组成。
下面,我们先就组成P0口的每个单元部份跟大家介绍一下:
先看输入缓冲器:在P0口中,有两个三态的缓冲器,在学数字电路时,我们已知道,三态门有三个状态,即在其的输出端可以是高电平、低电平,同时还有一种就是高阻状态(或称为禁止状态),大家看上图,上面一个是读锁存器的缓冲器,也就是说,要读取D锁存器输出端Q的数据,那就得使读锁存器的这个缓冲器的三态控制端(上图中标号为„读锁存器‟端)有效。下面一个是读引脚的缓冲器,要读取P0.X引脚上的数据,也要使标号为„读引脚‟的这个三态缓冲器的控制端有效,引脚上的数据才会传输到我们单片机的内部数据总线上。
D锁存器:构成一个锁存器,通常要用一个时序电路,时序的单元电路在学数字电路时我们已知道,一个触发器可以保存一位的二进制数(即具有保持功能),在51单片机的32根I/O口线中都是用一个D触发器来构成锁存器的。大家看上图中的D锁存器,D端是数据输入端,CP是控制端(也就是时序控制信号输入端),Q是输出端,Q非是反向输出端。
对于D触发器来讲,当D输入端有一个输入信号,如果这时控制端CP没有信号(也就是时序脉冲没有到来),这时输入端D的数据是无法传输到输出端Q及反向输出端Q非的。如果时序控制端CP的时序脉冲一旦到了,这时D端输入的数据就会传输到Q及Q非端。数据传送过来后,当CP时序控制端的时序信号消失了,这时,输出端还会保持着上次输入端D的数据(即把上次的数据锁存起来了)。如果下一个时序控制脉冲信号来了,这时D端的数据才再次传送到Q端,从而改变Q端的状态。
多路开关:在51单片机中,当内部的存储器够用(也就是不需要外扩展存储器时,这里讲的存储器包括数据存储器及程序存储器)时,P0口可以作为通用的输入输出端口(即I/O)使用,对于8031(内部没有ROM)的单片机或者编写的程序超过了单片机内部的存储器容量,需要外扩存储器时,P0口就作为„地址/数据‟总线使用。那么这个多路选择开关就是用于选择是做为普通I/O口使用还是作为„数据/地址‟总线使用的选择开关了。大家看上图,当多路开关与下面接通时,P0口是作为普通的I/O口使用的,当多路开关是与上面接通时,P0口是作为„地址/数据‟总线使用的。
输出驱动部份:从上图中我们已看出,P0口的输出是由两个MOS管组成的推拉式结构,也就是说,这两个MOS管一次只能导通一个,当V1导通时,V2就截止,当V2导通时,V1截止。
与门、与非门:这两个单元电路的逻辑原理我们在第四课数字及常用逻辑电路时已做过介绍,不明白的同学请回到第四节去看看。
前面我们已将P0口的各单元部件进行了一个详细的讲解,下面我们就来研究一下P0口做为I/O口及地址/数据总线使用时的具体工作过程。
1、作为I/O端口使用时的工作原理
P0口作为I/O端口使用时,多路开关的控制信号为0(低电平),看上图中的线线部份,多路开关的控制信号同时与与门的一个输入端是相接的,我们知道与门的逻辑特点是“全1出1,有0出0”那么控制信号是0的话,这时与门输出的也是一个0(低电平),与让的输出是0,V1管就截止,在多路控制开关的控制信号是0(低电平)时,多路开关是与锁存器的Q非端相接的(即P0口作为I/O口线使用)。
P0口用作I/O口线,其由数据总线向引脚输出(即输出状态Output)的工作过程:当写锁存器信号CP
有效,数据总线的信号→锁存器的输入端D→锁存器的反向输出Q非端→多路开关→V2管的栅极→V2的漏极到输出端P0.X。前面我们已讲了,当多路开关的控制信号为低电平0时,与门输出为低电平,V1管是截止的,所以作为输出口时,P0是漏极开路输出,类似于OC门,当驱动上接电流负载时,需要外接上拉电阻。
下图就是由内部数据总线向P0口输出数据的流程图(红色箭头)。
P0口用作I/O口线,其由引脚向内部数据总线输入(即输入状态Input)的工作过程:
数据输入时(读P0口)有两种情况
1、读引脚
读芯片引脚上的数据,读引脚数时,读引脚缓冲器打开(即三态缓冲器的控制端要有效),通过内部数据总线输入,请看下图(红色简头)。
2、读锁存器
通过打开读锁存器三态缓冲器读取锁存器输出端Q的状态,请看下图(红色箭头):
在输入状态下,从锁存器和从引脚上读来的信号一般是一致的,但也有例外。例如,当从内部总线输出低电平后,锁存器Q=0,Q非=1,场效应管T2开通,端口线呈低电平状态。此时无论端口线上外接的信号是低电乎还是高电平,从引脚读入单片机的信号都是低电平,因而不能正确地读入端口引脚上的信号。又如,当从内部总线输出高电平后,锁存器Q=1,Q非=0,场效应管T2截止。如外接引脚信号为低电平,从引脚上读入的信号就与从锁存器读入的信号不同。为此,8031单片机在对端口P0一P3的输入操作上,有如下约定:为此,8051单片机在对端口P0一P3的输入操作上,有如下约定:凡属于读-修改-写方式的指令,从锁存器读入信号,其它指令则从端口引脚线上读入信号。
读-修改-写指令的特点是,从端口输入(读)信号,在单片机内加以运算(修改)后,再输出(写)到该端口上。下面是几条读--修改-写指令的例子。
这样安排的原因在于读-修改-写指令需要得到端口原输出的状态,修改后再输出,读锁存器而不是读引脚,可以避免因外部电路的原因而使原端口的状态被读错。
P0端口是8031单片机的总线口,分时出现数据D7一D0、低8位地址A7一AO,以及三态,用来接口存储器、外部电路与外部设备。P0端口是使用最广泛的I/O端口。
2、作为地址/数据复用口使用时的工作原理
在访问外部存储器时P0口作为地址/数据复用口使用。
这时多路开关„控制‟信号为„1‟,„与门‟解锁,„与门‟输出信号电平由“地址/数据”线信号决定;多路开关与反相器的输出端相连,地址信号经“地址/数据”线→反相器→V2场效应管栅极→V2漏极输出。例如:控制信号为1,地址信号为“0”时,与门输出低电平,V1管截止;反相器输出高电平,V2管导通,输出引脚的地址信号为低电平。请看下图(兰色字体为电平):
反之,控制信号为“1”、地址信号为“1”,“与门”输出为高电平,V1管导通;反相器输出低电平,V2管截止,输出引脚的地址信号为高电平。请看下图(兰色字体为电平):
可见,在输出“地址/数据”信息时,V1、V2管是交替导通的,负载能力很强,可以直接与外设存储器相连,无须增加总线驱动器。
P0口又作为数据总线使用。在访问外部程序存储器时,P0口输出低8位地址信息后,将变为数据总线,以便读指令码(输入)。
在取指令期间,“控制”信号为“0”,V1管截止,多路开关也跟着转向锁存器反相输出端Q非;CPU自动将0FFH(11111111,即向D锁存器写入一个高电平„1‟)写入P0口锁存器,使V2管截止,在读引脚信号控制下,通过读引脚三态门电路将指令码读到内部总线。请看下图
如果该指令是输出数据,如MOVX
@DPTR,A(将累加器的内容通过P0口数据总线传送到外部RAM中),则多路开关“控制”信号为„1‟,“与门”解锁,与输出地址信号的工作流程类似,数据据由“地址/数据”线→反相器→V2场效应管栅极→V2漏极输出。
如果该指令是输入数据(读外部数据存储器或程序存储器),如MOVX A,@DPTR(将外部RAM某一存储单元内容通过P0口数据总线输入到累加器A中),则输入的数据仍通过读引脚三态缓冲器到内部总线,其过程类似于上图中的读取指令码流程图。
通过以上的分析可以看出,当P0作为地址/数据总线使用时,在读指令码或输入数据前,CPU自动向P0口锁存器写入0FFH,破坏了P0口原来的状态。因此,不能再作为通用的I/O端口。大家以后在系统设计时务必注意,即程序中不能再含有以P0口作为操作数(包含源操作数和目的操作数)的指令。
二、P1端口的结构及工作原理
P1口的结构最简单,用途也单一,仅作为数据输入/输出端口使用。输出的信息有锁存,输入有读引脚和读锁存器之分。P1端口的一位结构见下图.由图可见,P1端口与P0端口的主要差别在于,P1端口用内部上拉电阻R代替了P0端口的场效应管T1,并且输出的信息仅来自内部总线。由内部总线输出的数据经锁存器反相和场效应管反相后,锁存在端口线上,所以,P1端口是具有输出锁存的静态口。
由上图可见,要正确地从引脚上读入外部信息,必须先使场效应管关断,以便由外部输入的信息确定引脚的状态。为此,在作引脚读入前,必须先对该端口写入l。具有这种操作特点的输入/输出端口,称为准双向I/O口。8051单片机的P1、P2、P3都是准双向口。P0端口由于输出有三态功能,输入前,端口线已处于高阻态,无需先写入l后再作读操作。
P1口的结构相对简单,前面我们已详细的分析了P0口,只要大家认真的分析了P0口的工作原理,P1口我想大家都有能力去分析,这里我就不多论述了。
单片机复位后,各个端口已自动地被写入了1,此时,可直接作输入操作。如果在应用端口的过程中,已向P1一P3端口线输出过0,则再要输入时,必须先写1后再读引脚,才能得到正确的信息。此外,随输入指令的不同,H端口也有读锁存器与读引脚之分。
三、P2端口的结构及工作原理: P2端口的一位结构见下图:
由图可见,P2端口在片内既有上拉电阻,又有切换开关MUX,所以P2端口在功能上兼有P0端口和P1端口的特点。这主要表现在输出功能上,当切换开关向下接通时,从内部总线输出的一位数据经反相器和场效应管反相后,输出在端口引脚线上;当多路开关向上时,输出的一位地址信号也经反相器和场效应管反相后,输出在端口引脚线上。
对于8031单片机必须外接程序存储器才能构成应用电路(或者我们的应用电路扩展了外部存储器),而P2端口就是用来周期性地输出从外存中取指令的地址(高8位地址),因此,P2端口的多路开关总是在进行切换,分时地输出从内部总线来的数据和从地址信号线上来的地址。因此P2端口是动态的I/O端口。输出数据虽被锁存,但不是稳定地出现在端口线上。其实,这里输出的数据往往也是一种地址,只不过是外部RAM的高8位地址。
在输入功能方面,P2端口与P0和H端口相同,有读引脚和读锁存器之分,并且P2端口也是准双向口。
可见,P2端口的主要特点包括: ①不能输出静态的数据;
②自身输出外部程序存储器的高8位地址;
②执行MOVX指令时,还输出外部RAM的高位地址,故称P2端口为动态地址端口。
即然P2口可以作为I/O口使用,也可以作为地址总线使用,下面我们就不分析下它的两种工作状态。
1、作为I/O端口使用时的工作过程
当没有外部程序存储器或虽然有外部数据存储器,但容易不大于256B,即不需要高8位地址时(在这种情况下,不能通过数据地址寄存器DPTR读写外部数据存储器),P2口可以I/O口使用。这时,“控制”信号为“0”,多路开关转向锁存器同相输出端Q,输出信号经内部总线→锁存器同相输出端Q→反相器→V2管栅极→V2管9漏极输出。
由于V2漏极带有上拉电阻,可以提供一定的上拉电流,负载能力约为8个TTL与非门;作为输出口前,同样需要向锁存器写入“1”,使反相器输出低电平,V2管截止,即引脚悬空时为高电平,防止引脚被钳位在低电平。读引脚有效后,输入信息经读引脚三态门电路到内部数据总线。
2、作为地址总线使用时的工作过程
P2口作为地址总线时,“控制”信号为„1‟,多路开关车向地址线(即向上接通),地址信息经反相器→V2管栅极→漏极输出。由于P2口输出高8位地址,与P0口不同,无须分时使用,因此P2口上的地址信息(程序存储器上的A15~A8)功数据地址寄存器高8位DPH保存时间长,无须锁存。
四、P3端口的结构及工作原理
P3口是一个多功能口,它除了可以作为I/O口外,还具有第二功能,P3端口的一位结构见下图。
由上图可见,P3端口和Pl端口的结构相似,区别仅在于P3端口的各端口线有两种功能选择。当处于第一功能时,第二输出功能线为1,此时,内部总线信号经锁存器和场效应管输入/输出,其作用与P1端口作用相同,也是静态准双向I/O端口。当处于第二功能时,锁存器输出1,通过第二输出功能线输出特定的内含信号,在输入方面,即可以通过缓冲器读入引脚信号,还可以通过替代输入功能读入片内的特定第二功能信号。由于输出信号锁存并且有双重功能,故P3端口为静态双功能端口。P3口的特殊功能(即第二功能): 使P3端品各线处于第二功能的条件是:
1、串行I/O处于运行状态(RXD,TXD);
2、打开了处部中断(INT0,INT1);
3、定时器/计数器处于外部计数状态(T0,T1)
4、执行读写外部RAM的指令(RD,WR)
在应用中,如不设定P3端口各位的第二功能(WR,RD信叼的产生不用设置),则P3端口线自动处于第一功能状态,也就是静态I/O端口的工作状态。在更多的场合是根据应用的需要,把几条端口线设置为第二功能,而另外几条端口线处于第一功能运行状态。在这种情况下,不宜对P3端口作字节操作,需采用位操作的形式。
端口的负载能力和输入/输出操作:
P0端口能驱动8个LSTTL负载。如需增加负载能力,可在P0总线上增加总线驱动器。P1,P2,P3端口各能驱动4个LSTTL负载。
前已述及,由于P0-P3端口已映射成特殊功能寄存器中的P0一P3端口寄存器,所以对这些端口寄存器的读/写就实现了信息从相应端口的输入/输出。例如: MOV A,P1 ;把Pl端口线上的信息输入到A MoV P1,A ;把A的内容由P1端口输出 MOV P3,#0FFH ;使P3端口线各位置l
第三篇:单片机实验报告
目录
第一章单片机简介....................................................2 第二章
实验要求..................................................3 第三章实验设备......................................................3 第四章实验安排......................................................4 第五章实验内容......................................................4
LED灯实验.......................................................4 步进马达试验....................................................5 独立按键控制LED实验............................................7 矩阵键盘实验....................................................9 静态数码管实验.................................................12 动态数码管实验.................................................14 NE555脉冲发生器实验(定时/计数器).............................16 RS232串口通信实验(接收与发送)..................................21 第六章收获体会.....................................................25
单片机实验报告
第一章单片机简介
单片机也被称为微控制器(Microcontroller),是因为它最早被用在工业控制领域。单片机由芯片内仅有CPU的专用处理器发展而来。最早的设计理念是通过将大量外围设备和CPU集成在一个芯片中,使计算机系统更小,更容易集成进复杂的而对体积要求严格的控制设备当中。INTEL的Z80是最早按照这种思想设计出的处理器,从此以后,单片机和专用处理器的发展便分道扬镳。单片机是靠程序运行的,并且可以修改。通过不同的程序实现不同的功能,尤其是特殊的独特的一些功能,这是别的器件需要费很大力气才能做到的,有些则是花大力气也很难做到的。一个不是很复杂的功能要是用美国50年代开发的74系列,或者60年代的CD4000系列这些纯硬件来搞定的话,电路一定是一块大PCB板!但是如果要是用美国70年代成功投放市场的系列单片机,结果就会有天壤之别!只因为单片机的通过你编写的程序可以实现高智能,高效率,以及高可靠性!
单片机诞生于20世纪70年代末,经历了SCM、MCU、SoC三大阶段。
1.SCM即单片微型计算机(Single Chip Microcomputer)阶段,主要是寻求最佳的单片形态嵌入式系统的最佳体系结构。“创新模式”获得成功,奠定了SCM与通用计算机完全不同的发展道路。在开创嵌入式系统独立发展道路上,Intel公司功不可没。
2.MCU即微控制器(Micro Controller Unit)阶段,主要的技术发展方向是:不断扩展满足嵌入式应用时,对象系统要求的各种外围电路与接口电路,突显其对象的智能化控制能力。它所涉及的领域都与对象系统相关,因此,发展MCU的重任不可避免地落在电气、电子技术厂家。从这一角度来看,Intel逐渐淡出MCU的发展也有其客观因素。在发展MCU方面,最著名的厂家当数Philips公司。
Philips公司以其在嵌入式应用方面的巨大优势,将MCS-51从单片微型计算机迅速发展到微控制器。因此,当我们回顾嵌入式系统发展道路时,不要忘记Intel和Philips的历史功绩。
3.单片机是嵌入式系统的独立发展之路,向MCU阶段发展的重要因素,就是寻求
单片机实验报告
应用系统在芯片上的最大化解决;因此,专用单片机的发展自然形成了SoC化趋势。随着微电子技术、IC设计、EDA工具的发展,基于SoC的单片机应用系统设计会有较大的发展。因此,对单片机的理解可以从单片微型计算机、单片微控制器延伸到单片应用系统。
MCS51系列微控制器应用广泛,在家电、汽车甚至航空等领域都有其活跃的身影。然而,普通51系列微控制器内部资源有限,像我用Proteus构建微控制器虚拟实验室选用的AT89C52只有三个定时器、一个全双工的串行口和中断控制,并且其数据处理能力有限,不适合对大量数据进行复杂分析和运算。
因此,在不重新选型(可选用SoC)的前提下,为实现我们所需要的功能,就需要进行外围扩展。针对微控制器的特点,我们首先考虑串行扩展,因为微控制器的I/O引脚有限,并行扩展一则外围芯片面积比较大,二则对抑制EMI不利。
第二章 实验要求
1.学习Keil C51集成开发工具的操作及调试程序的方法,包括:仿真调试与脱机运行间的切换方法
2.熟悉TD-51单片机系统板及实验系统的结构及使用
3.进行MCS51单片机指令系统软件编程设计与硬件接口功能设
4. 学习并掌握Keil C51软件联机进行单片机接口电路的设计与编程调试
5.完成指定MCS51单片机综合设计题
第三章实验设备
1.HC600S-51单片机开发板 2.Keil C51 3.普中自动下载软件
第四章 实验安排
1.LED灯实验
单片机实验报告
2.步进马达试验
3.独立按键控制LED实验 4.矩阵键盘实验 5.静态数码管实验 6.动态数码管实验
7.NE555脉冲发生器实验(定时/计数器)8.RS232串口通信实验(接收与发送)
第五章 实验内容
一、LED灯实验
1.基本要求
利用位移循环指令实现LED灯的闪烁 2.实验内容
在Keil C51中进行程序的编写设计并生成.HEX文件,按照下图连接电路后将HC600S-51单片机开发板接通电源,按下开关,录入。打开普中录入生成.HEX文件,加载程序,观察实验结果,如果不正确对程序进行改进后重复此操作。实验结束后先断电源再拆线,将元器件归位后离开。3.接线图
4.电路原理图
单片机实验报告
5.程序
#include
main(){unsigned int i;while(1)
{for(i=0,P0=1;i<4;i++){d(500);P0=(P0<<2);}}}
二、步进马达试验
1.基本要求
编程实现马达的正反转,调速等功能 2.实验内容
在Keil C51中进行程序的编写设计并生成.HEX文件,按照下图连接电路后将HC600S-51单片机开发板接通电源,按下开关,录入。打开普中录入生成.HEX文件,加载程序,观察实验结果,如果不正确对程序进行改进后重复此操作。实验结束后先断电源再拆线,将元器件归位后离开。3.接线图(图一)
单片机实验报告
图一 图二
4.电路原理图
上图图二 5.程序
#include “reg52.h” #define speed 2 sbit PH1 = P1^0;
//定义管脚 sbit PH2 = P1^1;sbit I01 = P1^2;sbit I11 = P1^3;sbit I02 = P1^4;sbit I12 = P1^5;
void delay(int time);
void Go(){ //A
PH1 = 0;//PH1为0 则A线圈为反向电流
I01 = 0;I11 = 0;
//以最大电流输出
PH2 = 0;//PH2为0 则B线圈为反向电流
I02 = 1;I12 = 1;
//输出0 delay(speed);//圈为反向电流
I01 = 1;//输出0 I11 = 1;
PH2 = 1;//PH2为1 则B线圈为正向电流
I02 = 0;//以最大电流输出
I12 = 0;
delay(speed);//B PH1 = 1;
//PH1为1 则A线圈为
正向电流
I01 = 0;
//以最大电流输出
I11 = 0;
PH2 = 1;//PH2为1 则B线圈为正
向电流
I02 = 1;//输出0 I12 = 1;
delay(speed);
PH1 = 1;
//PH1为1 则A线圈为正向电流
I01 = 1;I11 = 1;
PH2 = 0;
//PH2为0 则B线圈为反向电流
I02 = 0;I12 = 0;delay(speed);}
void delay(int time){
int i,j;
for(j=0;j <= time;j++)
for(i =0;i <= 120;i++);}
void main(){
while(1)
{
Go();//步进电机运行
} }
单片机实验报告
三、独立按键控制LED实验
1.基本要求
通过编程控制8个独立按键分别控制8个LED灯的开关 2.实验内容
在Keil C51中进行程序的编写设计并生成.HEX文件,按照下图连接电路后将HC600S-51单片机开发板接通电源,按下开关,录入。打开普中录入生成.HEX文件,加载程序,观察实验结果,如果不正确对程序进行改进后重复此操作。实验结束后先断电源再拆线,将元器件归位后离开。3.接线图(图一)
图一 图二
4.电路原理图 上图图二 5.程序
#include
P1口
#define uchar unsigned char #define uint unsigned int
void Delayms(unsigned int c);
//延时10ms uchar Key_Scan();void main(void){
unsigned char ledValue, keyNum;
ledValue = 0x01;
while(1)
{
keyNum = Key_Scan();//扫描键
盘
switch(keyNum)
{
case(0xFE):
//返回按
键K1的数据
ledValue = 0x01;
break;
单片机实验报告
case(0xFD):
ledValue = 0x02;
break;case(0xFB):
ledValue = 0x04;
break;case(0xF7):
ledValue = 0x08;
break;case(0xEF):
ledValue = 0x10;
break;case(0xDF):
ledValue = 0x20;
break;case(0xBF):
ledValue = 0x40;
break;case(0x7F):
ledValue = 0x80;
//返回按键K2的数据
//返回按键K3的数据
//返回按键K4的数据
//返回按键K5的数据
//返回按键K6的数据
//返回按键K7的数据
//返回按键K8的数据
break;default:
break;
}
GPIO_LED = ledValue;//点亮LED灯
}
}
uchar Key_Scan(void)//键盘扫描函数 { uchar i,n=0xff;
if(P1==0xff)goto Scan_r;//无键按
下,返回
goto Scan_r;Scan_1:
while(P1!=0xff);//等待键释放
Delayms(10);Scan_r:
return n;}
void Delayms(uint x){
uint n;
for(;x>0;x--)
{
for(n=0;n<123;n++)
{;}
} }
四、矩阵键盘实验
1.基本要求
编程由16个矩阵按键控制数码管显示相应的数值 2.实验内容
在Keil C51中进行程序的编写设计并生成.HEX文件,按照下图连接电路后将HC600S-51单片机开发板接通电源,按下开关,录入。打开普中录入生成.HEX文件,加载程序,观察实验结果,如果不正确对程序进行改进后重复此操作。实验结束后先断电源再拆线,将元器件归位后离开。
3.接线图
单片机实验报告
见下图图一
图一 图二
4.电路原理图
见上图图二 5.程序
#include
uchar ScanKey(void);void Delayms(uint x);main(){ unsigned char ledValue;uchar i;ledValue = 0x01;loop: i = ScanKey();
switch(i)
{ case 0xee:
ledValue = ~0x3F;
break;
case 0xde:
ledValue = ~0x06;
break;
case 0xbe:
ledValue = ~0x5B;
break;
case 0x7e:
ledValue = ~0x4F;
break;
case 0xed:
ledValue = ~0x66;
break;
case 0xdd:
ledValue = ~0x6D;
break;
单片机实验报告
case 0xbd:
ledValue = ~0x7D;
break;
case 0x7d:
ledValue = ~0x07;
break;
case 0xeb:
ledValue = ~0x7F;
break;
case 0xdb:
ledValue = ~0x6F;
break;
case 0xbb:
ledValue = ~0x77;
break;
case 0x7b:
ledValue = ~0x7C;
break;
case 0xe7:
ledValue = ~0x39;
break;
case 0xd7:
ledValue = ~0x5E;
break;
case 0xb7:
ledValue = ~0x79;
break;
case 0x77:
ledValue = ~0x71;
break;
}
GPIO_LED = ledValue;i=0;goto loop;}
void Delayms(uint x){uint n;for(;x > 0;x--)
{ for(n=0;n<123;n++)
{;}
} }
uchar ScanKey(void)//键盘扫描函数 { uchar i,n=0xff;
P1=0xf0;
if(P1==0xf0)goto Scan_r;//无键按下,返回
for(i=0,P1=0xfe;i<4;i++)
{ if((P1&0xf0)!=0xf0)
{ Delayms(10);
if((P1&0xf0)!=0xf0)
{ n=
P1;
goto
Scan_1;}
}
P1=(P1<<1)+1;
//扫描下
一行
} goto Scan_r;Scan_1:
单片机实验报告
P1=0xf0;while((P1&0xf0)!=0xf0);//等待键
释放
Delayms(10);
Scan_r:
P1=0xff;return n;} }
五、静态数码管实验
1.基本要求
编程使数码管显示字符0-F 2.实验内容
在Keil C51中进行程序的编写设计并生成.HEX文件,按照下图连接电路后将HC600S-51单片机开发板接通电源,按下开关,录入。打开普中录入生成.HEX文件,加载程序,观察实验结果,如果不正确对程序进行改进后重复此操作。实验结束后先断电源再拆线,将元器件归位后离开。3.接线框图(图一)
图一
单片机实验报告
图二
4.电路原理图
见上图图二 5.程序
#include
{~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D, ~0x7D,~0x07,~0x7F,~0x6F,~0x77,~0x7C,~0x39,~0x5E,~0x79,~0x71};main(){
unsigned int LedNumVal;//定义变量 while(1)
{
// 将字模送到P0口显示
LedNumVal++;
P0 = LED7Code[LedNumVal%16];
Delayms(1000);
//调用延时程序
}
}
单片机实验报告
void Delayms(uint x){uint n;for(;x > 0;x--)
{ for(n=0;n<123;n++)
{;}
} }
六、动态数码管实验
1.基本要求
编程实现8个数码管的动态扫描。通过P22、P23、P24控制3-8译码器来对数码管进行位选,通过P0口经过573的驱动控制数码管的段选,通过P13控制573的使能端,为低电平时573才会有输出。2.实验内容
在Keil C51中进行程序的编写设计并生成.HEX文件,按照下图连电路后将HC600S-51单片机开发板接通电源,按下开关,录入。打开普中录入生成.HEX文件,加载程序,观察实验结果,如果不正确对程序进行改进后重复此操作。实验结束后先断电源再拆线,将元器件归位后离开。3.接线图(图一)
图一 图二
单片机实验报告
图三
4.电路原理图
见上图图
二、图三 5.程序
#define uint unsigned int void Dsplay();void Delayms(uint x);uchar mDS[6];uchar code cDsCode[]=
{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xf8,0x80,0x90};
void main(){ uchar i;
for(i=0;i<6;i++)mDS[i]=i+1;
loop:
Dsplay();
goto loop;}
void Dsplay()//动态扫描显示
{uchar i;
for(i=0,P2=0x01;i<6;i++)
{ P1=cDsCode[mDS[i]];//输出段
Delayms(1000);
P2=P2<<1;
//选通下一位
}
P2=0x00;
//关闭位选通 }
void Delayms(uint x){uint n;for(;x > 0;x--)
{ for(n=0;n<123;n++)
{;}
} }
七、NE555脉冲发生器实验(定时/计数器)
1.基本要求
2.实验内容
在Keil C51中进行程序的编写设计并生成.HEX文件,按照下图连接电路后将HC600S-51单片机开发板接通电源,按下开关,录入。打开普中录入生成.HEX文件,加载程序,观察实验结果,如果不正确对程序进行改进后重复此操作。实验结束后先断电源再拆线,将元器件归位后离开。3.接线图
4.电路原理图
5.程序
#include
CYMOMETER
”};uchar code EN_CHAR2[16]={“FREQ:
HZ”};
单片机实验报告
void TIMER_Configuration();//初始化定时器 ulong Freq;
//用来存放要显示的频率值 ulong TimeCount;//用于计算1S钟的
void main(){ uchar i, freqValue[6];
LcdInit();TIMER_Configuration();for(i=0;i<16;i++){
LcdWriteData(EN_CHAR1[i]);}
LcdWriteCom(0xc0);//第二行显示
for(i=0;i<16;i++){
LcdWriteData(EN_CHAR2[i]);}
while(1){
if(TR0==0)
//当计数器停下的时候,表明计数完毕
{
Freq = Freq + TL1;
//读取TL的值
Freq = Freq +(TH1 * 256);//读取TH的值
LcdWriteCom(0xc8);
//--求频率的个十百千万十万位--//
freqValue[0]='0'+Freq%1000000/100000;
freqValue[1]='0'+Freq%100000/10000;
freqValue[2]='0'+Freq%10000/1000;
freqValue[3]='0'+Freq%1000/100;
freqValue[4]='0'+Freq%100/10;
freqValue[5]='0'+Freq%10;
for(i=0;i<5;i++)//从最高位开始查找不为0的数开始显示(最低位为0显示0)
{
if(freqValue[i]==0x30)
{
freqValue[i]=0x20;//若为0则赋值空格键
}
else
单片机实验报告
{
break;
}
}
for(i=0;i<6;i++)
{
LcdWriteData(freqValue[i]);
}
Freq=0;//将计算的频率清零
TH1=0;//将计数器的值清零
TL1=0;
TR0=1;//开启定时器
TR1=1;//开启计数器
} } }
void TIMER_Configuration(){ TMOD=0x51;TH0=0x3C;TL0=0xB0;ET0=1;ET1=1;EA=1;TR0=1;TR1=1;} void Timer0()interrupt 1 { TimeCount++;if(TimeCount==20)//计时到1S {
TR0=0;
TR1=0;
TimeCount=0;
}
//--12MHZ设置定时50ms的初值--// TH0=0x3C;TL0=0xB0;} void Timer1()interrupt 3 {
单片机实验报告
//--进入一次中断,表明计数到了65536--// Freq=Freq+65536;
}
#include“lcd.h”
void Lcd1602_Delay1ms(uint c)
//误差 0us {
uchar a,b;for(;c>0;c--){
for(b=199;b>0;b--)
{
for(a=1;a>0;a--);
}
}
} #ifndef LCD1602_4PINS //当没有定义这个LCD1602_4PINS时 void LcdWriteCom(uchar com)
//写入命令 { LCD1602_E = 0;
//使能
LCD1602_RS = 0;
//选择发送命令
LCD1602_RW = 0;
//选择写入
LCD1602_DATAPINS = com;
//放入命令
Lcd1602_Delay1ms(1);//等待数据稳定
LCD1602_E = 1;
//写入时序
Lcd1602_Delay1ms(5);
//保持时间
LCD1602_E = 0;} #else
void LcdWriteCom(uchar com)
//写入命令 { LCD1602_E = 0;//使能清零
LCD1602_RS = 0;//选择写入命令
LCD1602_RW = 0;//选择写入
LCD1602_DATAPINS = com;// Lcd1602_Delay1ms(1);LCD1602_E = 1;//写入时序
Lcd1602_Delay1ms(5);LCD1602_E = 0;Lcd1602_Delay1ms(1);
单片机实验报告
LCD1602_DATAPINS = com << 4;//发送低四位
Lcd1602_Delay1ms(1);
LCD1602_E = 1;//写入时序
Lcd1602_Delay1ms(5);LCD1602_E = 0;} #endif #ifndef LCD1602_4PINS
void LcdWriteData(uchar dat)
//写入数据 { LCD1602_E = 0;//使能清零
LCD1602_RS = 1;//选择输入数据
LCD1602_RW = 0;//选择写入
LCD1602_DATAPINS = dat;//写入数据
Lcd1602_Delay1ms(1);
LCD1602_E = 1;
//写入时序
Lcd1602_Delay1ms(5);
//保持时间
LCD1602_E = 0;} #else void LcdWriteData(uchar dat)
//写入数据 { LCD1602_E = 0;//使能清零
LCD1602_RS = 1;
//选择写入数据
LCD1602_RW = 0;
//选择写入
LCD1602_DATAPINS = dat;
Lcd1602_Delay1ms(1);LCD1602_E = 1;//写入时序
Lcd1602_Delay1ms(5);LCD1602_E = 0;LCD1602_DATAPINS = dat << 4;//写入低四位
Lcd1602_Delay1ms(1);LCD1602_E = 1;//写入时序
Lcd1602_Delay1ms(5);LCD1602_E = 0;} #endif #ifndef LCD1602_4PINS void LcdInit()
//LCD初始化子程序 { LcdWriteCom(0x38);//开显示
单片机实验报告
LcdWriteCom(0x0c);//开显示不显示光标
LcdWriteCom(0x06);//写一个指针加1 LcdWriteCom(0x01);//清屏
LcdWriteCom(0x80);//设置数据指针起点 } #else void LcdInit()
//LCD初始化子程序 { LcdWriteCom(0x32);//将8位总线转为4位总线
LcdWriteCom(0x28);//在四位线下的初始化
LcdWriteCom(0x0c);//开显示不显示光标
LcdWriteCom(0x06);//写一个指针加1 LcdWriteCom(0x01);//清屏
LcdWriteCom(0x80);//设置数据指针起点 } #endif
八、RS232串口通信实验(接收与发送)
1.基本要求
a.通过实验了解串口的基本原理及使用,理解并掌握对串口进行初始化; b.使用串口调试助手(Baud 9600、数据位
8、停止位
1、效验位无)做为上位机来做收发试验;
c.利用串口调试助手中字符串输入进行数据发送,接受窗口显示收到的数据。2.实验内容
在Keil C51中进行程序的编写设计并生成.HEX文件,按照下图连接电路后将HC600S-51单片机开发板接通电源,按下开关,录入。打开普中录入生成.HEX文件,加载程序,观察实验结果,如果不正确对程序进行改进后重复此操作。实验结束后先断电源再拆线,将元器件归位后离开。3.接线图
单片机实验报告
4.电路原理图
5.程序
#include
LcdWriteData(ChCode[i]);} UsartConfiguration();while(1){
if(RI == 1)
//查看是否接收到数据
{
receiveData = SBUF;//读取数据
单片机实验报告
RI = 0;
//清除标志位
LcdWriteCom(0xC0);
LcdWriteData('0' +(receiveData / 100));
// 百位
LcdWriteData('0' +(receiveData % 100 / 10));// 十位
LcdWriteData('0' +(receiveData % 10));
// 个位
} } } void UsartConfiguration(){ SCON=0X50;
//设置为工作方式1 TMOD=0X20;//设置计数器工作方式2 PCON=0X80;
//波特率加倍
TH1=0XF3;
//计数器初始值设置,注意波特率是4800的TL1=0XF3;TR1=1;
//打开计数器 }
#include“lcd.h”
void Lcd1602_Delay1ms(uint c)
//误差 0us {
uchar a,b;for(;c>0;c--){
for(b=199;b>0;b--)
{
for(a=1;a>0;a--);
}
}
} #ifndef LCD1602_4PINS //当没有定义这个LCD1602_4PINS时 void LcdWriteCom(uchar com)
//写入命令 { LCD1602_E = 0;
//使能
LCD1602_RS = 0;
//选择发送命令
LCD1602_RW = 0;
//选择写入
LCD1602_DATAPINS = com;
//放入命令
Lcd1602_Delay1ms(1);//等待数据稳定
LCD1602_E = 1;
//写入时序
单片机实验报告
Lcd1602_Delay1ms(5);
//保持时间
LCD1602_E = 0;} #else
void LcdWriteCom(uchar com)
//写入命令 { LCD1602_E = 0;//使能清零
LCD1602_RS = 0;//选择写入命令
LCD1602_RW = 0;//选择写入
LCD1602_DATAPINS = com;Lcd1602_Delay1ms(1);LCD1602_E = 1;//写入时序
Lcd1602_Delay1ms(5);LCD1602_E = 0;Lcd1602_Delay1ms(1);LCD1602_DATAPINS = com << 4;//发送低四位
Lcd1602_Delay1ms(1);LCD1602_E = 1;//写入时序
Lcd1602_Delay1ms(5);LCD1602_E = 0;} #endif
#ifndef LCD1602_4PINS
void LcdWriteData(uchar dat)
//写入数据 { LCD1602_E = 0;//使能清零
LCD1602_RS = 1;//选择输入数据
LCD1602_RW = 0;//选择写入
LCD1602_DATAPINS = dat;//写入数据
Lcd1602_Delay1ms(1);LCD1602_E = 1;
//写入时序
Lcd1602_Delay1ms(5);
//保持时间
LCD1602_E = 0;} #else void LcdWriteData(uchar dat)
//写入数据 { LCD1602_E = 0;
//使能清零
LCD1602_RS = 1;
//选择写入数据
LCD1602_RW = 0;//选择写入
LCD1602_DATAPINS = dat;
Lcd1602_Delay1ms(1);LCD1602_E = 1;
//写入时序
Lcd1602_Delay1ms(5);
单片机实验报告
LCD1602_E = 0;LCD1602_DATAPINS = dat << 4;//写入低四位
Lcd1602_Delay1ms(1);LCD1602_E = 1;
//写入时序
Lcd1602_Delay1ms(5);LCD1602_E = 0;} #endif
#ifndef LCD1602_4PINS void LcdInit()
//LCD初始化子程序 { LcdWriteCom(0x38);//开显示
LcdWriteCom(0x0c);//开显示不显示光标
LcdWriteCom(0x06);//写一个指针加1 LcdWriteCom(0x01);//清屏
LcdWriteCom(0x80);//设置数据指针起点 } #else void LcdInit()
//LCD初始化子程序 { LcdWriteCom(0x32);//将8位总线转为4位总线
LcdWriteCom(0x28);//在四位线下的初始化
LcdWriteCom(0x0c);//开显示不显示光标
LcdWriteCom(0x06);//写一个指针加1 LcdWriteCom(0x01);//清屏
LcdWriteCom(0x80);//设置数据指针起点 } #endif
单片机实验报告
第六章 收获体会
本次微控制器综合设计基本上使用了所选微控制器的所有资源,进一步熟悉和加深了对中断、定时器和串行通信的理解和使用。我觉得软件实验就是让我们初学者熟悉keil的使用,然后复习下汇编的思想和掌握程序的流程,所以软件实验可以很快的完成,并且慢慢熟悉调试的强大功能。硬件设计中,仿真让我很有感触,感觉蛮好玩的,可以摒弃麻烦的实验硬件自己在寝室玩而且不受硬件状态的限制,即便出错了也不会损坏。当然更重要的是这种好习惯,仿真完后再去在实验板上验证会比直接要来的确切而且便捷,至少不要老是去插拔线。在做实验中在同学指导下我试用C语言来编写程序,确实发现比汇编语言容易编写也容易理解,以前的实验还是有参考资料的习惯,现在什么都开始自己写感觉还是很有成就感的,当然这是基于程序本身就那么几行很容易编写,也不是说参考不好。总而言之,这学期的单片机实验还是收获颇丰的。相信在以后的实验学习实践工作中都会有个潜移默化的作用的。
第四篇:单片机实验报告
单片机实验报告
一、实验目的
1.熟练使用Keil、Protues两款软件 2.通过上机操作,增强个人动手实践能力 3.加深对理论知识的理解
4.培养运用汇编语言进行初步编写程序的能力
二、实验内容
1.将片外RAM3050-306FH中数据转移至片内70-8FH中。
要求:可以从Keil或Protues上看到RAM的数据转移结果。2.设计一个外部中断触发流水灯系统:当外部中断来临时,启动流水灯,即令P2口的LED轮流循环点亮。
要求:开发板或Prrotues演示
3.将片内存储器80H中存放的BCD码转换为ASCII码,要求使用表格查询技术。
要求:在Keil或Protues上看到数据转换结果。
4.各使用中断方式和查询方式设计一个方波发生器,频率为50HZ。
要求:Protues使软件间示波器显示方波。
三、实验程序
1.将片外RAM3050-306FH中数据转移至片内70-8FH中
ORG 0000H AJMP MAIN 上电,转向主程序
ORG 0030H 主程序入口
MAIN: MOV DPTR,#3050H 数据指针指向地址3050H MOV A,#04H 将立即数04H送A寄存器
MOV R0,#20H NEXT: MOVX @DPTR,A INC DPTR 数据指针DPTR自加一
DJNZ R0,NEXT 判断是否跳转到NEXT或继续向下执行
MOV DPTR,#3050H MOV R0,#70H MOV R2,#20H NEXT1: MOVX A,@DPTR MOV @R0,A INC DPTR INC R0 DJNZ R2,NEXT1
SJMP $ 等待
END 2.设计一个外部中断触发流水灯系统:当外部中断来临时,启动流水灯,即令P2口的LED轮流循环点亮 ORG 0000H SJMP MAIN 上电,转向主程序
ORG 0003H 外部中断0向量入口
AJMP INSER ORG 0030H 主程序入口
MAIN: SETB EX0 SETB IT0
SETB EA CPUHERE: SJMP HERE ORG 0200H INSER: MOV R2,#08H MOV A,#01H NEXT: MOV P2,A LCALL DELAY RL A DJNZ R2,NEXT NEXT或继续向下执行
RETI DELAY: MOV R3,#0FFH DEL2: MOV R4,#0FFH DEL1: NOP
允许外部中断0中断 选择边沿触发方式 开中断 等待中断 设置循环次数 赋初值,设置高电平亮 将初值送往P2口 延时 左移一位
判断循环次数,是否跳转到中断返回 延时程序 DJNZ R4,DEL1 DJNZ R3,DEL2 RET END 3.将片内存储器80H中存放的BCD码转换为ASCII码,要求使用表格查询技术 ORG 0000H LJMP MAIN ORG 0030H主程序起始地址 MAIN: MOV 80H,#05H 将立即数50H转送内存单元80H MOV A,80H 将内存单元80H中的内容送寄存器A MOV DPTR,#TAB MOVC A,@A+DPTR A寄存器内容加指针偏移量后送A寄存器 MOV 80H,A RET TAB: DB 30H,31H,32H,33H,34H DB 35H,36H,37H,38H,39H 4.1中断方式产生50HZ方波
ORG 0000H
AJMP MAIN
ORG 0030H 主程序入口 MAIN: MOV TMOD,#10H 设置定时器工作模式为模式1 MOV TH1,#0D8H 装入T1计数初值
MOV TL1,#0F0H
SETB ET1 开中断
SETB EA CPU开中断
SETB TR1 启动定时器T1 HERE: SJMP HERE 等待中断 ORG 001BH T1中断向量地址
CLR TF1 将TF1清零
CPL P2.0 P2.0取反输出
MOV TH1,#0D8H 重装初值
MOV TH0,#0F0H
RETI;中断返回
END 4.2 查询方式产生50HZ方波
ORG 0000H
AJMP MAIN
ORG 0030H 主程序入口
MAIN: MOV TMOD,#10H 设置定时器的工作模式为模式1 SETB TR1 启动定时器T1 LOOP: MOV TH1,#0D8H 装入T1计数初值
MOV TH0,#0F0H JNB TF1,$ T1没有溢出则等待
CLR TF1
产生溢出,清标志位
CPL P2.0 P2.0取反输出
SJMP LOOP 循环
END
四、实验结果截图
1.2
3.4.1
4.2
第五篇:单片机实验报告
实验
四、中断交通灯实验
林立强
1000850116
一、实验目的
1、了解MCS-51单片机的组成、中断原理,中断处理过程、外部中断的中断方式。
2、掌握中断响应及处理的编程方法。
二、实验原理
MCS-51的中断系统中有5个中断源:外部中断INTO,INT1,定时器/计数器TO、T1中断和串口UART中断,它们对应不同的中断矢量。如表:
IE是中断允许寄存器,其中EXO,ETO,EX1,ET1,ES分别是上述5个中断的允许控制位,EA位是中断总允许位,每个中断只有在相应中断允许且总中断也允许的情况下,才能得到中断响应。80XX51的5个中断都可以设为高低2个优先级,IP是中断优先级寄存器,其中PXO,PTO,PX1,PT1,PS位分别对应5个中断的优先级设置,置“1”时设为高优先级中断,为“0”时是低优先级中断。在有中断嵌套要求时,低优先级中断可被高优先级所中断。当同一级的中断同时到来时,先响应中断矢量排在前面的中断。
三、实验电路
电路原理图如下,所需元件为:AT89C51、SW-SPDT、LED-RED、LED-GREEN、LED-YELLOW、RES、TRAFFICLIGHTS
四、实验内容
参照实验电路,设计交通灯控制系统。模拟交通信号灯控制:一般情况下正常显示,东西-南北交替放行,各方向通行时间为30秒。有救护车或警车到达时,两个方向交通信号灯全为红色,以便让急救车或警车通过,设通行时间为10秒,之后交通恢复正常。用单次脉冲模拟急救车或警车申请外部中断。
1、在生成HEX文件后,用Proteus软件对电路图进行计算机仿真;
2、程序下载到单片机实验板上验证;(实验板数码管的驱动程序见附件)。
五、程序流程图
仿真图:
紧急情况:
源程序:
ORG 0000H
AJMP START
ORG 0023H //串口中断地址
AJMP SBR1
START:MOV TMOD,#00100000B
//定时器方式2
MOV TL1,#0FDH //9600bps/11.0592MHz
MOV TH1,#0FDH
SETB TR1
MOV SCON,#01100000B //方式1
MOV R0,#20H
MOV R1,#40H
ACALL SOUT
SJMP $
SBR1: JNB RI,SEND
ACALL SIN
SJMP NEXT SEND: ACALL SOUT NEXT: RETI
SOUT: MOV A,@R0
MOV C,P
CPL C
MOV ACC.7,C
INC R0
MOV SBUF,A
CLR TI
RET
SIN: MOV A,SBUF
MOV C,P
CPL C
ANL A,#7FH
MOV @R1,A
INC R1
CLR RI
RET
PLAY: MOV A,R7
MOV B,#10
RET
TAB: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H
// 0
A B C D E F
END