使用经典汇编程序100例语言编写一个单片机程序,有八个灯,依次点亮,全亮后全灭,循环三次

手把手教你单片机流水灯实验(详解)
您现在位于:
云龙电子 →
单片机学习
手把手教你单片机流水灯实验(详解)
单片机轻松入门教学
---------------------------------------------------------------------------------------------------------------
  每当夜幕降临,我们可以看到大街各式各样广告牌上漂亮的霓虹灯,看起来令人赏心悦目,为夜幕中的城市增添了不少亮丽色彩。其实这些霓虹灯的工作原理和单片机流水灯是一样的,只不过霓虹灯的花样更多,看起来更漂亮一些。这一课我们就结合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           ;程序结束
本站部分软件资料来源于网络,如有涉及版权问题,请及时联系站长删除汇编语言 单片机8个灯依次亮,全部亮完依次灭,我写了程序总是提示有错误,大神帮帮忙_百度知道
汇编语言 单片机8个灯依次亮,全部亮完依次灭,我写了程序总是提示有错误,大神帮帮忙
我有更好的答案
什么逻辑,刚开始就跳转到main那么SJMP和main之间语句能执行吗?主程序中也有这个问题,一开始就跳到LOP2,那下面几条语句又没用了,不是废代码吗?很久不用汇编,试着写一下,也可能存在错误,不过程序结构你可以参考ORG 0000HLJMP MAINORG 0020HMAIN:MOV R6,#07H
MOV R7,#FEH ;LOP1:MOV P1,R7
LCALL DELAY
DJNZ R6,LOP1
MOV R6,#07H
MOV R7,#7FH;LOP2:MOV P1,R7
LCALL DELAY
DJNZ R6,LOP2
LJMP MAINDELAY:MOV R3,#0FFHLOP3: MOV R4,#0FFHLOP4:NOP
DJNZ R4,LOP4
DJNZ R3,LOP3
采纳率:86%
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。单片机汇编程序:有八个小灯,要求依次点亮,时间间隔1s_百度知道
单片机汇编程序:有八个小灯,要求依次点亮,时间间隔1s
用80C51单片机的汇编程序做,谢谢了
我有更好的答案
/* 实验目的:初步了解单片机I/O口的工作原理,进一步掌握51单片机的汇编指令。 * 实验内容:用汇编指令对单片机I/O口进行编程,控制8个发光二极管的流水亮灭。 */
/* 程序详细功能介绍: *做单一灯的左移右移,八个发光二极管L0-L7分别接在单片机的P0.0-P0.7接口上, *输出“0”时,发光二极管亮,开始时P0.0→P0.1→P0.2→P0.3→┅→P0.7→P0.6→┅→P0.0亮,重复循环。
*/ORG 0000HLJMP STARTORG 0030HSTART:
MOV R2,#8 ;左移次数
MOV A,#0FEH ;A的初始值,即 P0.0的L0 点亮
SETB CLOOP: MOV P0,A
LCALL DELAY
RLC A左移流水灯(带进位的左移),即亮点向P0口的高位移动
DJNZ R2,LOOPMOV R2,#8 ;右移次数LOOP1: RRC A右移流水灯
LCALL DELAY
DJNZ R2,LOOP1
LJMP STARTDELAY: MOV R5,#10 ;延时子程序,改变R5,R6,R7 的值,可以改变延时的时间,从而改变流水灯移动速度D1: MOV R6,#20D2: MOV R7,#248DJNZ R7,$DJNZ R6,D2DJNZ R5,D1RETEND
采纳率:36%
这个是简单的:org 000main:mov p1,#blcall t1S ;灭1秒mov p1,#blcall t1Smov p1,#blcall t1Smov p1,#blcall t1Smov p1,#blcall t1Smov p1,#blcall t1Smov p1,#blcall t1Smov p1,#blcall t1Smov p1,#blcall t1Sljmp maint1s:mov r2,#10 ;1秒mov r1,#195loop1:djnz r0,$djnz r1,loop1djnz r2,loop1RETend
最好先明确一下: 8只都点亮后,就静止了吗?
为您推荐:
其他类似问题
您可能关注的内容
汇编程序的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。如何用单片机实现流水灯,从一依次亮到八,再从八依次亮回一,一直循环?_百度知道
如何用单片机实现流水灯,从一依次亮到八,再从八依次亮回一,一直循环?
我有更好的答案
//简单一点#include&reg51.h&#define uchar unsigned char#define uint unsigned intvoid delay(uint ms){ while(ms--) for(i=0;i&123;i++);}void main(){ P1=0x00; while(1) {
uchar temp=0x01;
for(j=0;j&8;j++)
temp=temp&&1;
delay(500);
temp=0x80;
for(j=0;j&8;j++)
temp=temp&&1;
delay(500);
采纳率:43%
有个想法, 放一个字节LED做标志位,可位寻址。 每一位代表一个灯。对字节LED附初值1,做一个200mS的时钟,每200ms对字节LED值做左移1位指令(汇编可循环)。主程序中位寻址判断字节LED的bit(0-7)点亮相应的灯。或者直接P0=LED纯想法、还没试过,感觉好玩,呵呵。 好像上述灯流的方式不对,不过可以改。。。
额,我是新学的,貌似,有点看不懂…
饿。。今天有热心网友给出程序了,看程序吧。自已再加些申明就可以了
为您推荐:
其他类似问题
流水灯的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。单片机流水灯程序汇编8个流水灯,先依次点亮,再依次熄灭,如_百度知道
单片机流水灯程序汇编8个流水灯,先依次点亮,再依次熄灭,如
单片机流水灯程序汇编8个流水灯,先依次点亮,再依次熄灭,如此循环
我有更好的答案
就用C语言编写不好吗?用变量数组保存亮灭次序,依次播放就好了。
采纳率:42%
来自团队:
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。

我要回帖

更多关于 单片机独立键盘程序汇编语言 的文章

 

随机推荐