当前位置:首页 > 单片机控制闪烁灯
1. 实验任务
如图4.1.1所示:在P1.0端口上接一个发光二极管L1,使L1在不停地一亮一灭,一亮一灭的时间间隔为0.2秒。
2. 电路原理图
图4.1.1
3. 系统板上硬件连线
把“单片机系统”区域中的P1.0端口用导线连接到“八路发光二极管指示模块”区域中的L1端口上。
4. 程序设计内容
(1). 延时程序的设计方法
作为单片机的指令的执行的时间是很短,数量大微秒级,因此,我们要求的闪烁时间间隔为0.2秒,相对于微秒来说,相差太大,所以我们在执行某一指令时,插入延时程序,来达到我们的要求,但这样的延时程序是如何设计呢?下面具体介绍其原理:
如图4.1.1所示的石英晶体为12MHz,因此,1个机器周期为1微秒=0.001毫秒(ms)
机器周期 微秒
2个
2 2
MOV R6,#20
D1: MOV R7,#248 2个 2+2×248=498 20×(2+2×248)
DJNZ R7,$
2个 2×248=496
DJNZ R6,D1 2个 2×20=40 10002
因此,上面的延时程序时间为10.002ms。 10002=2+(2+2*248)*20+40
由以上可知,当R6=10、R7=248时,延时5ms,R6=20、R7=248时,延时10ms,以此为基本的计时单位。如本实验要求0.2秒=200ms,10ms×R5=200ms,则R5=20,延时子程序如下:
DELAY: D1: D2:
MOV R5,#20 MOV R6,#20 MOV R7,#248 DJNZ R7,$ DJNZ R6,D2 DJNZ R5,D1 RET
(2). 输出控制
如图1所示,当P1.0端口输出高电平,即P1.0=1时,根据发光二极管的单向导电性可知,这时发光二极管L1熄灭;当P1.0端口输出低电平,即P1.0=0时,发光二极管L1亮;我们可以使用SETB P1.0指令使
P1.0端口输出高电平,使用CLR P1.0指令使P1.0端口输出低电平。
5. 程序框图
如图4.1.2所示
6. 汇编源程序
ORG 0
; ORG 的意思是什么就是
值不同跟系统程序存贮器地址有关. 以上面的程序来讲ORG 0000H接下来写的程序都在0000H后。ORG 2000H也一样。(如果ROM够大的话)
START:
CLR P1.0 LCALL DELAY
; “调用”(ACALL或LCALL)一下,避免重复编写也节省程序存储空间,子程序的最
后都要放一条返回指令既“RET”。
SETB P1.0 ;使P1.0变为1。灯亮。 LCALL DELAY
LJMP START ;转入主程序
MOV R5,#20 ;延时子程序,延时0.2秒 MOV R6,#20 MOV R7,#248 DJNZ R7,$ DJNZ R6,D2 DJNZ R5,D1 RET END
DELAY: D1: D2:
7. C语言源程序
#include
sbit D1=P1^0; //定义一个变量D1,值是P1的第一个口 void delay02s(void) {
unsigned char i,j,k; for(i=20;i>0;i--) for(j=20;j>0;j--) for(k=248;k>0;k--); }
void main(void) {
while(1) {
D1=0; //灯亮 delay02s();
D1=1; //灯灭 delay02s(); } }
//延时0.2秒子程序 2*(20*20*248)/(1000*1000)
单片机的延时及时序分析
第一个问题:延时程序分析
在上节课中,我们已经知道,程序中的符号R7、R6是代表了一个个的RAM单元,是用来放一些数据的,下面我们再来看一下其它符号的含义。 DELAY: MOV R7,#250 ;(6) D1: MOV R6,#250 ;(7) D2: DJNZ R6,D2 ;(8) DJNZ R7,D1 ;(9) RET ;(10)
MOV:这是一条指令,意思是传递数据。说到传递,我们都很清楚,传东西要从一个人的手上传到另一个人的手上,也就是说要有一个接受者,一个传递者和一样东西。从指令MOV R7,#250中来分析,R7是一个接受者,250是被传递的数,传递者在这条指令中被省略了(注意:并不是每一条传递指令都会省的,事实上大部份数据传递指令都会有传递者)。它的意义也 很明显:将数据250送到R7中去,因此执行完这条指令后,R7单元中的值就应当是250。在250前面有个#号,这又是什么意思呢?这个#就是用来说明250就是一个被传递的东西本身,而不是传递者。那么MOV R6,#250是什么意思,应当不用分析了吧。
DJNZ:这是另一条指令,我们来看一下这条指令后面跟着的两个东西,一个是R6,一个是D2,R6我们当然已知是什么了,查一下D2是什么。D2在本行的前面,我们已学过,这称之为标号。标号的用途是什么呢?就是给本行起一个名字。DJNZ指令的执行过程是这样的,它将其后面的第一个参数中的值减1,然后看一下,这个值是否等于0,如果等于0,就往下执行,如果不等于0,就转移,转到什么地方去呢?可能大家已猜到了,转到第二个参数所指定的地方去(请大家用自已的话讲一下这条语句是怎样执行的)。本条指令的最终执行结果就是,在原地转圈250次。 执行完了DJNZ R6,D2之后(也就是R6的值等于0之后),就会去执行下面一行,也就是DJNZ R7,D1,请大家自行分析一下这句话执行的结果。(转去执行MOV R6,#250,同时R7中的值减1),最终DJNZ R6,D2这句话将被执行250*250=62500次,执行这么多次同一条指令干吗?就是为了延时。
一个问题:如果在R6中放入0,会有什么样的结果?
第二个问题:单片机时序分析:
上节课中我们已经介绍了延时程序,但这还不完善,因为,我们只知道DJNZ R6,D2这句话会被执行62500次,但是执行这么多次需要多长时间呢?是否满足我们的要求呢?我们还不知道,所以下面要来解决这个问题。
先提一个问题:我们学校里什么是最重要的?
(铃声)校长可以出差,老师可以休息,但学校一日无铃声必定大乱。整个学校就是在铃声的统一指挥下,步调一致,统一协调地工作着。这个铃是按一定的时间安排来响的,我们可以称之为“时序时间的顺序”。一个由人组成的单位尚且要有一定的时序,计算机当然更要有严格的时序。事实上,计算机更象一个大钟,什么时候分针动,什么时候秒针动,什么时候时针动,都有严格的规定,一点也不能乱。计算机要完成的事更复杂,所以它的时序也更复杂。
我们已知,计算机工作时,是一条一条地从ROM中取指令,然后一步一步地执行,我们规定:计算机访问一次存储器的时间,称之为一个机器周期。这是一个时间基准,好象我们人用“秒”作为我们的时间基准一样,为什么不干脆用“秒”,多好,很习惯,学下去我们就会知道用“秒”反而不习惯。
一个机器周期包括12个时钟周期。下面让我们算一下一个机器周期是多长时间吧。设一个单片机工作于12M晶振,它的时钟周期是1/12(微秒)。它的一个机器周期是12*(1/12)也就是1微秒。(请计算一个工作于6M晶振的单片机,它的机器周期是多少)。 MCS-51单片机的所有指令中,有一些完成得比较快,只要一个机器周期就行了,有一些完成
得比较慢,得要2个机器周期,还有两条指令要4个机器周期才行。这也不难再解,不是吗?我让你扫地的执行要完成总得比要你完成擦黑板的指令时间要长。为了恒量指令执行时间的长短,又引入一个新的概念:指令周期。所谓指令周期就是指执行一条指令的时间。INTEL对每一条指令都给出了它的指令周期数,这些数据,大部份不需要我们去记忆,但是有一些指令是需要记住的,如DJNZ指令是双周期指令。
下面让我们来计算刚才的延时。首先必须要知道晶振的频率,我们设所用晶振为12M,则一个机器周期就是1微秒。而DJNZ指令是双周期指令,所以执行一次要2个微秒。一共执行62500次,正好125000微秒,也就是125毫秒。 练习:设计一个延时100毫秒的延时程序。
要点分析:1、一个单元中的数是否可以超过255。2、如何分配两个数。
如何精确计算延时子程序的执行时间?
汇编语言的一大优势就是能够精确控制程序的执行时间,这在编写一些对时序要求严格的外围器件驱动时由为重要!
;延时子程序,12M晶振延时约253毫秒 DELAY:
MOV R4,#2------执行1个机器周期,耗时1微秒 L3: MOV R2 ,#250---执行1个机器周期,耗时1微秒 L1: MOV R3 ,#251---执行1个机器周期,耗时1微秒
L2: DJNZ R3 ,L2---执行2个机器周期,反复执行251次(2x251)=502微秒)
DJNZ R2 ,L1-----执行2个机器周期,反复执行250次(1+502+2)*250=126250微秒) DJNZ R4 ,L3-----执行2个机器周期,反复执行2次 (1+1+502+126250+2)*2=253512微秒) RET
delay 加上第一条总共延时1+253512=253513微秒
共分享92篇相关文档