单片机流水灯设计方法
单片机流水灯设计方法
元件清单:
名称 型号 数量
电阻 470欧 8
发光二极管(普通白发红) 8
电阻 10K 1
电容 10UF 1
晶振 12MHZ 1
电容 30PF 2
导线
单片机(配底座) AT89S51 1
独立孔万用板
排针 (也可选用两针排线(配底座))
流水灯原理图
流水灯程序
从原理图可以看出,如果我们想让接在P1.0口的LED1亮起来,那么我们只要把P1.0口的电平变为低电平就可以了;相反,如果要接在P1.0口的LED1熄灭,就要把P1.0口的电平变为高电平就可以;同理,接在P1.1~P1.7口的其他7个LED的点亮和熄灭方法方法同LED1。因此,要实现流水灯功能,我们只要将LED2~LED8依次点亮、熄灭,依始类推,8只LED变会一亮一暗的做流水灯了。
实现8个LED流水灯程序用中文表示为:(P1.0低)、(延时)、(P1.0高、P1.1低)、(延时)、(P1.1高、P1.2低)、(延时)、(P1.2高、P1.3低)、(延时)、(P1.3高、P1.4低)、(延时)、(P1.4高、P1.5低)、(延时)、(P1.5高、P1.6低)、(延时)、(P1.6高、P1.7低)、(延时)、(P1.7高)、(返回到开始)、(程序结束)。
我们在程序一开始就给P1口送一个数,这个数本身就让P1.0先低,其他位为高,然后让这个数据向高位移动不就实现“流水”效果啦?的确如此!8051指令中没有让P1数据移动的指令,但有对累加器ACC中数据左移或右移的指令,ACC在指令中常写为A,累加器A数据左移指令为
ORG 00H
START:
MOV ACC,#0FEH ;将数11111110赋给累加器ACC,H代表十六进制 MOV P1,ACC ;将ACC上的11111110给P1此时.P1.0等亮,其他灯暗 MOV R0,#8 ;将数8赋给寄存器R0
LOOP:
RL A ;将ACC中的数据左移一位(移动一次时11111110 -->11111101) MOV P1,A ;把ACC移动过的数据送p1口显示
ACALL DELAY ;调用延时子程序
DJNZ R0,LOOP ;没有移动够8次继续移动 (将寄存器上的数据减1
不为0时执行逗号后面LOOP,为0时执行下
条指令)
AJMP START ;移动完7次后跳到开始重来,以达到循环流动效果 DELAY: ;----- 延时子程序 -----
MOV R1,#248 ;延时一段时间
D1:MOV R2,#248
DJNZ R2,$
DJNZ R1,D1
RET ;子程序返回
END ;程序结束
在上面主程序中用到了以下几条汇编语言指令:MOV、ACALL、RL、DJNZ,AJMP、RET、END。
MOV:数据传送指令 ACALL:是子程序调用指令,程序中调用了DELAY延时子程序
RL:数据左移指令为
DJNZ;减1条件转移指令,这是把减1与条件转移两种功能结合在一起的指令AJMP:是无条件跳转指令,意思是:跳转到指定的标号处继续运行
RET:子程序返回指令
END: 是程序结束的伪指令,意思是告诉编译器,程序到此结束。伪指令只告诉编译器此程序到此有何要求或条件,它不参与和影响程序的执行。
在上面源程序中
产生这种现象主要是因为单片机执行每条指令的时间很短,我们知道实验板上单片机的时钟高达12MHz,在这个时钟信号(即晶体振荡信号)下,一个“机器周期”仅大约1 (微秒)。本程序中我们用到的指令不是单周期就是双
周期,也就是说,执行一句用时仅1(微秒)或者2(微秒),也就是点亮和熄灭时间都为几微秒级别,在如此高速的流水速度下,8个LED发光与熄灭的时间都很短,当然凭我们的肉眼看不到“流水”效果了!而延时程序利用多次循环执行指令来达到目的。由于DJNZ为双周期指令执行一次2微秒,上面的延时程序延时间为2*248*248=123008 即0.123秒
这里需要说明的是,按汇编语法要求,所编制的程序(下称源程序)之格式和书写要求必须依下列原则:
1、源程序必须为纯文本格式文件,如用Windows“附件”中的“记事本”编写的文本文件;
2、源程序的扩展名应是 *.ASM;
3、一行只能写一条语句,以回车作为本句的结束,每一语句行长度应少于80个字符(即40个汉字)。
4、每行的格式应为:标号: 命令 参数 ;注释 。即一行由四部份组成,各部份的顺序不能搞错,依实际要求可以缺省其中的一部份或几部份,甚至全部省去,即空白行。需要使用标号时标号后面必须有“:”(冒号),而命令语句和参数之间必须用空格分开,如果命令有多个参数,则参数与参数之间必须用“,”(逗号)分开,需要注释时注释前必须用“;”(分号),“;”后面的语句可以写任何字符,包括汉字用于解释前面的汇编语句,它将不参与汇编,不生成代码。由于汇编程序对我们还不直观,所以在编写源程序时,应当养成多写注释的习惯,这样有助于今后源程序的阅读和维护。
标号是标志程序中某一行的符号名,编译后标号的数值就是标号所在行代码的地址。在宏汇编ASM51中标号的长度不受限制,但标号中不能包含‘:'或其它的一些特殊符号,也不能用汉字,可以用数字作标号,但必须用字母开头。当标号作参数用(如标号作转移地址),在命令后面出现时,必须舍去‘:'(如上面程序中的 AJMP START中的START是不能再有:)。每行只能有一个标号,一个标号只能用在一处,如果有两行用了同一个标号,则汇编时就会出错。由于标号的长度没有限制,可以用有意义的英文或汉语拼音来说明行,使源程序读起来更方便。在源程序中的字母不区分大小写,也就是说 start 和 START 是一样的,请不要用大小写方式去区分不同的标号。
知道了汇编语言程序的规则,就动手编辑源程序。在记事本上写上上面的程序,启动伟福仿真机模拟器,将上面的源程序*.asm导入到软件中,设置好仿真器参数(V5/S—POD-S8X5X-AT89S51),编译得到BIN格式的目标文件*.BIN,用ISP下载线将目标文件*.BIN烧写到AT89S51单片机中,接下来就是将烧写好的AT89S51从编程器上取下,放到做好的电路板上通电,我们就看到了LED1~LED8的