八个流水灯及程序
- 格式:docx
- 大小:78.18 KB
- 文档页数:2
一:实验目的熟悉如何使用stp-isp软件,用汇编语言实现8个LED1-LED8依次闪亮从而产生“流水”现象,了解单片机汇编语言设计使用和调试方法。
二:实验内容通过p2口将8个LED连接在一起,从而产生“流水现象”。
三:实验线路图四: 实验原理从原理图中可以看出,如果要让接在p2.0口的LED 1灯亮起来,那么只要把p2.0的电平变为低电平就可以;相反的,如果要接在p2.0口的LED 1熄灭,就要把p2.0口的电平变为高电平;同理,接在p2.1-p2.7口的其他7个LED的点亮和熄灭的方法同LED 1 。
因此要实现流水灯功能,我们只要将发光二极管LED 1 —LED 8 依次点亮/熄灭,8个LED灯就会一亮一暗的做规律活动,即“流水”现象。
此外我们还应该注意一点,由于人的视觉暂留,神经反应间隔以及单片机执行每条指令的时间很短,我们在控制二极管亮和暗的时候应该延时一段时间,否则由于时间太短,我们视觉神经反应不过来而看不到“流水”效果了。
六:实验程序ORG 00HLJMP STARTORG 30HSTART: MOV A, #7FHLOOP: RL AINC AMOV P2, ALCALL DELAYLJMP LOOPDELAY: MOV R5, #5DELAY01: MOV R6, #200 DELAY02: MOV R7, #250 DELAY03:DJNZ R7, DELAY03DJNZ R6, DELAY02DJNZ R5, DELAY01RETEND(反复调试程序使之正确)七:实验步骤1 .打开电脑,安装 stp-isp软件;2 .连接接usb转串口线和电源线;3 .在改程序中打开所需程序,然后下载程序进单片机,按照提示打开关闭电板上的开关控制,带程序开始运行之后观察是否与所涉及程序结果一致。
若一致(即观察到”流水“现象),则实验成功,分析实验结果写总结。
若不一致(即观察不到”流水“现象),则重新调试程序和接线,找到原因,重新实验,直至看到”流水“现象。
/***************项目名称:实现8个LED流水灯***************/ #include<reg52.h> //引用S52单片机头文件/***************定义8个LED引脚***************************/ sbit LED1=P1^0; //定义一个LED的引脚sbit LED2=P1^1; //定义另一个LED的引脚sbit LED3=P1^2;sbit LED4=P1^3;sbit LED5=P1^4;sbit LED6=P1^5;sbit LED7=P1^6;sbit LED8=P1^7;void Delay(void); //子函数的声明,后面要加分号。
void main() //主程序main函数{while(1) //在主程序中设置死循环"while(1)"{LED1=0; //P1.0口输出低电平,使LED1灯亮Delay(); //延时字函数的调用LED1=1; //P1.0口输出高电平,使LED1灯灭LED2=0; //P1.1口输出低电平,使LED2灯亮Delay(); //延时字函数的调用LED2=1; //P1.1口输出高电平,使LED2灯灭LED3=0; //P1.2口输出低电平,使LED3灯亮Delay(); //延时字函数的调用LED3=1; //P1.2口输出高电平,使LED3灯灭LED4=0; //P1.3口输出低电平,使LED4灯亮Delay(); //延时字函数的调用LED4=1; //P1.3口输出高电平,使LED4灯灭LED5=0; //P1.4口输出低电平,使LED5灯亮Delay(); //延时字函数的调用LED5=1; //P1.4口输出高电平,使LED5灯灭LED6=0; //P1.5口输出低电平,使LED6灯亮Delay(); //延时字函数的调用LED6=1; //P1.5口输出高电平,使LED6灯灭LED7=0; //P1.6口输出低电平,使LED7灯亮Delay(); //延时字函数的调用LED7=1; //P1.6口输出高电平,使LED7灯灭LED8=0; //P1.7口输出低电平,使LED8灯亮Delay(); //延时字函数的调用LED8=1; //P1.7口输出高电平,使LED8灯灭}}void Delay(void) //子函数的建立,延时一段时间的子函数{unsigned int i=50000; //声明一个int型的变量,即"int"的范围为0~65536 while(--i); //延时一段时间}。
八位双向流水灯”设计以下是对八位双向流水灯设计的详细介绍。
1.硬件设计:该设计需要使用以下硬件元件:-8个LED灯:用于点亮和显示流水灯效果。
-8个当前限流电阻:用于限制LED灯的电流,保护LED灯不受损坏。
-8个开关:用于手动切换流水灯的方向。
-一个控制器:用于控制LED灯的点亮和熄灭。
-一个脉冲发生器:用于为控制器提供驱动信号。
首先,将8个LED灯连接到控制器的8个输出引脚上,并通过对应的当前限流电阻进行连接。
然后,将8个开关连接到控制器上,用于手动控制流水灯的方向。
最后,将脉冲发生器连接到控制器上,用于为控制器提供驱动信号。
2.软件设计:该设计需要使用软件来控制LED灯的点亮和熄灭。
软件设计可以使用C语言等编程语言实现。
首先,需要定义一个数组,用于存储LED灯的状态。
数组中的每个元素对应一个LED灯,其中0表示灯灭,1表示灯亮。
然后,通过控制器的输入和输出引脚,可以确定当前LED灯的状态和流水灯的方向。
接着,需要实现一个循环,用于不断更新LED灯的状态。
循环的过程中,根据当前LED灯的状态和流水灯的方向,通过控制器的输出引脚控制LED灯的点亮和熄灭。
在循环的过程中,需要监测开关的状态,以便手动切换流水灯的方向。
当检测到开关状态改变时,需要更新流水灯的方向。
3.工作原理:首先,当控制器接收到脉冲发生器的驱动信号时,它将根据当前流水灯的方向和控制器的输入引脚的状态来更新LED灯的状态。
如果流水灯的方向是从左到右,则控制器会根据当前LED灯的状态和开关的状态,点亮或熄灭相应的LED灯。
具体的控制规则可以根据设计需求进行定义,例如按照顺序点亮灯1、2、3、4、5、6、7、8如果流水灯的方向是从右到左,则控制器会根据当前LED灯的状态和开关的状态,点亮或熄灭相应的LED灯。
具体的控制规则可以根据设计需求进行定义,例如按照顺序点亮灯8、7、6、5、4、3、2、1当开关的状态改变时,控制器会更新流水灯的方向,并根据新的方向重新设置LED灯的状态。
流水灯C语言程序流水灯是一种常见的电子显示效果,通常用于展示灯光的流动效果。
在C语言中,我们可以通过控制单片机的IO口来实现流水灯的效果。
以下是一个标准格式的C语言程序,用于实现流水灯效果。
```c#include <stdio.h>#include <stdlib.h>#include <unistd.h>#define LED_COUNT 8 // 流水灯的数量#define DELAY_MS 500 // 每一个灯亮起的延迟时间(毫秒)int main() {int leds[LED_COUNT] = {0}; // 存储每一个灯的状态,0表示灭,1表示亮 int i, j;while (1) {// 灯往右挪移for (i = LED_COUNT - 1; i > 0; i--) {leds[i] = leds[i - 1];}leds[0] = 1;// 输出灯的状态for (i = 0; i < LED_COUNT; i++) {if (leds[i]) {printf("*"); // 亮的灯用*表示} else {printf(" "); // 灭的灯用空格表示}}printf("\n");// 延迟一段时间usleep(DELAY_MS * 1000);// 清空屏幕system("clear");}return 0;}```上述程序使用了C语言的基本语法和系统函数,实现了一个简单的流水灯效果。
程序中的`LED_COUNT`表示流水灯的数量,可以根据实际需求进行调整。
`DELAY_MS`表示每一个灯亮起的延迟时间,单位为毫秒。
在程序的主循环中,通过不断改变灯的状态和输出屏幕,实现了流水灯的效果。
首先,灯往右挪移,即将前一个灯的状态赋值给后一个灯,最后一个灯的状态设置为亮。
51八只LED灯做流水灯实验第一节:单片机在上电初始后,其各端口输出为高电平。
如果我们现在想让接在P1.0口的LED1亮,那么我们只要把P1.0口的电平变为低电平就可以了。
想让LED1灭,LED0亮,只需将P1.0升高,P1.1变低,LED 1就熄灭LED2随后既点亮!依始类推如下所示8只LED变会一亮一暗的做流水灯了。
本实验在“SP-5 1实验板”学习套件上的相关图纸: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.1你变低,它就变低了。
因为单片机听不懂我们的汉语的,只能接受二进制的“1、0......”代码。
我们又怎样来用二进制语议论使单片机按我们的意思去工作呢?为了让单片机工作,只能将程序写为二进制代码交给其执行;早期单片机开发人员就是使用人工编写的二进制代码交给单片机去工作的。
今天,我们不必用烦人的二进制去编写程序,完全可以将我们容易理解的“程序语言”通过“翻译”软件“翻译”成单片机所需的二进制代码,然后交给单片机去执行。
这里的“程序语言”目前主要有汇编和C两种;在这里我们所说的“翻译”软件,同行们都叫它为“编译器”,将“程序语言”通过编译器产生单片机的二进制代码的过程叫编译。
前面说到,要想使LED1变亮,只需将对应的单片机引脚电平变为低电平就可以了。
现在让我们将上面提到的8只LED流水灯实验写为汇编语言程序。
“汉语”语言汇编语言开始:star:P1.0低clr p1.0P1.0高setb p1.0P1.1低clr p1.1P1.1高setb p1.1P1.2低clr p1.2P1.2高setb p1.2这里用到了四条汇编指令:clr、 setb、 ljmp 、end;clr:是将其后面指定的位清为0;setb:是将其后面指定的位置成1;ljmp:是无条件跳转指令,意思是:跳转到指定的标号处继续运行。
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,#255DJNZ R1,$DJNZ R0,D1RET ;子程序返回END ;程序结束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,#255DJNZ R1,$DJNZ R0,D1RET ;子程序返回END ;程序结束ORG 0000H ; 上电复位,程序从 0000H 开始执行END ;程序结束START: MOVSP,#60HMOVDPTR,#LIU_TAB LOOP:CLR AMOVC A,@A+DPTRCJNEA,#0FFH,SHOWAJMPSTARTSHOW:MOV P1,A ACALL DELAYINC DPTRAJMP LOOP延时子程序; 堆栈初始化为 60H;流水花样表首地址送 DPTR;检查流水结束标志;所有花样流完 ,则从头开始重复流;将数据送到 P1 口DELAY: MOV R0,#255;延时一段时间D1:MOV R1,#255DJNZ R1,$DJNZR0,D1RET;子程序返回; ---- 下面是流水花样数据表 -----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 01111111BDB 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延时子程序,12M 晶振延时约250 毫秒DELAY:MOV R4,#2L3: MOV R2 ,#250L1: MOV R3 ,#250L2: DJNZ R3 ,L2DJNZ R2 ,L1DJNZ R4 ,L3RETorg 00h ;程序上电从00h 开始ajmp main ;跳转到主程序org 0030h ;主程序起始地址main:mov a,#0feh ;给A 赋值成11111110loop:mov p1,a ;将A 送到P1 口,发光二极管低电平点亮lcall delay ; 调用延时子程序rl a ; 累加器A 循环左移一位ajmp loop ; 重新送P1 显示delay:mov r3,#20 ;最外层循环二十次d1:mov r4,#80 ;次外层循环八十次d2:mov r5,#250 ;最内层循环250 次djnz r5,$ ;总共延时2us*250*80*20=0.8Sdjnz r4,d2djnz r3,d1 ret end如何精确计算延时子程序的执行时间?汇编语言的一大优势就是能够精确控制程序的执行时间,这在编写一些对时序要求严格的外围器件驱动时由为重要!;延时子程序,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丄3 ------------- 执行2个机器周期,反复执行2次(1+1+502+126250+2)*2=253512微秒)RETdelay 加上第一条总共延时1+253512=253513微秒。
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,#255DJNZ R1,$DJNZ R0,D1RET;子程序返回END;程序结束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,#255DJNZ R1,$DJNZ R0,D1RET;子程序返回END;程序结束ORG0000H;上电复位,程序从0000H开始执行START:MOV SP,#60H;堆栈初始化为60HMOV DPTR,#LIU_TAB;流水花样表首地址送DPTR LOOP: CLR AMOVC A,@A+DPTRCJNE A,#0FFH,SHOW;检查流水结束标志AJMP START;所有花样流完,则从头开始重复流SHOW: MOV P1,A;将数据送到P1口ACALL DELAYINC DPTRAJMP LOOP;----- 延时子程序-----DELAY:MOV R0,#255;延时一段时间D1:MOV R1,#255DJNZ R1,$DJNZ R0,D1RET;子程序返回;----- 下面是流水花样数据表-----LIU_TAB:DB 01111111B ;二进制表示的流水花样数据DB 10111111BDB 11011111BDB 11101111BDB 11110111BDB 11111011BDB 11111101BDB 11111110BDB 11111110BDB 11111101BDB 11111011BDB 11110111BDB 11101111BDB 11011111BDB 10111111BDB 01111111BDB 7FH,0BFH,0DFH,0EFH,0F7H,0FBH,0FDH,0FEH ;十六进制表示DB 0FEH,0FDH,0FBH,0F7H,0EFH,0DFH,0BFH,7FHDB 7EH,0BDH,0DBH,0E7H,0E7H,0DBH,0BDH,7EHDB 7FH,3FH,1FH,0FH,07H,03H,01H,00HDB 0FFH ;流水花样结束标志0FFHEND;程序结束延时子程序,12M晶振延时约250毫秒DELAY:MOV R4,#2L3: MOV R2 ,#250L1: MOV R3 ,#250L2: DJNZ R3 ,L2DJNZ R2 ,L1DJNZ R4 ,L3RETorg 00h ;程序上电从00h开始ajmp main ;跳转到主程序org 0030h ;主程序起始地址main:mov a,#0feh ;给A赋值成11111110loop:mov p1,a ;将A送到P1口,发光二极管低电平点亮 lcall delay ;调用延时子程序rl a ;累加器A循环左移一位ajmp loop ;重新送P1显示delay:mov r3,#20 ;最外层循环二十次d1:mov r4,#80 ;次外层循环八十次d2:mov r5,#250 ;最内层循环250次djnz r5,$ ;总共延时2us*250*80*20=0.8Sdjnz r4,d2djnz r3,d1retend如何精确计算延时子程序的执行时间?汇编语言的一大优势就是能够精确控制程序的执行时间,这在编写一些对时序要求严格的外围器件驱动时由为重要!;延时子程序,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微秒)RETdelay 加上第一条总共延时1+253512=253513微秒。