一、LED控制介绍
发光二极管是半导体二极管的一种,可以把电能转化成光能,常简写为LED。发光二极管与普通二极管一样是由一个PN结组成,也具有单向导电特性。当给发光二极管加上正向电压时就会发光,光的强弱与工作电流成正比。一般情况下,LED的正向工作电流在10mA左右,如果电流过大就会烧坏LED,因此使用时必须串联限流电阻以控制通过二极管的电流。
普通发光二极管的正向饱和压降为1.6V~2.1V。发光二极管的特点是:工作电压很低(有的仅一点几伏);工作电流很小(有的仅零点几毫安即可发光);抗冲击和抗震性能好,可靠性高,寿命长;通过调制通过的电流强弱可以方便地调制发光的强弱。由于有这些特点,发光二极管在一些光电控制设备中用作光源,并广泛应用于各种电子电路、家电、仪表等设备中。
本文使用的开发板上设计了8个发光二极管,其中有2个红色、2个黄色、2个绿色和2个蓝色。发光二极管部分的原理图如下图所示。R21是470欧姆的8位阻排,LED1~LED8是8个发光二极管,阻排的公共端与5V电源VCC相连,发光二极管的正极与阻排相连,负极与插针J21相连,J21经过杜邦线可以连接到需要使用的I/O口。连接好后,单片机输出低电平时对应的LED灯点亮,高电平时对应的LED灯熄灭。
我们来了解下I/O口的工作原理。I/O口即输入和输出口,单片机的I/O口既可以作为输入信号端、也可以作为输出信号端。图中,J21可以接5V、悬空、也可以接地。以LED1为例,我们将LED1的等效电路单独画出来,如下图所示。
图中VCC是5V的电源,当电路的右侧接5V或者悬空时,电路没有电流通过,LED灯的状态是熄灭的;当电路的右侧接地时,两端压差是5V,所以LED灯被点亮。在数字电路中,接+5V为电平“1”,接地为“0”。
所以在设计中,将LED连接到单片机的I/O口,此时我们只需要控制单片机的I/O口为“1”或者为“0”就可以控制LED灯的亮灭了。
二、例程测试
在这个实验中我们用两种不同的方法对一个LED灯进行控制,在测试之前需要将上边J21的1引脚与单片机的P00用杜邦线连接起来。
方法1:
实现的代码如下所示
#include sbit LED=P0^0; void main (void) { LED=0; //将P00口赋值0,对外输出低电平 for(;;); //死循环,原地等待 } 将这个代码编译之后将Hex文件烧写到单片机中,可以看到LED1点亮。 1、在上面的代码中,#include #ifndef __REG52_H__ #define __REG52_H__ /* BYTE Registers */ sfr P0 = 0x80; sfr P1 = 0x90; sfr P2 = 0xA0; sfr P3 = 0xB0; sfr PSW = 0xD0; sfr ACC = 0xE0; sfr B = 0xF0; sfr SP = 0x81; sfr DPL = 0x82; sfr DPH = 0x83; sfr PCON = 0x87; sfr TCON = 0x88; sfr TMOD = 0x89; sfr TL0 = 0x8A; sfr TL1 = 0x8B; sfr TH0 = 0x8C; sfr TH1 = 0x8D; sfr IE = 0xA8; sfr IP = 0xB8; sfr SCON = 0x98; sfr SBUF = 0x99; /* 8052 Extensions */ sfr T2CON = 0xC8; sfr RCAP2L = 0xCA; sfr RCAP2H = 0xCB; sfr TL2 = 0xCC; sfr TH2 = 0xCD; /* BIT Registers */ /* PSW */ sbit CY = PSW^7; sbit AC = PSW^6; sbit F0 = PSW^5; sbit RS1 = PSW^4; sbit RS0 = PSW^3; sbit OV = PSW^2; sbit P = PSW^0; //8052 only /* TCON */ sbit TF1 = TCON^7; sbit TR1 = TCON^6; sbit TF0 = TCON^5; sbit TR0 = TCON^4; sbit IE1 = TCON^3; sbit IT1 = TCON^2; sbit IE0 = TCON^1; sbit IT0 = TCON^0; /* IE */ sbit EA = IE^7; sbit ET2 = IE^5; //8052 only sbit ES = IE^4; sbit ET1 = IE^3; sbit EX1 = IE^2; sbit ET0 = IE^1; sbit EX0 = IE^0; /* IP */ sbit PT2 = IP^5; sbit PS = IP^4; sbit PT1 = IP^3; sbit PX1 = IP^2; sbit PT0 = IP^1; sbit PX0 = IP^0; /* P3 */ sbit RD = P3^7; sbit WR = P3^6; sbit T1 = P3^5; sbit T0 = P3^4; sbit INT1 = P3^3; sbit INT0 = P3^2; sbit TXD = P3^1; sbit RXD = P3^0; /* SCON */ sbit SM0 = SCON^7; sbit SM1 = SCON^6; sbit SM2 = SCON^5; sbit REN = SCON^4; sbit TB8 = SCON^3; sbit RB8 = SCON^2; sbit TI = SCON^1; sbit RI = SCON^0; /* P1 */ sbit T2EX = P1^1; // 8052 only sbit T2 = P1^0; // 8052 only /* T2CON */ sbit TF2 = T2CON^7; sbit EXF2 = T2CON^6; sbit RCLK = T2CON^5; sbit TCLK = T2CON^4; sbit EXEN2 = T2CON^3; sbit TR2 = T2CON^2; sbit C_T2 = T2CON^1; sbit CP_RL2 = T2CON^0; #endif 从这个文件的定义可以看出,这个文件主要定义了单片机的端口和特殊功能寄存器。程序中包含了头文件之后,就可以直接使用定义过的标志符。例如:P0口的寄存器地址是0x80,其中0x表示它后边的数值是16进制的。如果对P0口进行操作,我们直接使用P0这个标志符就行了,而不需要了解P0口寄存器的物理地址和内部结构。 2、sfr和sbit,reg52.h中可以看到这两个关键字。“sfr P0= 0x80;”这一句的含义是将单片机内部地址为0x80的寄存器重新起名为P0,以后我们在程序中就可以直接操作P0,就相当于对单片机内部的0x80地址处的寄存器进行操作。实际上,通过sfr关键字的定义,让Keil编译器在单片机和用户之间搭建了一条可以进行沟通的桥梁,我们操作P0口,而单片机并不知道什么是P0口,但它知道知道它内部的地址0x80是什么。 “sbit CY= PSW^7;”这一句的意思是将PSW这个寄存器的第7位重新命名为CY,所以在需要单独操作PSW寄存器第7位时,可以直接操作CY。 在程序中有一句“sbit LED=P0^0;” 这一句的意思是将P0口寄存器的第0位,也就是最低位定义为LED,因此程序中操作LED时相当于操作P0口寄存器的第0位。例如:LED=0; 相当将0赋值给P0口寄存器的第0位。 3、main()函数,主函数就是main函数,是程序的入口,程序一旦执行的时候就会从这个入口开始,任何一个程序中有且只有一个主函数。 4、for(;;)。for()循环是C语言中一种基本的循环方式,当条件为真时,进入循环体,条件不满足时,跳出。 for()循环的标准格式为 for(表达式1;表达式2;表达式3) {语句(内部可以为空)} 我们来看一下下边这段程序。 unsigned char i; for(i=2;i>0;i++) { } 这段程序首先定义了一个无符号字符型变量i,然后指向for语句。i=2;i>0;i++这三个表达式中,表达式1是给i赋一个初值2,表达式2判断i>0是真还是假,表达式3是i每个周期减1。我们来分析一下这个for循环的执行过程。 第一步:给i赋初值2,此时i=2。 第二步:因为2>0,条件成立,所以其值为真,那么执行for循环下边大括号中的内容。由于大括号中为空,所以什么也不执行。 第三步:i自减1,即i=i-1=2-1=1。 第四步:跳回到第二步,因为1>0,条件成立,所以其值为真,那么执行for循环下边大括号中的内容。由于大括号中为空,所以什么也不执行。 第五步:i自减1,即i=i-1=1-1=0。 第六步:跳回到第二步,因为0>0,条件不成立,所以其值为假,那么结束for循环,程序从for循环中跳出。 “for(;;);”这个语句中for的三个表达式都为空,这个for语句是无限循环。 本例中,进入main函数对LED灯进行操作,之后进入for循环,并一直在循环中等待,不进行任何操作,因此LED灯的状态也不会发生变化。 该程序虽然简单,但是包含C语言最基础的知识,后面的程序会在此基础上增加新的内容。 5、程序的注释,//和/* */这两种符号表示注释。注释语句虽然不对程序的运行产生任何影响,但必要的注释是程序的重要组成部分。对于一个程序员来说,及时加注释是一个好的习惯。上述两个注释的区别在于://是行注释,换行无效;/* */中间的内容都是注释,换行有效。注释可以根据大家的习惯,没有具体要求。 方法二: 实现代码如下所示 #include #define LED P0 //宏定义关键字,定义LED到单片机的P0口 void main (void) { LED=0xfe; //将P0口赋值0xfe, //0xfe转换为二进制为 1111 1110,即P0口的最低位输出低电平,其它位输出高电平。 for(;;); //死循环,原地等待 } 在这个实验中,对LED控制的命令与方法一是不同的,主要知识点如下: 1、宏定义,宏定义又称为宏代换、宏替换,简称“宏”。 宏定义的格式: #define 标识符 字符串 其中的标识符就是所谓的符号常量,也称为“宏名”。预处理(预编译)工作也叫做宏展开,将宏名替换为字符串。掌握“宏”概念的关键是“换”。一切以换为前提、做任何事情之前先要换,准确理解之前就要“换”。即在对相关命令或语句的含义和功能作具体分析之前就要换。 例如程序中#define LED P0 表示LED灯定义在P0口上。因此对P0口进行操作,我们可以直接用LED来代替,LED=0xfe;就相当于P0=0xfe; 2、进制转换,这个实验与第一个实验不同,直接对P0口整体进行操作。P0口的宽度是8位,用二进制表示是xxxx xxxx。单片机常用的进制是:二进制、八进制、十进制和十六进制,0x前缀表示十六进制,如:0xFF。0xFF与0xff相同,C语言中数值不区分大小写。这几种进制形式不同,但是可以相互转换。 本实验中同样是点亮了LED1。但是对P0口进行整体赋值的方法,将0xfe赋给了P0,0xfe转换成2进制就是11111110,也就是将P0口的高7位拉高,最低位拉低,这样LED1就可以点亮了,其余的灯熄灭。
上一篇:51单片机(六)—— GPIO控制多路LED
下一篇:51单片机(四)—— 51单片机仿真芯片的使用
推荐阅读最新更新时间:2024-11-12 22:46
设计资源 培训 开发板 精华推荐
- A000053,基于 ATmega32u4 8 位 ATmega AVR MCU 的 Arduino 微型开发套件平台
- UNO下载器|TTL多口调试下载器
- AD5327 4 缓冲、12 位 DAC 的典型应用,用于对系统中的多个设备进行解码
- 使用 Murata Manufacturing 的 LBWA1ZV1CD-716 的参考设计
- UM232R, USB - 用于 FT232RL USB-to-UART 接口的串行 UART 开发模块
- 物联控制|宿舍双吊灯控制
- IRAUDAMP18、2 通道、35W(4 欧姆)半桥 D 类音频功率放大器,具有单电源,使用 IR4312
- AM30EW-240512TZ 5V双输出DC/DC转换器的典型应用
- ADP2390-EVALZ,用于评估 ADP2390 的评估板,18V,12A,降压稳压器,可编程限流
- LTM8008 演示板、72VIN、6 输出 DC/DC SEPIC 模块稳压器