设计与开发

单片机的小灯 「连载14」LED 小灯的原理解析|学单片机做四轴飞行器项目故事

小编 2024-11-24 设计与开发 23 0

「连载14」LED 小灯的原理解析|学单片机做四轴飞行器项目故事

《 STC15 单片机实战指南( C 语言版)》 一书以一坚科技研发的飞天三号( FSST15-V1.0)实验板为硬件平台, 以《 深入浅出玩转 STC15 单片机》为配套视频, 由清华大学出版社权威出版, 并且分别是 STC 官方大学计划和高校高性能联合实验室推荐教程和视频, 版权归作者和清华大学出版社所有。

本资料以个人学习、 工作经验以及宏晶科技单片机技术为素材, 以单片机初学者、单片机项目开发者为对象, 教大家如何走进单片机,继而达到开发工程项目(如:四轴飞行器设计,多功能收音机等)为目的。 限于时间和水平关系,资料中难免有过失之处,望各位高手批评指教,多多拍砖,拍累了,你们休息,我继续上路。

现已连载的方式免费共享于电子发烧友网,供单片机新手们参考学习,可以自由下载传阅 ,但未经作者许可,不得用于任何商业目的, 转载请注明出处。

作者 | 残弈悟恩

编辑 | Garen

要熟练操作 LED 小灯,必须要对其内部特性和发光特性加以了解,这样才能更好的控制 它。

3.8.1 LED 灯的原理说明

LED(Light Emitting Diode),发光二极管,简称 LED,是一种能将电能转换为可见光 的固态半导体器件。LED 的核心是一个半导体的晶片,晶片的一端附在一个支架上,连接电 源的正极使整个晶片被环氧树脂封装起来,另一端是负极。半导体晶片由两部分组成,一部 分是 P 型半导体,在它里面空穴占主导地位,另一端是 N 型半导体,在这边主要是电子。但 这两种半导体连接起来的时候,它们之间就形成了一个“P-N 结”。当电流通过导线作用于 这个晶片的时候,电子就会被推向 P 区,在 P 区里电子跟空穴复合,然后就会以光子的形式 发出能量,这就是 LED 发光的原理。至于颜色,读者可以自行查阅资料,概况说,电子与空 穴复合时释放出的能量决定了光的波长,波长决定了发光的颜色。

LED 品种繁多,如何识别正负,常见的有直插式和贴片式两种,如何区分 LED 的正负极是很多初学者经常问到的问题,常见的方法有观察法和万用表测量法。

1、观察法。直插式 LED:直插式的 LED 如果是全新的,可以通过引脚长短来判别发光 二极管的正负极,引脚长的为正极,短的为负极。还有就是拿手上,一抹就知道(发光二极 管的环氧树脂封装上有个缺口的是负极);贴片 LED:俯视,一边带彩色线的是负极,另一边是正极。

2.万用表测量法。这里讲述数字式(不是指针式的)。将万用表打到二极管测试档,两 表笔接触二极管的两个脚,若二极管发光,说明红表笔接的是正极,黑表笔接的是负极。若 不亮,情况刚好相反。

3.8.2 LED 小灯的硬件电路

对于 LED 来说,总共两个引脚,在电路设计上没有难度,这里以 FSST15 开发板上的原 理图来做讲解。通常情况下,LED 内部需要通过一定的电流且存在一定的压差(也即压降) 才能使得其发光。通常使用的 LED 的工作电流为 3~20mA 左右,但二极管本身的内阻又比较 小,所以不能直接将两端接电源和 GND,而需要加一个限流电阻(阻值如何计算,请看后面 分解),限制通过 LED 的电流不要太大,LED 原理图如图 3-33 所示。

该方式的 LED 驱动电路是将正极接在 3.3V(高电平)上,负极再串联一个 47OΩ 的限流 电阻,再接到单片机的 I/O 口上,这样,只需给 LED1~LED12 所对应的 I/O 口上低电平,就 可以点亮 LED;还有一种接法是将 LED 的正极接单片机的 I/O 口,再通过一限流电阻,将负 极接地,单片机输出高电平,就可以点亮 LED,但是需要将 I/O 设置为强推挽输出模式。但 事实上是单片机上电之后 I/O 口默认电平为高电平,这样,从工程的角度考虑,单片机上电以后,LED 就会工作,这并不是我们想要的结果,所以一般不建议这么设计电路,当然具体 设计依情况而定。

图 3-33 FSST15 开发板上 LED 原理图

经上述分析,LED 两端只要有一合适的压差和电流,就会点亮 LED。那么单片机又是如 何控制的呢。举个例子,要有水流,必须有水压差,同样,要有电流,就得有电压差,结合 上图,LED 的正极已经接了高电平,那如果 LED1~LED12 所对应的单片机端口也为高电平, 这样,LED 的左右电平都是高电平(3.3V),则就没有压差,所以就没有电流,则 LED 就不 会亮,相反若单片机端口为低电平,从而 LED 两端则会有压差(左低、右高),这样 LED 灯 就会被点亮。至于这里的 LED1~LED11,肯定都接了单片机的 I/O,具体接到了哪里,请参考 附录的 FSST15 原理图。这里读者唯独需要注意的是,原理图中,网络标号相同,表示此线 是在电气特性上是相连接的。同时需要注意的是,开发板上资源过多,I/O 口不够,这里将 LED11 和 RS485 的方向控制脚都连接到了 P3.6 引脚上。

3.9 LED 小灯的应用实例

通过以上学习,大家已经扫除了 LED 原理和硬件障碍,现在来看看如何借助单片机用软 件来控制 LED,由原理图可知,12 个 LED 全都接在单片机的 I/O 口上,这里只需将其对应口 线的电平高低就可以实现控制 LED 的亮灭。为了不把新手们扼杀在萌芽阶段,先不讲解单片 机的原理,所以只需依葫芦(前面讲述的 Keil5 开发流程)画瓢(剪刀、浆糊下面的例程),继而熟悉开发流程并点亮一颗 LED 小灯。

不知读者是否还记得,学完第 2 章之后,所预留的第 3 个问题,仔细观察过的读者应该 知道,D9 发光二极管被点亮了,具体实例请读者查看 2.3 小节,点亮一个 LED 灯的效果如图 3-34 所示,此时,读者应该感到高兴,毕竟已经点亮了一个小灯,星星之火可以燎原嘛, 所以,只要读者带着坚持和渴望的心态,那么接下来学习将会变的更简单。

图 3-34 点亮一个 LED 的效果图

3.9.1 LED 闪烁实例

估计有些读者已经按捺不住内心的好奇心,觉得只点亮 LED 还不能满足,想实现 LED的闪烁,那该如何实现呢?

该实例对于 C 语言基础比较好的读者来说,应该比较简单,无非就是反复循环的点亮→延时→熄灭→延时,但对于初学者,估计还是有些难度,因为该实例相对于第二章的实例出现了好多新名词,例如 Delay1000ms延时函数、头文件“STC15.h”等,在这里,笔者对 这些知识点先不做讲述,读者只需按照开发流程,把程序多写几遍,熟悉开发流程和基本的编程技巧就够了,具体内容等读者学习了下节课的模块化编程,这些问题就会变得简单了。 最后编译生成 HEX 文件,下载到单片机中,读者应该能够观察到,FSST15 开发板上的 LED(D19)小灯开始闪。

3.9.2 LED 跑马灯实例

有了 3.9.1 实例基础,我们再对其加以升级,让其开发板上的 12 个 LED 全部依次开始 闪烁,这样就可实现 LED 跑马灯的效果,也即 LED 像一匹骏马驰骋于开发板上,不同的时刻, 出现在不同的位置,需要注意的是,同一时刻,只有一个 LED 是点亮的。这里忽略单片机自 身运行时间的差异。

这里很巧妙的用了 KeilC51 自带的函数库_crol_,该函数包含在“intrins.h”头 文件中,所以需要增加一句#include 《intrins.h》包含该头文件。_crol_函数的功能是 循环左移,什么是循环左移,什么是左移,什么又是右移、或者循环右移,结合图示来说明, 如图 3-35、3-36、3-37、3-38 所示。

图 3-35 左移示意图

图 3-36 循环左移示意图

图 3-37 右移示意图

图 3-38 循环右移示意图

有了以上的图示,笔者相信,C 语言中的“《《”、“》》”和循环左、右位移应该不难理解,之后读者自行编程下载,观察其实验现象。

3.9.3 LED 流水灯实例

流水灯顾名思义就是让 LED 如同流水一般,从无灯亮,到亮一个,再到亮二个,以此类 推,亮 3 个、4…12 个,最后全部熄灭,再周而复始的循环下去,先看源码,再做讲述。

此程序了,就不做详细说明了,读者只需结合上面的左移示意图和ft寨流程图,流程 图如图 3-39(右半部分)所示,为了和跑马灯例程相对比,笔者还画了跑马灯的示意图, 这样只有读者对其两者进行对比,肯定能看出端倪,同时应该能掌握其运行的过程。

图 3-39 跑马灯和流水灯示意图

这里讲述跑马灯和流水灯,不仅要熟悉开发流程,还需掌握和积累 C 语言以及一些 C51 的自带函数,只有不断的积累、重复、思考,才能做到由“量变”到“质变”。单片机的学 习不同于别的学科,当你真正做几个实验入门以后,你会发现“她”很有魅力,一直吸引着你,不厌不弃!

单片机小制作,LED小灯瓶

有一天在网上看到一个制作——LED电子萤火虫,我感觉电路很有特点,于是就想仿制一个。那个LED电子萤火虫用的是ATtiny13单片机来控制,我也正好有。而且硬件制作比较简单,成本也不高,10元钱都不到,就能DIY一个。虽然简单,但是制作却需要耐心和细心,毕竟需要连接12个LED,焊接的工作量不少,我自己用了一个下午才完成,而程序更是陆陆续续地写了几个小时。

估计你会很好奇地问,一共才6个可用I/O引脚的 ATtiny13,怎么能驱动12个LED呢?其实,我要告诉你,它不仅可以点亮每个LED,而且还能控制每个LED的亮度呢!这才是本次制作的精华。在制作的过程中,发生了一点小小的意外。由于我购买的JST充电线和原来的充电器引脚相反,致使我原本打算使用的小型锂电池损坏,不能充电。在万般无奈的情况下,我只好更换体积更大的锂电池了。

主要材料

图6.1 制作所需的主要材料

这次的主要元器件就是ATtiny13单片机和12个LED。当然还有双绞线、洞洞板、电池、空瓶子、电阻等其他辅助材料,如图6.1所示。

本制作使用的是8个引脚的ATtiny13单片机,这款单片机现在的价格很便宜,4元左右就能买到。ATtiny13 是AVR 单片机,它有1KB 的 Flash、64B 的EEPROM、64B 的SRAM、6 个通用I/O口线、32个通用工作寄存器、1个具有比较模式的8位定时器/计数器、片内/外中断、4路10位ADC、具有片内振荡器的可编程看门狗定时器,以及3种可以通过软件进行选择的省电模式。12个LED为普通的3mm发黄色光的LED。

制作过程

1 焊接单片机插座。

2 焊接两个电阻。

3 双绞线套入热缩管后,焊接LED。焊接好后,用打火机加热热缩管,使其收缩固定。最后,别忘了再扭下热缩管。

4 焊接好的12个LED。

5 双绞线焊接到洞洞板上。

6 洞洞板和双绞线焊接好的效果。

7 焊接JST插头、锂电池和开关。

8 在瓶子上开口。

9 用热熔胶固定。

10 装入瓶子中。

控制原理

为什么6个I/O能控制12个LED呢?它们之间会不会相互影响呢?其实,这样的连接方式不仅能控制每个LED,还能控制其亮度呢!之所以能这样连接,是因为AVR单片机的每个I/O都是3态输出。如果用普通51单片机,这样连接是不行的。

那么又是如何控制LED的亮度呢?控制亮度的关键是ATtiny13的两路PWM,它们可以分别设置连接到PB0和PB1引脚上。在ATtiny13使用内部振荡器的情况下,PWM的最高频率可设置为47.5kHz。而且PWM的极性可以通过设置寄存器而改变,这使得12个LED亮度的控制更加简单了。

先谈谈如何控制每个LED单独的亮和灭。ATtiny13的每个I/O都有4种状态,即输出0状态、输出1状态、高阻态(悬空态)、带上拉电阻的高阻态。要使LED亮,必须要让LED中流过正向的电流,如果要让最左边的LED亮,PB1输出1、PB2输出0即可。但是,其他不相关的引脚需要设置成高阻态。否则,如果PB0此时也为1的话,第2个LED也会亮。总之,为了保证其他LED不受到影响,在设置某个灯亮时,必须先把所有I/O设置成不带上拉的高阻态。

能控制亮和灭有什么了不起?呵呵,其实还能控制每个LED单独的渐变,就是渐渐变亮,渐渐变暗。我举个例子吧,如果要最左边的LED渐渐变亮,就先设置PB2引脚为0电平,PB1引脚设置为高电平驱动的PWM波。然后,程序逐渐控制PB1的PWM状态,通过调整PWM高电平的脉宽长度来实现亮度控制。当PWM高电平的时间长时,LED就变亮了。反之,LED就变暗了。

那么电路原理图(见图6.2)中第7个反过来接的LED怎么实现亮度控制呢?原理还是一样,只是PB2将刚才的0电平设置成1电平,原来PB1为高电平脉冲驱动的PWM波设置成低电平脉冲驱动的PWM波即可。同样,要控制第7个LED的亮度,就控制PWM低电平的脉宽长度,当低电平的脉宽长度长时,LED就变亮了。反之,LED就变暗了。

图6.2 控制电路原理图

那么能实现所有的LED同时发光吗?制作过程中,这个功能的实现倒是困扰了我一会儿。后来,我想到了动态扫描。什么是动态扫描?老式电视机不就是这个原理吗?电视机通过磁场让射线高速地扫描屏幕,从而产生一幅画面。那么,让每个灯分别亮1ms左右,然后像电视机一样不断地扫描,看上去就都亮了。在此基础上,再控制每个灯的亮度数值,就能实现整体亮度控制了。如果LED足够多,单片机引脚也足够多,还可能显示一副灰度画面呢!

3种效果的程序编写

程序的PWM频率设置为最高的37.5kHz。之所以选择这么高的频率是为了不影响动态扫描。试想,如果PWM频率为100Hz,那么还怎么动态扫描呢?在程序中,动态扫描实际的频率为62Hz。这已经足够骗过人的眼睛,让我们看不到灯的闪烁。

在单片机的中断代码中,程序每过26µs就会产生溢出中断一次,通过变量count计数中断次数。当中断的次数达到50次时,就更换下一个LED,显示它对应的亮度。LED的亮度存储到led[ ]这个数组中,每个LED通过载入对应的亮度值,即通过改变PWM产生寄存器的OCR0A与OCR0B,来实际控制高低电平脉宽长度,最终实现亮度的控制。当然,每次通过PWM控制亮度,都要先根据LED的驱动电平方式,重新设置PWM的控制模式。在此之前,还要记得设置不相关的引脚为高阻态。

LED的3种效果控制程序能够实现LED不断地变换,只要调用就能分别实现如下功能:所有LED的呼吸效果、逐个点亮和熄灭LED、LED流水显示的效果。从编程的思路上讲,led[ ]数组存放了12个元素,每个元素所存内容,即对应每个LED灯亮度值。要改变某个LED灯亮度,都是通过设置led[ ]数组中对应元素的 PWM 缓冲数值来实现自动变换。要让所有的灯全亮只需设置数组中的每个元素的数值都为255即可。如果要一半的亮度就设置为128。要让某个灯单独最亮,只要设置这个LED元素数值为255,其他的元素为0。如果任意LED要产生渐渐变亮的效果,那么只要对应数组元素中的数值从0逐渐变为255即可。同理,渐渐变暗,数值就从255变成0。要实现什么样的效果,大家可以通过改变led[ ]数组来实现。

相关问答

单片机 电源灯不亮是什么原因?

原因一:连接问题要使单片机点亮LED灯,需要对单片机的引脚与外部电路进行正确的连接。如果电路连接错误或者电路中的接口松动,就会导致LED灯不亮或者无法正常...

51 单片机 ,有8个流水灯,每个之间延迟1秒,这个延迟用c程序编写怎么写?

1、用精确定时的方法,设置流水灯运行时的时间间隔,延时时间为500MS。2、#include"reg51.h"首先写出单片机的头函数。3、#include"int...

一个51 单片机 可以驱动多少 小灯 泡?

如果不进行外部扩展,40pin的正常51可控制32盏灯,p0到p3各8盏;如果不限制外部扩展,只要时间来得及,可以控制无限制的数量的灯、STC12-40P单片机有36个IO口,...

单片机的 io口电流大概10ma左右,如何让一个io口控制四个并联一起的led(同时亮灭)?

每个LED电流20mA?你为什么要那么大电流呢?不怕烧坏LED?好吧,不管你为什么用那么大的了,反正你不能把四个LED连接到IO口上,因为单片机IO口没那么大驱动能力.用...

单片机 接灯的时候为什么之间要加电阻?

单片机接灯时要加电阻,主要是为了限制电流。因为单片机的IO口输出的电流很小,而灯的电阻很小,如果直接接串联,会使电流很大,可能会烧坏单片机。而加上一个适...

单片机 流水灯为什么要串联电阻串多大的合适?

单片机流水灯需要串联电阻是为了限制电流,保护LED灯和单片机不受过大电流的损害。合适的串联电阻大小取决于LED的工作电压和单片机的输出电压,一般可以根据欧...

怎么用keil5做51 单片机 流水灯?

要用keil5做51单片机流水灯,首先需要创建一个新的工程,并选择合适的单片机型号。然后,在代码中定义需要使用的引脚,并编写流水灯控制程序。在编译和链接完成...

51 单片机 C程序实验LED灯:[1]单个灯闪烁?

单片机控制LED灯间隔时间闪烁,所用程序很简单,实际情况可作相应变化,也有多种方式实现。那么51单片机C程序实验LED灯:[1]单个灯闪烁?我们该怎么办呢?所需...单...

怎样利用 单片机 ,使用LED灯作通信指示灯,接收数据时以固定周期闪烁,无数据常亮?

一般收发信号是有一个位来控制的,判断这个位,让led执行命令就行一般收发信号是有一个位来控制的,判断这个位,让led执行命令就行

单片机 声控灯技术原理?

声控灯的工作原理:声控开关是由对声音敏感的电子元件和其他电子元件够成的,主要是靠外界发出的声音来控制电源,当外界声音达到多少额定的分贝时就会使电路导...

猜你喜欢