单⽚机p1⼝亮灯实验c语⾔代码,⼿把⼿教你单⽚机流⽔灯实验
(详解)
⼿把⼿教你单⽚机流⽔灯实验(详解)
单⽚机轻松⼊门教学
---------------------------------------------------------------------------------------------------------------
每当夜幕降临,我们可以看到⼤街各式各样⼴告牌上漂亮的霓虹灯,看起来令⼈赏⼼悦⽬,为夜幕中的城市增添了不少亮丽⾊彩。其实这些霓虹灯的⼯作原理和单⽚机流⽔灯是⼀样的,只不过霓虹灯的花样更多,看起来更漂亮⼀些。这⼀课我们就结合YL-51单⽚机开发板来⼿把⼿教你详细学习单⽚机的流⽔灯实验。
⾸先介绍实验的硬件设备:YL-51单⽚机开发板
YL-51单⽚机开发板上有8个⾼亮度发光⼆极管(见图1所⽰),可以⽤来做单⽚机流⽔灯、跑马灯。。。等实验,电路原理图见下图3。
图3
从原理图可以看出,如果我们想让接在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.0你变低,它就变低了。因为单⽚机听不懂我们的汉语的,只能接受⼆进制的“1、0......”机器代码。我们⼜怎样来使单⽚机按我们的意思去⼯作呢?为了让单⽚机⼯作,只能将程序写为⼆进制代码交给其执⾏;早期单⽚机开发⼈员就是使⽤⼈⼯编写的⼆进制代码交给单⽚机去⼯作的。今天,我们不必⽤烦⼈的⼆进制去编写程序,完全可以将我们容易理解的“程序语⾔”通过“翻译”软件“翻译”成单⽚机所需的⼆进制代码,然后交给单⽚机去执⾏。这⾥的“程序语⾔”⽬前主要有汇编语⾔和C语⾔两种;在这⾥我们所说的“翻译”软件,同⾏们都叫它为“编译器”,将“程序语⾔”通过编译器产⽣单⽚机的⼆进制代码的过程叫编译。前⾯说到,要想使LED1变亮,只需将对应的单⽚机引脚电平变为低电平就可以了。现在让我们将上⾯提到的8只LED 流⽔灯实验写为汇编语⾔程序。
实现8个LED流⽔灯汇编语⾔程序 liu01.asm
;----- 主程序开始 -----
START: CLR P1.0 ;P1.0输出低电平,使LED1点亮
ACALL DELAY ;调⽤延时⼦程序
SETB P1.0 ;P1.0输出⾼电平,使LED1熄灭
CLR P1.1 ;P1.1输出低电平,使LED2点亮
ACALL DELAY ;调⽤延时⼦程序
SETB P1.1 ;P1.1输出⾼电平,使LED2熄灭
CLR P1.2 ;P1.2输出低电平,使LED3点亮
ACALL DELAY ;调⽤延时⼦程序
SETB P1.2 ;P1.2输出⾼电平,使LED3熄灭
CLR P1.3 ;P1.3输出低电平,使LED4点亮
ACALL DELAY ;调⽤延时⼦程序
SETB P1.3 ;P1.3输出⾼电平,使LED4熄灭
最容易上手的编程语言CLR P1.4 ;P1.4输出低电平,使LED5点亮
ACALL DELAY ;调⽤延时⼦程序
SETB P1.4 ;P1.4输出⾼电平,使LED5熄灭
CLR P1.5 ;P1.5输出低电平,使LED6点亮
ACALL DELAY ;调⽤延时⼦程序
SETB P1.5 ;P1.5输出⾼电平,使LED6熄灭
CLR P1.6 ;P1.6输出低电平,使LED7点亮
ACALL DELAY ;调⽤延时⼦程序
SETB P1.6 ;P1.6输出⾼电平,使LED7熄灭
CLR P1.7 ;P1.7输出低电平,使LED8点亮
ACALL DELAY ;调⽤延时⼦程序
SETB P1.7 ;P1.7输出⾼电平,使LED8熄灭
ACALL DELAY ;调⽤延时⼦程序
AJMP START ;8个LED流了⼀遍后返回到标号START处再循环
;----- 延时⼦程序 -----
DELAY: MOV R0,#255 ;延时⼀段时间
D1: MOV R1,#255
DJNZ R1,$
DJNZ R0,D1
RET ;⼦程序返回
END ;程序结束
在上⾯主程序中⽤到了五条汇编语⾔指令:CLR、ACALL、SETB、LJMP、END。
CLR: 是将其后⾯指定的位清为0,程序中使对应端⼝输出低电平
ACALL:是⼦程序调⽤指令,程序中调⽤了DELAY延时⼦程序
SETB:是将其后⾯指定的位置成1,程序中使对应端⼝输出⾼电平
AJMP:是⽆条件跳转指令,意思是:跳转到指定的标号处继续运⾏
END: 是程序结束的伪指令,意思是告诉编译器,程序到此结束。伪指令只告诉编译器此程序到此有何要求或条件,它不参与和影响程序的执⾏。
在上⾯源程序中"ACALL DELAY"指令的作⽤是调⽤DELAY延时⼦程序。为什么要使⽤这指令呢?如果不⽤该指令能够实现"流⽔"效果吗?答案是肯定的,⼀定要⽤该指令才能看到我们需要的"流⽔"效果。如果不⽤该指令,则由于8个LED发光与熄灭的时间都很短,我们⾁眼⽆法看到LED的熄灭与点亮,
凭我们⾁眼看到的是LED1~LED8都同时亮(半亮),⽽看不到“流⽔”效果的!注:初学者可以将上⾯源程序中所有"ACALL DELAY"指令⾏删除后再编译后烧写到单⽚机进⾏验证⼀下。
产⽣这种现象主要是因为单⽚机执⾏每条指令的时间很短,我们知道实验板上单⽚机的时钟⾼达11.0592MHz,在这个时钟信号(即晶体振荡信号)下,⼀个“机器周期”仅⼤约1.08uS(微秒)。本程序中我们⽤到的SETB P.x和CLR P.x均属于单周期指令,也就是说,执⾏⼀句SETB P.x ⽤时仅1.08uS(微秒),CLR P.x 也是1.08uS(微秒);也就是点亮和熄灭时间都为1.08uS(微秒),在如此⾼速的流⽔速度下,8个LED发光与熄灭的时间都很短,当然凭我们的⾁眼看不到“流⽔”效果了!
这⾥需要说明的是,按汇编语法要求,所编制的程序(下称源程序)之格式和书写要求必须依下列原则:
1、源程序必须为纯⽂本格式⽂件,如⽤Windows“附件”中的“记事本”编写的⽂本⽂件或⽤UltraEdit⽂本编辑器编辑;
2、源程序的扩展名应是 *.ASM;
3、⼀⾏只能写⼀条语句,以回车作为本句的结束,每⼀语句⾏长度应少于80个字符(即40个汉字)。
4、每⾏的格式应为:标号: 命令 参数 ;注释 。即⼀⾏由四部份组成,各部份的顺序不能搞错,依实际要求可以缺省其中的⼀部份或⼏部份,甚⾄全部省去,即空⽩⾏。需要使⽤标号时标号后⾯必须有“:
”(冒号),⽽命令语句和参数之间必须⽤空格分开,如果命令有多个参数,则参数与参数之间必须⽤“,”(逗号)分开,需要注释时注释前必须⽤“;”(分号),“;”后⾯的语句可以写任何字符,包括汉字⽤于解释前⾯的汇编语句,它将不参与汇编,不⽣成代码。由于汇编程序对我们还不直观,所以在编写源程序时,应当养成多写注释的习惯,这样有助于今后源程序的阅读和维护。
标号是标志程序中某⼀⾏的符号名,编译后标号的数值就是标号所在⾏代码的地址。在宏汇编ASM51中标号的长度不受限制,但标号中不能包含‘:'或其它的⼀些特殊符号,也不能⽤汉字,可以⽤数字作标号,但必须⽤字母开头。当标号作参数⽤(如标号作转移地址),在命令后⾯出现时,必须舍去‘:'(如上⾯程序中的 AJMP START中的START是不能再有:)。每⾏只能有⼀个标号,⼀个标号只能⽤在⼀处,如果有两⾏⽤了同⼀个标号,则汇编时就会出错。由于标号的长度没有限制,可以⽤有意义的英⽂或汉语拼⾳来说明⾏,使源程序读起来更⽅便。在源程序中的字母不区分⼤⼩写,也就是说 start 和 START 是⼀样的,请不要⽤⼤⼩写⽅式去区分不同的标号。
好啦!我们知道了汇编语⾔程序的规则,现在就动⼿编辑源程序吧。马上启动Keil单⽚机集成开发环境,建⽴新⼯程liu01.UV2,将上⾯的源程序liu01.asm导⼊到⼯程中,设置好Keil⼯程的编译参数,编译得到HEX格式的⽬标⽂件liu01.hex, 将⽬标⽂件liu01.hex烧写到
AT89S51单⽚机中,接下来就是将烧写好的AT89S51从编程器上取下,放到“YL-51单⽚机开发板 ”上通电,我们就看到了LED1~LED8的"流⽔"效果了。
到此,我们做的流⽔灯已成功,⼯作原理也清楚啦,若你完全掌握了上⾯程序,那么你就可以将“流⽔灯”的流向改变⼀下,可以将从"左向右流"改为从"右向左流",也可以改为"两边向内流"、"内部向外流"......,我想你⼀定能⽤前⾯学到的⽅法实现这些功能。可能有些⾼⼿说,前⾯的编程⽅法是最最笨的!不错!但初学单⽚机初期可以不必讲究语⾔的简练,只要能实现预先要求就好,最主要的是学好基本指令(111条)的⽤法,清楚各个指令的功能,这是初学者要知道的。那么还有更好的编程思路吗?当然有!请跟随站长继续学习下⾯的内容。
在前⾯学习的程序中我们让LED流⽔是去逐个控制P1端⼝的每个位来实现的,因此程序显得有点复杂,下⾯我们就采⽤新的思路来编程。新的编程思路如下:我们在程序⼀开始就给P1⼝送⼀个数,这个数本⾝就让P1.0先低,其他位为⾼,然后让这个数据向⾼位移动不就实
现“流⽔”效果啦?的确如此!8051指令中没有让P1数据移动的指令,但有对累加器ACC中数据左移或右移的指令,ACC在指令中常写为A,累加器A数据左移指令为"RL A",累加器数据右移指令为"RR A",累加器在数据传输和数据处理过程中作⽤⼗分重要,累加器ACC为8位。他可与⽚内所有单字节寄存器交换数据,实际上P1和其他端⼝在单⽚机中也是⼀个寄存器。这样我们可以将需移动的数据先放到ACC中,让其移动,然后将ACC移动后的数据再转送到P1⼝,这样同样可以实现“流⽔”效果。下⾯程序就是采⽤新的编程思路源程序liu02.asm。
实现8个LED流⽔灯汇编语⾔程序 liu02.asm
;----- 主程序开始 -----
START: MOV ACC,#0FEH ;ACC中先装⼊LED1亮的数据(⼆进制的11111110)
MOV P1,ACC ;将ACC的数据送P1⼝
MOV R0,#7 ;将数据再移动7次就完成⼀个8位流⽔过程
LOOP: RL A ;将ACC中的数据左移⼀位
MOV P1,A ;把ACC移动过的数据送p1⼝显⽰
ACALL DELAY ;调⽤延时⼦程序
DJNZ R0,LOOP ;没有移动够7次继续移动
AJMP START ;移动完7次后跳到开始重来,以达到循环流动效果
;----- 延时⼦程序 -----
DELAY: MOV R0,#255 ;延时⼀段时间
D1: MOV R1,#255
DJNZ R1,$
DJNZ R0,D1
RET ;⼦程序返回
END ;程序结束
接下来,我们将上述程序编译,并烧写到实验芯⽚中,放到实验板上可以看到程序的"流⽔"效果是⼀样的,但源程序看起来更加简洁,直观。其实8051单⽚机有111条指令,有的指令常⽤,有的指令不常⽤,只要遵守语法规则,你可以⽤这些指令“组合”成你想象到的任何程序。当然,有时⼀条指令可以替代很多条指令,这样会使程序简洁,程序代码减少,在编写较⼤程序时可以让程序存储器放得下你需要的代码,这也是单⽚机⾼⼿所追求的“程序简洁⾼效”。当然,初学者不必刻意去追求程序的简洁⾼效,主要是要全⾯地掌握各种指令的应⽤,只要你对基本指令都熟悉了,那么你也就可以编出简洁⾼效的程序了,不过这编程“内功”是需要你勤学苦练,⽇积⽉累的练习、实验才能达到的哦!马上拿起你的实验板,现在就开始动⼿吧:)
上⾯我们学习的两个程序都是⽐较简单的流⽔灯程序,"流⽔"花样只能实现单⼀的"从左到右"流⽅式。
下⾯介绍⼀个实⽤的流⽔灯程序,程序能够实现任意⽅式流⽔,⽽且流⽔花样⽆限,只要更改流⽔花样数据表的流⽔数据就可以随意添加或改变流⽔花样,真正实现随⼼所欲的流⽔。只要将下⾯的程序稍稍修改⼀下,通过S51增强型单⽚机实验板的扩展接⼝连接到霓虹灯⾼压驱动接⼝板就可以驱动真正的霓虹灯了。
实⽤的查表⽅式多功能流⽔灯程序 liu03.asm
;----- 主程序开始 -----
ORG 0000H ;上电复位,程序从0000H开始执⾏
START: MOV SP,#60H ;堆栈初始化为60H
MOV DPTR,#LIU_TAB ;流⽔花样表⾸地址送DPTR
LOOP: CLR A
MOVC A,@A+DPTR
CJNE A,#0FFH,SHOW ;检查流⽔结束标志
AJMP START ;所有花样流完,则从头开始重复流
SHOW: MOV P1,A ;将数据送到P1⼝
ACALL DELAY
INC DPTR
AJMP LOOP
;----- 延时⼦程序 -----
DELAY: MOV R0,#255 ;延时⼀段时间
D1: MOV R1,#255
DJNZ R1,$
DJNZ R0,D1
RET ;⼦程序返回
;
----- 下⾯是流⽔花样数据表 -----
LIU_TAB:
DB 01111111B ;⼆进制表⽰的流⽔花样数据
DB 10111111B
DB 11011111B
DB 11101111B
DB 11110111B
DB 11111011B
DB 11111101B
DB 11111110B
DB 11111110B
DB 11111101B
DB 11111011B
DB 11110111B
DB 11101111B
DB 11011111B
DB 10111111B
DB 01111111B
DB 7FH,0BFH,0DFH,0EFH,0F7H,0FBH,0FDH,0FEH ;⼗六进制表⽰DB 0FEH,0FDH,0FBH,0F7H,0EFH,0DFH,0BFH,7FH
DB 7EH,0BDH,0DBH,0E7H,0E7H,0DBH,0BDH,7EH
DB 7FH,3FH,1FH,0FH,07H,03H,01H,00H
DB 0FFH ;流⽔花样结束标志0FFH
END ;程序结束
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论