51单片机闪烁灯

合集下载

51单片机控制LED灯程序设计

51单片机控制LED灯程序设计

51单片机控制LED灯程序设计首先,我们需要明确要使用到的硬件资源和引脚连接情况。

假设我们使用的是STC89C51单片机,LED灯的正极连接到单片机的P1口,负极通过电阻连接到地。

接下来,我们需要了解一些基本的汇编指令和编程规范。

在编写51单片机程序时,需要使用到一些特定的寄存器和指令。

首先是P1寄存器,它用来控制P1口的输出和输入状态。

然后是MOV指令,这是一个用来将数据从一个寄存器复制到另一个寄存器的指令。

最后是一个延时函数,可以利用循环来实现延时。

首先,我们需要初始化P1口为输出状态。

在51单片机中,IO口可以被配置为输入(1)或输出(0)。

我们可以使用MOV指令将0赋值给P1寄存器,将其配置为输出。

此外,我们还需要一个简单的延时函数,来控制LED灯的亮灭时间。

下面是一个基本的51单片机控制LED灯的程序:```assemblyORG0;程序的起始地址MOVP1,;初始化P1口为输出状态LOOP:;主循环MOVP1,;将P1的状态置为0,LED灯灭ACALLDELAY;调用延时函数,延时一段时间MOVP1,;将P1的状态置为1,LED灯亮ACALLDELAY;调用延时函数,延时一段时间JMPLOOP;无限循环DELAY:;延时函数MOVR3,;初始化循环计数器为250LOOP1:MOVR2,;初始化循环计数器为250LOOP2:MOVR1,;初始化循环计数器为250LOOP3:DJNZR1,LOOP3;内层循环DJNZR2,LOOP2;中层循环DJNZR3,LOOP1;外层循环RET;返回主程序```以上是一个简单的51单片机控制LED灯的汇编程序。

程序中通过不断切换P1口的状态来实现LED灯的亮灭。

同时,通过调用延时函数来实现亮灭的时间间隔。

在主循环中,LED灯会亮和灭各一段时间,然后无限循环。

为了将以上汇编程序烧录到单片机中,需要将其汇编为二进制文件。

通常可以使用Keil C等开发工具进行汇编和烧录操作。

单片机实验报告—— LED灯闪烁

单片机实验报告—— LED灯闪烁

XXXX学院实验报告Experimentation Report of Taiyuan Normal University系部计算机年级大三课程单片机原理与接口技术姓名同组者日期2019.10.31 学号项目 LED闪烁一、实验目的1、了解单片机顺序执行的特点;2、掌握51单片机开发板所需软件的安装过程;3、以LED灯闪烁为例子,掌握C语言的编写和keilc51的使用;二、实验仪器硬件资源:单片机开发板笔记本电脑;软件资源:软件 Keil uVision5、USB驱动程序;三、实验原理1、流程图2、连接图四、实验结果点击运行按钮,LED灯先全部熄灭,隔一段时间,LED灯亮,再隔一段时间,LED灯全部熄灭,LED灯亮灭循环,直到点击复位按钮才结束。

五、实验代码及分析#include <reg51.h> //此文件中定义了51的一些特殊功能寄存器//--定义全局函数--//void Delay10ms(unsigned int c); //延时10ms* 函数名 : main* 函数功能 : 主函数* 输入 : 无* 输出 : 无void main(){while(1){//--数字前面加0x表示该数是十六进制的数,0x00就是十六进制的00--////--P0口一共有8个IO口,即从P0.0到P0.7,而0x00二进制就是0000 0000--////--效果就是P0.0到P2.7都是0,即低电平。

而如果你想给P0.1口赋高电平时--////--二进制就是0000 0001,就是十六进制0x01.--//P0 = 0x00; //置P0口为低电平,LED灯先熄灭Delay10ms(50); //调用延时程序,修改括号里面的值可以调整延时时间P0 = 0xff; //置P0口为高电平,LED灯亮Delay10ms(50); // 调用延时程序}}* 函数名 : Delay10ms* 函数功能 : 延时函数,延时10ms* 输入 : 无* 输出 : 无void Delay10ms(unsigned int c) //误差 0us{unsigned char a, b//--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//for (;c>0;c--){for (b=38;b>0;b--){for (a=130;a>0;a--);}}}六、心得体会通过此次试验我了解单片机顺序执行的特点,掌握51单片机开发板所需软件的安装过程,通过LED灯闪烁这个例程,我初步了解了Keilc51使用。

51单片机彩灯控制器的设计

51单片机彩灯控制器的设计

51单片机彩灯控制器的设计一、设计目的单片机彩灯控制器是一种能够通过控制程序实现RGBLED灯光颜色和亮度变化的设备。

其设计目的是实现LED的多彩灯光效果,丰富室内环境,提高生活品质。

二、硬件设计1.单片机选择在设计彩灯控制器时,我们选择了常用的8051单片机作为控制芯片。

8051单片机拥有丰富的外设资源,易于编程控制,并且具有较高的稳定性和可靠性。

2.RGBLEDRGBLED是一种由红、绿和蓝三个LED灯组成的组合灯,可以通过控制不同颜色的LED来实现丰富多彩的灯光效果。

在设计中,我们选用了高亮度的RGBLED,以确保灯光效果的良好。

3.驱动电路为了驱动RGBLED,我们设计了一套驱动电路,其中包括三个恒流驱动电路和三个PWM调光电路。

恒流驱动电路可以确保LED的电流稳定,而PWM调光电路可以实现LED的亮度调节。

4.控制电路控制电路主要由单片机、按键、显示屏等组成。

通过单片机控制按键输入,并根据用户需求调整LED的颜色和亮度。

同时,显示屏可以实时显示LED的参数信息,方便用户操作。

5.电源彩灯控制器的电源一般采用直流5V供电,可以通过USB接口或者外部电源适配器来供电,以满足不同环境下的使用需求。

三、软件设计1.系统架构我们将彩灯控制器的软件设计分为三个模块:按键输入模块、LED控制模块和显示模块。

按键输入模块负责接收用户的按键输入,LED控制模块根据用户输入控制LED的颜色和亮度,显示模块实时显示LED的参数信息。

2.按键输入模块按键输入模块主要负责检测用户按键的状态,并根据按键的状态进行相应的处理。

例如,当用户按下“颜色+/颜色-”按键时,按键输入模块会向LED控制模块发送指令,控制LED颜色的变化。

3.LED控制模块LED控制模块负责控制RGBLED的颜色和亮度。

当接收到按键输入模块发送的指令时,LED控制模块会根据指令调节LED的PWM值,实现LED 颜色的变化和亮度的调节。

4.显示模块显示模块通过显示屏实时显示LED的参数信息,包括LED的颜色、亮度等参数。

单片机应用技术项目2 闪烁灯

单片机应用技术项目2 闪烁灯
项目2 闪烁灯
知识目标:
1.掌握51单片机并行输入/输出(I/O)端口的结构和功能;
2.掌握P0、P1、P2、P3口的操作方法; 3.理解单片机的时钟和时序; 4.掌握C语言源程序结构; 5.掌握C语言基本语句; 6.重点掌握循环语句while、do…while、for的语法特点; 7.掌握延时程序设计和调试方法。
1. 表达式语句就是一个表达式加上一个分号。
其一般形式如下:
表达式; 执行表达式语句就是计算表达式的值 如:a++; x=1; 2. 空语句 用一个分号表示,其一般形式为:

程序执行空语句时需要占用一条指令的执行时间,但是什么也不做。 在C51程序中常常把空语句作为循环体,用于消耗CPU
时间等待事件发生的场合。
当f =6MHz时,时钟周期=1/ f =1/6µs,机器周期
=(1/6)×12µs=2µs 当f=12MHz时,时钟周期=1/f=1/12µs,机器周期 (1/12)×12µs=1µs
C基本语句
C语言的语句可分为以下五种:


表达式语句
空语句 复合语句


选择语句Biblioteka 循环语句表达式语句和空语句
复合语句(程序块) 示例
/*P1口8个LED灯依次点亮*/ main( ) {
图2- 4时钟周期、机器周期、指令周期之间的关系图
时钟周期、机器周期、指令周期的计算
【例2-1】MCS-51的时钟周期、机器周期、指令周期是如何分配的
?当晶振频率分别为6MHz和12MHz时,一个机器周期为多少µs?
解:MCS-51单片机每个状态周期包含2个时钟周期,1个机器周期有 6个状态周期,每条指令的执行时间(即指令周期)为1~4个机器周期。

51单片机闪灯

51单片机闪灯

51单⽚机闪灯上⼀篇写了点亮⼀个灯,这⼀篇写⼀下闪⼀个灯⾸先,流⽔灯实现起来就是⼀个⼀个点灯,中间加⼊⼀个延时就⾏了我们先实现闪⼀个灯,从上⼀个代码添加⼀些代码即可完成最重要的就是这个延时函数的实现,我们是通过不精准延时,单⽚机啥也不⼲在计数实现这⾥同时可以再讲讲while的⽤法unsigned int count = 0;while(count <= 50000){count = count + 1;}这样就是通过单⽚机不停计数来实现延时(具体延时多久,不⽤太在意)加⼊到代码实现闪灯#include "reg52.h"sbit D1 = P2^0;unsigned int count = 0;void main(void){while(1){D1 = 0;//灯亮while(count <= 50000){count = count + 1;}D1 = 1;//灯灭while(count <= 50000){count = count + 1;}}}这样就能实现闪灯了吗?想想应该可以,下载进去看下效果这⾥说道下载就要提⼀下,⽣成下载hex⽂件点击魔法棒点击选项卡output,勾选上,点击确定然后最重要的是要在编译⼀次,下⾯输出这个创建了hex⽂件到⼯程⽬录的\Objects\led.hex这个⽂件了,下载就不说了下载进去发现,咦,怎么不⾏,仔细看⼀下就能分析出来是变量没有清零了 = =!改⼀改#include "reg52.h"sbit D1 = P2^0;unsigned int count = 0;//unsigned int 范围0到65535void main(void){while(1){D1 = 0;//灯亮count = 0;while(count <= 50000){count = count + 1;}D1 = 1;//灯灭count = 0;while(count <= 50000){count = count + 1;}}}下载进去发现可以了,这⾥我们举⼀反三,如果要实现灭灯是亮灯时间的⼀半怎么写?只要稍微改改⼀个数就⾏了,主要是根据需求来,这个清零是根据需求决定的,并不⼀定就要清零(应该明⽩我的意思吧)#include "reg52.h"sbit D1 = P2^0;unsigned int count = 0;//unsigned int 范围为0到65535void main(void){while(1){D1 = 0;//灯亮count = 0;while(count <= 50000){count = count + 1;}D1 = 1;//灯灭count = 25000;while(count <= 50000)//这⾥因为初始值是从25000开始的所以时间是灯亮的⼀半时间{count = count + 1;}}}这⾥发现这个地⽅有重复的语句,重复的语句可以⽤函数写下来,直接调⽤,会更加简单上⼀章讲了函数是酱紫的,我们就来确定这些东西返回值函数名(参数){ 函数体}⾸先我们来确定最难的函数名,就叫delay吧,函数名和变量名尽量取得有意义⼀点,⼀看就明⽩是⼲嘛的返回值和参数都先为空就void咯然后把重复的东西复制到函数体⾥⾯void delay(void){count = 0;while(count <= 50000){count = count + 1;}}总体就是#include "reg52.h"sbit D1 = P2^0;unsigned int count = 0;void delay(void){count = 0;while(count <= 50000){count = count + 1;}}void main(void){while(1){D1 = 0;//灯亮delay();D1 = 1;//灯灭delay();}}这样就实现了延时,但是如果我要实现我后⾯那个功能呢(灭灯是亮灯时间的⼀半)这⾥有很多种⽅法,我就随便举例两种⼀种是修改delay函数的赋值语句,在主函数⾥⾯赋值⼀种是函数带参数逇形式,这种是最为简便的⾃⼰⽐较⼀下第⼀种:#include "reg52.h"sbit D1 = P2^0;unsigned int count = 0;void delay(void){while(count <= 50000){count = count + 1;}}void main(void){while(1){D1 = 0;//灯亮count = 0;delay();D1 = 1;//灯灭count = 25000;delay();}}第⼆种:#include "reg52.h"sbit D1 = P2^0;void delay(unsigned int count){unsigned int i = 0;while(i <= count){i = i + 1;}}void main(void){while(1){D1 = 0;//灯亮delay(50000);D1 = 1;//灯灭delay(25000);}}⼀⽐较就知道第⼆种代码更加简洁,⽽且想要计数多少都⾏这⾥牵扯到变量的作⽤域,⼀个是全局函数⼀个是局部函数,也讲⼀讲吧【喷⾎】局部变量定义在函数内部的变量称为局部变量(Local Variable),它的作⽤域仅限于函数内部,离开该函数后就是⽆效的全局变量在所有函数外部定义的变量称为全局变量(Global Variable),它的作⽤域默认是整个程序,也就是所有的源⽂件,包括 .c 和 .h ⽂件。

51单片机闪烁灯制作

51单片机闪烁灯制作

51单片机闪烁灯制作简介:51单片机闪烁灯制作:在单片机P1.0端口上接一个发光二极管L1,使L1在不停地一亮一灭形成闪烁灯状态,一亮一灭的时间间隔为0.2秒。

1.电路原理图图4.1.12.系统板上硬件连线把“单片机系统”区域中的P1.0端口用导线连接到“八路发光二极管指示模块”区域中的L1端口上。

3.程序设计内容(1). 延时程序的设计方法作为单片机的指令的执行的时间是很短,数量大微秒级,因此,我们要求的闪烁时间间隔为0.2秒,相对于微秒来说,相差太大,所以我们在执行某一指令时,插入延时程序,来达到我们的要求,但这样的延时程序是如何设计呢?下面具体介绍其原理:如图4.1.1所示的石英晶体为12MHz,因此,1个机器周期为1微MOV R6,#20 2个 2D1: MOV R7,#248 2个22+2×248=49820×DJNZ R7,$ 2个2×248 (498DJNZ R6,D1 2个2×20=4010002因此,上面的延时程序时间为10.002ms。

由以上可知,当R6=10、R7=248时,延时5ms,R6=20、R7=248时,延时10ms,以此为基本的计时单位。

如本实验要求0.2秒=200ms,10ms×R5=200ms,则R5=20,延时子程序如下:DELAY: MOV R5,#20D1: MOV R6,#20D2: MOV R7,#248DJNZ R7,$DJNZ R6,D2DJNZ R5,D1RET(2). 输出控制如图1所示,当P1.0端口输出高电平,即P1.0=1时,根据发光二极管的单向导电性可知,这时发光二极管L1熄灭;当P1.0端口输出低电平,即P1.0=0时,发光二极管L1亮;我们可以使用SETBP1.0指令使P1.0端口输出高电平,使用CLRP1.0指令使P1.0端口输出低电平。

4. 程序框图5. 汇编源程序ORG 0START: CLR P1.0LCALL DELAYSETB P1.0LCALL DELAYLJMP STARTDELAY: MOV R5,#20 ;延时子程序,延时0.2秒 D1: MOV R6,#20D2: MOV R7,#248DJNZ R7,$DJNZ R6,D2DJNZ R5,D1RETEND6. C语言源程序#includesbit L1=P1^0;void delay02s(void) //延时0.2秒子程序{unsigned char i,j,k;for(i=20;i0;i)for(j=20;j0;j)for(k=248;k0;k);}void main(void){while(1){L1=0;delay02s();L1=1;delay02s();}}完毕!您现在会不会制作自己的闪烁灯了呢?。

51单片机彩灯控制器的设计

51单片机彩灯控制器的设计

51单片机彩灯控制器的设计原题要求如下:1. 用16盏以上的LED小灯,实现至少4种彩灯灯光效果(不含全部点亮,全部熄灭);2. 可以用输入按钮在几种灯光效果间切换;3. 可以通过按钮暂停彩灯效果,使小灯全亮,再次按下相同按钮后继续之前的效果;4. 增加自动在几种效果间切换的功能,并设置一个按钮可以在自动模式和手动模式间切换;5. 使用定时中断延时。

最终作品如下:一共有十钟灯光效果,分别是:顺时针流水灯、逆时针流水灯、交替闪烁、顺时针对角灯、逆时针对角灯、顺时针逐个点亮、顺时针逐个熄灭、逆时针逐个点亮、逆时针逐个熄灭、二进制加法。

程序代码如下:/**************************************************************************************************模块名称:51单片机彩灯控制器模块功能:实现十种循环彩灯控制编写日期:2016/12/18******************************************************************************* *******************/#include <reg51.h>#define false 0#define true 1#define uchar unsigned char#define uint unsigned intsbit pause_key = P3^0; //暂停按钮sbit auto_key = P3^1; //手动模式的效果切换sbit change_key = P3^2; //手动模式效果切换sbit pauseLed = P3^6; //暂停、启动指示灯sbit autoLed = P3^7; //自动、手动模式指示灯int ledCode[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //led段码(单个显示)int ledCode2[8]={0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00}; //led段码(半显示半灭)int disCode[10]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09}; //数码管段码0~9void displayLed(void); //显示led的主函数void keyScan(void); //键盘扫描处理函数void Delay10ms(unsigned int n); //延时10msbit isPause = false; //是否暂停bit isAuto = true; //是否自动运行bit isChange = false; //是否要切换下一个效果uchar time; //计时满0.5suchar types; //第几种灯光显示方案uint counts; //灯光的第几个/****************************************************************************** ** 函数名: T0_INT* 函数功能: T0定时器中断函数* 输入: 无* 输出: 无******************************************************************************* /void T0_INT(void) interrupt 1{TL0= (65536-50000)/256;TH0= (65536-50000)%256;time ++;if(time >= 10) //定时时间:0.5s{time=0;if(isChange == true) //可以变换下一种显示效果了{counts = 0;types++; //显示下一种效果if(types > 9) types = 0;P0 = disCode[types]; //更新数码管显示isChange = false;}displayLed();counts++;}}/****************************************************************************** ** 函数名: main* 函数功能: 主函数* 输入: 无* 输出: 无******************************************************************************* /void main(void){TMOD=0x61; //0110 0001 //方式一TL0= (65536-50000)/256; //50msTH0= (65536-50000)%256;TR0=1; //开启T0ET0=1; //T0中断允许EA=1; //总中断开启time = 0; //定时器时间扩种(0.5s)counts = 0; //灯光的第几次types = 0; //灯光显示模式pauseLed = 0; //暂停指示灯灭P0 = disCode[types]; //更新数码管显示while(1){keyScan(); //键盘扫描及处理}}/****************************************************************************** ** 函数名: keyScan* 函数功能: 键盘扫描处理* 输入: 无* 输出: 无******************************************************************************* /void keyScan(void){if(pause_key == 0) //按下了暂停按钮{Delay10ms(1);if(pause_key == 0){isPause = ~isPause;pauseLed = isPause;if(isPause == true){ET0=0; //关闭T0中断P0 = 0xfd; //数码管显示“-”P1 = 0x00; //所有的灯都亮起来P2 = 0x00;}else{ET0=1; //T0中断允许P0 = disCode[types]; //更新数码管显示displayLed();}while(pause_key == 0); //防止按键重复检测}}if(auto_key == 0) //自动、手动切换按键按下{Delay10ms(1);if(auto_key == 0){isAuto = ~isAuto;autoLed = isAuto;}while(auto_key == 0); //防止按键重复检测}if(change_key == 0 && isAuto == false) //手动模式,并且效果切换按下{Delay10ms(1);if(change_key == 0){isChange = true;}while(change_key == 0); //防止按键重复检测}}/****************************************************************************** ** 函数名: displayLed* 函数功能: 显示led灯* 输入: (全局变量)types:显示效果;counts:当前效果下的第几次* 输出: 无******************************************************************************* /void displayLed(void){switch(types){case 0: //顺时针旋转led灯{if(counts >= 16) counts = 0;if(counts >=15){if(isAuto == true) isChange = true;}if(counts <8){P1 = 0xff;P2 = ledCode[7-counts];}else{P1 = ledCode[15-counts];P2 = 0xff;}break;}case 1: //逆时针旋转LED灯{if(counts >= 16) counts = 0;if(counts >=15){if(isAuto == true) isChange = true;}if(counts <8){P1 = ledCode[counts];P2 = 0xff;}else{P1 = 0xff;P2 = ledCode[counts-8];}break;}case 2: //交叉替换{if(counts >= 16) counts = 0;if(counts >=15){if(isAuto == true) isChange = true;}if(counts % 2 == 0) //偶数{P1=0xaa;P2=0xaa;else{P1=0x55;P2=0x55;}break;}case 3: //对角顺时针{if(counts >= 8) counts = 0;if(counts >=7){if(isAuto == true) isChange = true;}P1 = ledCode[7 - counts];P2 = ledCode[7 - counts];break;}case 4: //对角逆时针{if(counts >= 8) counts = 0;if(counts >=7){if(isAuto == true) isChange = true;}P1 = ledCode[counts];P2 = ledCode[counts];break;}case 5: //顺时针逐个点亮{if(counts >= 17) counts = 0;if(counts <8){P1 = ~ledCode2[7 - counts];P2 = 0xff;}else if(counts <16){P1 = 0x00;P2 = ~ledCode2[15 - counts];else //全亮{P1 = 0x00;P2 = 0x00;if(isAuto == true) isChange = true;}break;}case 6: //顺时针逐个又灭掉{if(counts >= 17) counts = 0;if(counts <8){P1 = ledCode2[7 - counts];P2 = 0x00;}else if(counts <16){P1 = 0xff;P2 = ledCode2[15 - counts];}else //全灭{P1 = 0xff;P2 = 0xff;if(isAuto == true) isChange = true;}break;}case 7: //逆时针逐个点亮{if(counts >= 17) counts = 0;if(counts <8){P1 = 0xff;P2 = ledCode2[counts];}else if(counts <16){P1 = ledCode2[counts - 7];P2 = 0x00;}else //全亮P1 = 0x00;P2 = 0x00;if(isAuto == true) isChange = true;}break;}case 8: //逆时针逐个灭掉{if(counts >= 17) counts = 0;if(counts <8){P1 = 0x00;P2 = ~ledCode2[counts];}else if(counts <16){P1 = ~ledCode2[counts - 7];P2 = 0xff;}else //全亮{P1 = 0xff;P2 = 0xff;if(isAuto == true) isChange = true;}break;}case 9: //二进制加法{if(counts >= 255) counts = 0;if(counts == 254 && isAuto == true) isChange = true;P1 = ~counts;P2 = ~counts;break;}default:types = 0;P0 = disCode[types]; //更新数码管显示}}/****************************************************************************** ** 函数名: Delay10ms (多个)* 函数功能: 延时函数,延时n*10ms* 输入: n-延时次数* 输出: 无******************************************************************************* /void Delay10ms(unsigned int n){unsigned char a, b;for (; n>0; n--){for (b=38; b>0; b--){for (a=130; a>0; a--);}}}完整proteus仿真图如下:。

51单片机点亮一盏LED灯的原理解析

51单片机点亮一盏LED灯的原理解析

51 单片机点亮一盏LED 灯的原理解析
首先应该了解51 单片机最小系统:51 最小系统也称为51 最小应用系
统,是指用最少的元件组成的51 单片机可以工作的系统。

如图2.1.1 所示,51 最小系统一般应该包括:单片机、晶振电路、复位电路。

晶振电路的原理及组成,作用:
在单片机系统里晶振的作用非常大,他结合单片机内部的电路,产生单片机所必须的时钟频率,单片机的一切指令的执行都是建立在这个基础上的,晶振的提供的时钟频率越高,那单片机的运行速度也就越快。

简单地说,没有晶振,就没有时钟周期,没有时钟周期,就无法执行程序代码,单片机就无法工作。

单片机工作时,是一条一条地从RoM 中取指令,然后一步一步地执行。

单片机访问一次存储器的时间,称之为一个机器周期,这是一个时间基准。

个机器周期包括12 时钟周期。

如果一个单选择了12MHz 晶振,它的
时钟周期是1/12us,它的一个机器周期是12&TImes;(1/12)us,也就是
1us。

组成:晶振,负载电容,内部电路。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1.实验任务
如图4.1.1所示:在P1.0端口上接一个发光二极管L1,使L1在不停地一亮一灭,一亮一灭的时间间隔为0.2秒。

2.电路原理图
图4.1.1
3.系统板上硬件连线
把“单片机系统”区域中的P1.0端口用导线连接到“八路发光二极管指示模块”区域中的L1端口上。

4.程序设计内容
(1).延时程序的设计方法
作为单片机的指令的执行的时间是很短,数量大微秒级,因此,我们要求的闪烁时间间隔为0.2秒,相对于微秒来说,相差太大,所以我们在执行某一指令时,插入延时程序,来达到我们的要求,但这样的延时程序是如何设计呢?下面具体介绍其原理:
如图4.1.1所示的石英晶体为12MHz,因此,1个机器周期为1微秒=0.001毫秒(ms)
机器周期微秒
MOV R6,#20 2个 2 2
D1: MOV R7,#248 2个 2+2×248=498 20×(2+2×248)
DJNZ R7,$ 2个2×248=496
DJNZ R6,D1 2个2×20=40 10002
因此,上面的延时程序时间为10.002ms。

10002=2+(2+2*248)*20+40
由以上可知,当R6=10、R7=248时,延时5ms,R6=20、R7=248时,延时10ms,以此为基本的计时单位。

如本实验要求0.2秒=200ms,10ms×R5=200ms,则R5=20,延时子程序如下:
DELAY: MOV R5,#20
D1: MOV R6,#20
D2: MOV R7,#248
DJNZ R7,$
DJNZ R6,D2
DJNZ R5,D1
RET
(2).输出控制
如图1所示,当P1.0端口输出高电平,即P1.0=1时,根据发光二极管的单向导电性可知,这时发光二极管L1熄灭;当P1.0端口输出低电平,即P1.0=0时,发光二极管L1亮;我们可以使用SETB P1.0指令使P1.0端口输出高电平,使用CLR P1.0指令使P1.0端口输出低电平。

5.程序框图
如图4.1.2所示
6.汇编源程序
ORG 0
; ORG 的意思是什么就是
值不同跟系统程序存贮器地址有关. 以上面的程序来讲ORG 0000H接下来写的程序都在
0000H后。

ORG 2000H也一样。

(如果ROM够大的话)
START: CLR P1.0
LCALL DELAY
;“调用”(ACALL或LCALL)一下,避免重复编写也节省程序存储空间,子程序的最后都
要放一条返回指令既“RET”。

SETB P1.0 ;使P1.0变为1。

灯亮。

LCALL DELAY
LJMP START ;转入主程序
DELAY: MOV R5,#20 ;延时子程序,延时0.2秒
D1: MOV R6,#20
D2: MOV R7,#248
DJNZ R7,$
DJNZ R6,D2
DJNZ R5,D1
RET
END
7.C语言源程序
#include <AT89X51.H>
sbit D1=P1^0; //定义一个变量D1,值是P1的第一个口
void delay02s(void) //延时0.2秒子程序 2*(20*20*248)/(1000*1000){
unsigned char i,j,k;
for(i=20;i>0;i--)
for(j=20;j>0;j--)
for(k=248;k>0;k--);
}
void main(void)
{
while(1)
{
D1=0; //灯亮
delay02s();
D1=1; //灯灭
delay02s();
}
}。

相关文档
最新文档