AVR单片机教程——数字输出
本文隶属于AVR单片机教程系列。
从上一篇教程中我们了解到,按键与开关的输入本质上就是数字信号的读取。这一篇教程要讲的是,控制LED的原理是数字信号的输出。数字IO是单片机编程之有别于桌面编程的各项内容中最简单、最基础的。
在讲数字信号输出之前,我们先来了解一下它控制的器件。LED,是一种二极管,在理想模型中,加以正向电压会发光,反向电压则不会。在稍微实际一点的模型中,当正向电压超过一定阈值时,二极管会发光,其电流会随着正向电压的增大而急剧增大;对反向电压的耐受力也是有限的。现实中的LED的具体参数因生产厂家而异,一般红色与黄色LED的导通压降为2V多,绿、蓝、白色的为3V左右或多一点;反向耐压一般为5V。
电流大到一定程度,任何器件都会烧毁,我们最好要把LED的电压控制在比导通压降高一点,但直接获得这样的电压比较困难,而且与LED的参数和温度等都是相关的。一种方案是用电流源来驱动LED,但由于现代计算机,包括单片机,都以电压方式来工作,在控制亮暗这种简单应用中一般不会使用(大功率LED一般有专用的恒流电源来驱动)。常见的方案是将LED与一个电阻串联。这个电阻能保证LED的电流不太大,因此称为限流电阻。至于这种接法下电流是多少,可以通过“负载线”来求得。本系列教程不会专门讲电路,你可以自己搜索相关知识,早晚会用到的。
早期的单片机设计中,一般把LED和电阻接在引脚和正电源之间,这是因为TTL的拉电流能力强而灌电流能力很弱,只能这样接。CMOS工艺的单片机不必在意这一点,由于我们习惯让1代表有而0代表无,因此一般将LED与电阻接在引脚与地之间。电阻接在LED的正极还是负极是无所谓的。
以上都是对单个LED而言的。对于一些多色LED,比如RGB的,各个单色光源的一极是接在一起的,以节省引脚。当正极接在一起时,称为共阳接法:
为了亮度均匀,需要为每个LED接一个限流电阻(阻值一般不同),这时电阻就必须接在LED负极上了,然后再连接单片机引脚,而LED的另一端则连接正电源。引脚输出低电平会让对应颜色亮起。
当负极接在一起时,称为共阴接法:
LED的两极称为正极负极,接法称为共阳和共阴,都是习惯而已,不必纠结其中的不一致性。
我们的开发板上有一颗RGBW的LED,4种颜色的LED都有独立的正负极,但我把它们的负极都接到了地,可以理解为共阴接法。LED右边的4个针脚分别连接电阻,然后再连接LED的正极。因此,连接单片机引脚和LED的针脚后,使引脚输出高电平能让LED亮,反之则不亮。
将引脚4~7分别连接到RGBW上,我们来实现一个略微复杂(相比之前)的效果:红,红+绿,绿,绿+蓝,蓝,蓝+红;然后重复,只是加上白色;循环。
1 #include <ee1/pin.h> 2 #include <ee1/delay.h> 3 4 #define RED PIN_4 5 #define GREEN PIN_5 6 #define BLUE PIN_6 7 #define WHITE PIN_7 8 9 void rgb_cycle() 10 { 11 for (uint8_t i = 0; i != 6; ++i) 12 { 13 pin_write(RED , i == 5 || i == 0 || i == 1); 14 pin_write(GREEN, i == 1 || i == 2 || i == 3); 15 pin_write(BLUE , i == 3 || i == 4 || i == 5); 16 delay(500); 17 } 18 } 19 20 int main() 21 { 22 uint8_t pins[] = {RED, GREEN, BLUE, WHITE}; 23 for (uint8_t i = 0; i != sizeof(pins) / sizeof(pins[0]); ++i) 24 pin_mode(pins[i], OUTPUT); 25 while (1) 26 { 27 pin_write(WHITE, false); 28 rgb_cycle(); 29 pin_write(WHITE, true); 30 rgb_cycle(); 31 } 32 }
这段代码虽然略长,但还是比较容易理解的:rgb_cycle 即为6种状态的枚举,包含了延时;main 函数中,先初始化,然后进入主循环;每一遍循环中先控制白色灯,然后调用 rgb_cycle ,对于白色灯的两种状态调用两次;整体效果的循环周期为12次改变。
另外,你也许已经发现,对于数字输入的引脚,即使没有调用 pin_mode 来配置模式,也能正常检测输入。这是因为输入是单片机复位后默认的设置。那么,对于输出来说,就必须调用 pin_mode 将引脚配置为输出模式。如果没有将引脚配置为输出而写高电平会怎样?自己试试吧。原因我们以后分析。
由于今天的教程非常简单,就没有作业了。复习一下之前的内容,下一篇教程会比较难。
posted on 2019-09-29 00:11 Jerry_SJTU 阅读(1167) 评论(0) 编辑 收藏 举报