首页 > 其他分享 >51单片机--LED闪烁、流水灯的简单试验

51单片机--LED闪烁、流水灯的简单试验

时间:2022-12-06 12:31:22浏览次数:40  
标签:P2 LED -- 51 delay 单片机 延时 led


一、LED闪烁 

/*****************************************************************
LED闪烁的简单试验 *****************************************************************/
include <reg51.h> //此文件中定义了51的一些特殊功能寄存器
/*******延时函数**************************************/
// 定义一个演示函数,定时时间大概为一个ms。

void delay(unsigned int i)
{
unsigned char j;
for(i; i > 0; i--)
for(j = 100; j > 0; j--);
}
/**************************************************************************/
main()
{
while(1)
{
P2 = 0x00; //置P2口为低电平 led灯点灭
delay(1000); //调用延时程序 led持续灭,保持
P2 = 0xff; //置P2口为高电平 led灯熄亮
delay(1000); // 调用延时程序 led持续亮,保持
//重复以上语句, led灯点亮,保持亮的状态,熄灭,保持熄//灭状态 循环这个4个过程。
}
}

 

/*  */作用,它是用来注释一段内容的,编译器不对其进行编译,只要在/*  */直接的内容都被注释掉。

// 是用来注释其后面的内容,只能注释一行。

#include <reg51.h> //这句告诉我们包涵51的头文件,头文件放的是什么东西,放的是51单片机对应的操作的寄存器地址,如我们直接用来操作的P1口就是代表0x90地址,我们可以将光标低位在<reg51.h>上然后右键

51单片机--LED闪烁、流水灯的简单试验_单片机

打开头文件,

#ifndef __REG51_H__
#define __REG51_H__

/* BYTE Register */
sfr P0 = 0x80;
sfr P1 = 0x90;
sfr P2 = 0xA0;
sfr P3 = 0xB0;
sfr PSW = 0xD0;
sfr ACC = 0xE0;
…………………………….
/* SCON */
sbit SM0 = 0x9F;
sbit SM1 = 0x9E;
sbit SM2 = 0x9D;
sbit REN = 0x9C;
sbit TB8 = 0x9B;
sbit RB8 = 0x9A;
sbit TI = 0x99;
sbit RI = 0x98;
#endif

头文件中定义了51系列单片机的所有功能寄存器,我们直接使用其代号就可以,P0,P1等

如 sfr P0=0x80,意思是把单片机内部地址0x80处的寄存器重新起名字叫P0,以后我们在程序中直接操作P0,就相当于对单片机内部0x80地址处的寄存器进行操作。通俗的讲,也就是说,通过sfr这个关键字,让Keil编译器在单片机与人之间搭建一个桥梁,我们操作P0口,单片机对应就去操作内部0x80的地址。所以我们写程序要在开始处直接包涵单片机的头文件。

sbit  SM0  = 0x9F;是定义位操作地址0x9F的,这个地址只代表一个位。我们操作SM0,对应单片机就是操作位地址0x9F。

 

总结起来sfr与sbit区别

         sfr 是定义字节的  8位

         sbit 是定义位的   1位

 

我们在返回主程序:

void delay(unsigned int i)

{

    unsigned char j;

    for(i; i > 0; i--)  

        for(j = 100; j > 0; j--);

}

 定义一个函数delay();与c语言一样,要用一个函数,先定义,我们可以叫它子函数,可以调用的。

 

main()  // 结构同c语言一样,main()函数开始

 

{  // 大括号。

  P2  = 0x00; //置P2口为低电平

从这句开始,你现在控制单片机了,告诉单片机把你的P2口都输出0,如果你不操作P2口了,那么P2口一直保持这个状态,直到你去改变它。

  delay(1000); //调用延时程序

调用子函数delay(),告诉单片机去执行delay那个函数,那么P2口一直保持0这状态。

 

  P2  = 0xff; //置P2口为高电平

这时告诉P2口全部输出1,(0xff=1111 1111).转太有0变成1了,对应的灯的输出也由低电平变成高电平了

  delay(1000); // 调用延时程序,再进行延时,

}

这个程序里执行完了一次又干什么呢,

Keil编译器会编译成一直重复执行main()函数里面的代码,整个代码的效果就是:

1)P2输出低电平

2)延时一段时间,目的是P2输出的电平保持一段时间

3)P2输出高电平

4)延时一段时间,目的是P2输出的电平保持一段时间

5)重复1)到4)的过程   实际效果就是led一闪一闪

通过更改delay(延时时间t),参数t,可以改变闪烁频率。

 

实际操作:

  1. 打开软件(提前装好驱动)
  2. 点击打开文件,打开我们刚刚编译的led.hex文件,下载程序,就会看到led闪烁。

二、流水灯的简单试验

/******************************************************************************
流水灯
延时实现P2口LED流水灯效果 (用循环移位指令)

******************************************************************************/
#include <reg51.h> //此文件中定义了51的一些特殊功能寄存器

void delay(unsigned int i) // 延时子程序
{
unsigned char j;
for(i; i > 0; i--)
for(j = 100; j > 0; j--);
}
main()
{
unsigned char LED;
LED = 0xfe; //0xfe = 1111 1110 此时,led灯的最低一位亮
while(1)
{
P2 = LED;
delay(300);
LED = LED << 1; //循环左移1位,点亮下一个LED "<<"为左移位
if(P2 == 0x00 )
{LED = 0xfe; } // 0xfe = 1111 1110
}
}

代码注释:

void delay(unsigned int i)    // 延时子程序
{
unsigned int i; //定义一个无符号变量i,16位宽度,最大可表示二进制1111 1111 1111 1111,对应十进制是65535共计65536个数,从0开始。
for(i; i > 0; i--) //传过来的参数进行自减,只要不为0就执行循环里的参数,执行一次减1,直到i变为0,跳出循环
{
for(j = 100; j > 0; j--); //i=0开始,判断i是否>0,不是的话,j自动减1,之后再判断i是否>0,直到i<=0,跳出for 循环。整个延时子程序 每次调用都要执行i*100个for 循环。由于c语言编译的结果时间不确定,不是很精确,这里暂不计算时间。
} }
unsigned char LED; //定义一个无符号8位变量。
LED = 0xfe; //0xfe = 1111 1110 把刚刚定义的变量赋值
while(1) // 无限循环以下程序
{
P2 = LED; // 第一次吧0xfe送给P2口,那么最低位连接的led点亮
delayms(300); //延时,就是上一个语句状态保持一段时间
LED = LED << 1; //循环左移1位,点亮下一个LED "<<"为左移位
if(P2 == 0x00 ) //判断P2的值,是否都为0,如果都为0的话就要重新赋值
{LED = 0xfe; } // 0xfe = 1111 1110
}


以上程序实现led依次亮,循环执行。

 

以下是我们的硬件电路,led从D11~D18,排阻RP20和RP21。

51单片机--LED闪烁、流水灯的简单试验_头文件_02

元器件介绍:

排阻:

一般在排阻上都标有阻值号,其公共端附近也有明显标记。如下下图表示为472,表示47*(10^2)=4700欧姆,

51单片机--LED闪烁、流水灯的简单试验_单片机_03

还有的标号如3R0,表示阻值为3欧姆, 4K7表示阻值为4.7kΩ, R002表示阻值为0.002欧姆。

 

    (2)发光二极管。它具有单向导电性,通过5mA左右电流即可发光,电流越大,其亮度越强,但若电流过大,会烧毁二极管,一般我们控制在3 mA-20mA之间。在这里,给发光二极管串联一个电阻的目的就是为了限制通过发光二极管的电流不要太大,因此这个电阻又称为“限流电阻”。当发光二极管发光时,测量它两端电压约为1.7V,这个电压又叫做发光二极管的“导通压降”。图2.2.9和图2.2.10分别为直插式发光二极管和贴片式发光二极管实物图。发光二极管正极又称阳极,负极又称阴极,电流只能从阳极流向阴极。直插式发光二极管长脚为阳极,短脚为阴极。仔细观察贴片式发光二极管正面的一端有彩色标记,通常有标记的一端为阴极。

51单片机--LED闪烁、流水灯的简单试验_单片机_04

            

51单片机--LED闪烁、流水灯的简单试验_头文件_05

   关于排阻大小的选择:欧姆定律想必大家都清楚,U=IR,当发光二极管正常导通时,其两端电压约为1.7V,发光管的阴极为低电平,即0V,阳极串接一电阻,电阻的另一端为Vcc , 为5V,因此加在电阻两端的电压为5V-1.7V=3.3V,计算穿过电阻的电流,3.3 V/ 1000Ω=3.3mA

即穿过发光管的电流也为3.3mA,若想让发光管再亮一些,我们可以适当减小该电阻。

 

看我们的原理图,可以知道:LED的正极接在VCC上,只要给了低电平,那么LED就会亮,低电平对应到单片机的逻辑就是0,只要单片机的某一个管脚输出0,那么对应的发光二极管就会亮。

标签:P2,LED,--,51,delay,单片机,延时,led
From: https://blog.51cto.com/u_15903730/5915632

相关文章

  • 以修改内存的方式实现导入表动态注入
    简介搜索"导入表注入",网上大堆的博客和代码,统统都是修改PE文件实现的.这里将介绍exe加载到内存后,修改主模块映像,而不必去改变本地的exe文件的注入方法.原理注......
  • PYTHON 面向对象
    1.1面向对象三个基本特性:封装性(隐藏了内部细节,只保留有限的对外接口)继承性(代码的复用,父类(一般类,超类),子类(特殊类,派生类))多态性(子类继承父类,具有不同的状态或表现行为,即......
  • python基础-异常处理
    1.异常与异常处理  异常就是程序中的错误,正常情况下程序是自上而下逐行执行的,当遇到异常时,就会报错退出执行;  异常处理就是在程序中可能出错的地方进行提前预捕获,并......
  • CentOS下搭建Gitea-自己的git服务器
    CentOS下搭建Gitea-自己的git服务器1Gitea是什么完全开源功能基本满足我的需求需要的机器性能不高,官方建议是2核CPU及1GB内存,我自己跑1核1GB有点小慢(故而以下教......
  • Linux基础学习
    Linux基础Lesson1-常用基本命令​1.Ctrlc:取消命令,并且换行Ctrlu:清空本行命令tab键:可以补全命令和文件名,如果补全不了快速按两下tab键,可以显示备选选项ls......
  • 技术分享| anyRTC音视频与微信小程序互通实践
    随着网络架构的变迁、媒体技术发展、音视频场景迭代,基于流媒体的技术也是推陈出新。WebRTC渐渐的成为了音视频互动场景的主流,而微信在6.5.21版本通过小程序开放了实时音视......
  • 刷题笔记——2997.梯形面积
    题目2997.梯形面积代码h=(2*150)/15s=((15+25)*h)/2print('%.2f'%s)笔记使用占位符方法保留小数%g,科学计数法输出小数,会舍弃无效的部分print(......
  • nginx解决vue跨域问题
    location/epayapi{proxy_passhttp://127.0.0.1:7011;proxy_set_headerHost$host;proxy_set_headerX-Real-IP$remote_addr;proxy_set_headerX......
  • "无汗畏寒发热"和"有汗发热"和"温病虚证"的症状和治疗方法
    无汗畏寒发热是比较常见的一种发热,通俗地讲就是一边发烧一边浑身发冷,一点汗都没有。【主要症状】恶寒,发热,头痛,关节疼痛明显,鼻塞声重,流清鼻涕,口不渴,咳嗽时吐稀痰,咽喉疼痛不......
  • HTML-学习笔记02
    HTML13、样式器+标签选择器内部样式表<html> <head> <metacharset="utf-8"> <title></title> <!--内部样式表--> <style> /*标签选择器*/ h1{ ......