c51单片机流水灯程序左右循环移动流水灯,求解答每句话含义,谢谢

;累加器A循环左移一位 djnz r0,loop mov p0,#0ffh mov a,#7fh mov r0,#8loop1:
;将A送到P1口,发光低电平点亮; mov p2,a lcall delay
;调用延时子程序 rr a
;累加器A循环左移一位 djnz r0,loop1 mov p2,#0ffh ajmp main ;重新送P1显示delay: mov r3,#10
;最外层循环二十次d1: mov r4,#80
;次外层循环八十次d2: mov r5,#250
;最内层循环250次 djnz r5,$
;总共延时2us*250*80*20=0.8S djnz r4,d2 djnz r3,d1 ret end
本网站试开通微、小企业商家广告业务;维修点推荐项目。收费实惠有效果!欢迎在QQ或邮箱联系!
试试再找找您想看的资料
资料搜索:
查看相关资料 & & &
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款
copyright & &广电电器(中国梧州) -all right reserved& 若您有什么意见或建议请mail: & &
地址: 电话:(86)774-2826670&手把手教你单片机流水灯实验(详解)
您现在位于:
云龙电子 →
单片机学习
手把手教你单片机流水灯实验(详解)
单片机轻松入门教学
---------------------------------------------------------------------------------------------------------------
  每当夜幕降临,我们可以看到大街各式各样广告牌上漂亮的霓虹灯,看起来令人赏心悦目,为夜幕中的城市增添了不少亮丽色彩。其实这些霓虹灯的工作原理和单片机流水灯是一样的,只不过霓虹灯的花样更多,看起来更漂亮一些。这一课我们就结合YL-51单片机开发板来手把手教你详细学习单片机的流水灯实验。
  首先介绍实验的硬件设备:YL-51单片机开发板
  YL-51单片机开发板上有8个高亮度发光二极管(见图1所示),可以用来做单片机流水灯、跑马灯。。。等实验,电路原理图见下图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亮的数据(二进制的)
    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            ;子程序返回
    ;----- 下面是流水花样数据表 -----
    DB B       ;二进制表示的流水花样数据
    DB B
    DB B
    DB B
    DB B
    DB B
    DB B
    DB B
    DB B
    DB B
    DB B
    DB B
    DB B
    DB B
    DB B
    DB B
    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           ;程序结束
本站部分软件资料来源于网络,如有涉及版权问题,请及时联系站长删除问题已关闭
代为完成的个人任务
提问需要满足:其他人可能遇到相似问题,或问题的解决方法对其他人有所助益。如果通过其他方式解决遇到困难,欢迎提问并说明你的求知过程。
谢邀。这个问题我不打算回答了。一看就是作业题。这种问题自己搜、自己想不是很好吗?方法不会还是技术不懂?直接跟别人要答案的话,还不如花钱买个学位得了,更省时间。我不希望知乎成为百度知道。我更愿意看到认真思考过,或值得别人思考的问题。哪怕这个问题的答案比我码半天字更容易,我也不想直接说出来是什么,怎么样。我喜欢别人问为什么,或者是比较高级一点的是什么。希望有所帮助。
谢邀。这类伸手的问题一般大家都不愿意回答。不过我还是比较好奇什么是花样流水灯,跟花式撸管有关系吗?&br&&br&还是跟你简单说思路吧:&br&想要实现你的所谓花式LU管,阿不....花式流水灯,首先你要实现一个土鳖的流水灯,就是一LED灯一个挨着一个点亮,循环往复&br&要实现一个土鳖流水灯,首先你要学会点亮一个LED,这是最基本的I/O操作了&br&要点亮LED,首先你要有LED和单片机连接,也就是你的硬件电路&br&&br&好了,所以你要先确定你的硬件电路,根据电路连接操作对应的I/O口点亮一个LED,然后通过循环,移位运算,定时器或者延时函数的配合来实现一个土鳖流水灯,接着你就可以通过不同的逻辑判断来实现你的花式那啥了。&br&&br&看看书,看看别人的例子。真的很简单,不要不思考就直接问。&br&流水灯就是单片机的Hello World,网上的例子数不胜数,搜一下就出来了。你见过有人在知乎上问“如何用C#写hello world”吗?
谢邀。这类伸手的问题一般大家都不愿意回答。不过我还是比较好奇什么是花样流水灯,跟花式撸管有关系吗? 还是跟你简单说思路吧: 想要实现你的所谓花式LU管,阿不....花式流水灯,首先你要实现一个土鳖的流水灯,就是一LED灯一个挨着一个点亮,循环往复 要…
已有帐号?
无法登录?
社交帐号登录
搞过几天嵌入式,研究过几个月机器人,做了几年数控问一个51单片机LED流水灯的延时问题
[问题点数:40分]
问一个51单片机LED流水灯的延时问题
[问题点数:40分]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。难题。流水灯左右循环效果 - 单片机论坛 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
难题。流水灯左右循环效果
22:05:00  
#include &reg52.h&
void main()
& & unsigned int i = 0;& &&&//定义循环变量i,用于软件延时
& & unsigned char cnt = 0;&&//定义计数变量cnt,用于移位控制
& & while (1)&&//主循环,程序无限循环执行该循环体语句
& && &&&P0 = (0x01 && cnt);& && &//P0等于1左移cnt位,控制8个LED
& && &&&for (i=0; i&20000; i++);&&//软件延时
& && &&&cnt++;& && && && && && &&&//移位计数变量自加1
& && &&&if (cnt &= 8)& && && && & //移位计数超过7后,再重新从0开始
& && && && &cnt = 0;
& && && &P0 = (0x80 && cnt);& && &//P0等于0x80右移cnt位,控制8个LED
& && &&&for (i=0; i&20000; i++);&&//软件延时
& && &&&cnt++;& && && && && && &&&//移位计数变量自加1
& && &&&if (cnt &= 8)& && && && & //移位计数超过7后,再重新从0开始
& && && && &cnt = 0;
这段程序为什么没有流水灯左右循环效果
22:51:59  
for循环往复不对,右移符号不对
00:21:30  
醉了醉了。
00:48:35  
大哥,左移号是一个大于号吗?2个吧
19:25:03  
我给你附上一段循环左移的看看吧,你看看你的问题出哪里了
/*-----------------------------------------------
&&内容:循环左移,始终一个led点亮,并循环执行流水动作,左移符号 &&&&逻辑或符号 |
------------------------------------------------*/
#include&reg52.h& //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
void Delay(unsigned int t); //函数声明
/*------------------------------------------------
& && && && && && &&&主函数
------------------------------------------------*/
void main (void)
& && && && && && &
&&//定义一个无符号字符型局部变量 i 取值范围 0~255
Delay(50000);
P1=0& && && &&&//赋初始值
while (1)& && && &//主循环
for(i=0;i&8;i++)& &//加入 for循环,表明for循环大括号中的程序循环执行8次
& &Delay(50000);
& &P1&&=1;
& &P1=P1|0x01;& &&&//左移后,最右端自动赋值0,所以需要该语句赋值1
&&P1=0& && && &&&//重新赋初始值
&&//主循环中添加其他需要一直工作的程序
/*------------------------------------------------
延时函数,含有输入参数 unsigned int t,无返回值
unsigned int 是定义无符号整形变量,其值的范围是
------------------------------------------------*/
void Delay(unsigned int t)
while(--t);
19:25:27  
/*-----------------------------------------------
&&内容:循环左移,始终一个led点亮,并循环执行流水动作,左移符号 &&&&逻辑或符号 |
------------------------------------------------*/
#include&reg52.h& //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
void Delay(unsigned int t); //函数声明
/*------------------------------------------------
& && && && && && &&&主函数
------------------------------------------------*/
void main (void)
& && && && && && &
&&//定义一个无符号字符型局部变量 i 取值范围 0~255
Delay(50000);
P1=0& && && &&&//赋初始值
while (1)& && && &//主循环
for(i=0;i&8;i++)& &//加入 for循环,表明for循环大括号中的程序循环执行8次
& &Delay(50000);
& &P1&&=1;
& &P1=P1|0x01;& &&&//左移后,最右端自动赋值0,所以需要该语句赋值1
&&P1=0& && && &&&//重新赋初始值
&&//主循环中添加其他需要一直工作的程序
/*------------------------------------------------
延时函数,含有输入参数 unsigned int t,无返回值
unsigned int 是定义无符号整形变量,其值的范围是
------------------------------------------------*/
void Delay(unsigned int t)
while(--t);
19:27:39  
建议你用_crol_循环左移_cror_循环右移,这个比较简单
19:28:23  
for(i=0;i&8;i++)& &//加入 for循环,表明for循环大括号中的程序循环执行8次
& &Delay(50000);
& &P1&&=1;
& &P1=P1|0x01;& &&&//左移后,最右端自动赋值0,所以需要该语句赋值1
助理工程师
17:47:37  
学习学习,大家都好积极啊
浏览过的版块
Powered by

我要回帖

更多关于 单片机流水灯 的文章

 

随机推荐