本文隶属于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上,我们来实现一个略微复杂(相比之前)的效果:红,红+绿,绿,绿+蓝,蓝,蓝+红;然后重复,只是加上白色;循环。

 #include <ee1/pin.h>
#include <ee1/delay.h> #define RED PIN_4
#define GREEN PIN_5
#define BLUE PIN_6
#define WHITE PIN_7 void rgb_cycle()
{
for (uint8_t i = ; i != ; ++i)
{
pin_write(RED , i == || i == || i == );
pin_write(GREEN, i == || i == || i == );
pin_write(BLUE , i == || i == || i == );
delay();
}
} int main()
{
uint8_t pins[] = {RED, GREEN, BLUE, WHITE};
for (uint8_t i = ; i != sizeof(pins) / sizeof(pins[]); ++i)
pin_mode(pins[i], OUTPUT);
while ()
{
pin_write(WHITE, false);
rgb_cycle();
pin_write(WHITE, true);
rgb_cycle();
}
}

这段代码虽然略长,但还是比较容易理解的:rgb_cycle 即为6种状态的枚举,包含了延时;main 函数中,先初始化,然后进入主循环;每一遍循环中先控制白色灯,然后调用 rgb_cycle ,对于白色灯的两种状态调用两次;整体效果的循环周期为12次改变。

另外,你也许已经发现,对于数字输入的引脚,即使没有调用 pin_mode 来配置模式,也能正常检测输入。这是因为输入是单片机复位后默认的设置。那么,对于输出来说,就必须调用 pin_mode 将引脚配置为输出模式。如果没有将引脚配置为输出而写高电平会怎样?自己试试吧。原因我们以后分析。

由于今天的教程非常简单,就没有作业了。复习一下之前的内容,下一篇教程会比较难。

AVR单片机教程——数字输出的更多相关文章

  1. AVR单片机教程——数码管

    先解答之前一个思考题:如果不把引脚配置为输出而写高电平,连接LED会怎样? 实验结果是,LED会亮,但相比于输出高电平的情况,亮度很低.这是为什么呢? 通过上一篇教程我们知道,引脚输入输出模式是由寄存 ...

  2. AVR单片机教程——旋转编码器

    好久没写这个系列了.今天讲讲旋转编码器. 旋转编码器好像不是单片机玩家很常用的器件,但是我们的开发板上有,原因如下: 旋转编码器挺好用的.电位器能旋转的角度有限,旋转编码器可以无限圈旋转:旋转时不连续 ...

  3. AVR单片机教程——数字输入

    我们已经学习了如何使用按键和拨动开关,不知你有没有好奇 button_down 和 switch_status 等函数是如何实现的.本篇教程带你一探究竟,让我们从按键的原理开始. 在原理图中,按键的符 ...

  4. AVR单片机教程——拨动开关

    在按键的上方有4个拨动开关.开关与按键,在原理和使用方法上都是很类似的,但有不同的用途——按键按下后松开就会弹起,而开关可以保存其状态. <switch.h> 定义了与开关相关的函数.sw ...

  5. AVR单片机教程——按键动作

    上一篇教程中我们学习了如何读取按键状态.而按键的动作,比如单击,至少需要两个状态才能判定,长按.双击的判定更加复杂.今天我们来学习如何使用库函数判断按键单击,以及其实现原理. 我们要实现的是:当一个按 ...

  6. AVR单片机教程——按键状态

    好久没更新了,今天开始继续,争取日更. 今天我们来讲按键.开发板的右下角有4个按键,按下会有明显的“咔嗒”声.如何检测按键是否被按下呢?首先要把按键或直接或间接地连接到单片机上.与之前使用的4个LED ...

  7. AVR单片机教程——随机点亮LED

    之前我们做的闪烁LED和流水灯,灯效都是循环的.这次我们来尝试一些不一样的——每一次随机选择一个LED并点亮. 要实现随机的效果,我们要用C语言标准库中的相关设施: #define RAND_MAX ...

  8. AVR单片机教程——流水灯

    上次我们用 delay 函数与 while 循环实现了一个LED的闪烁.这一次我们把所有LED加入进来,让它们依次闪烁,形成流水灯的效果. 开发板上有4个LED,我们可以用不多的语句把循环体直接描述出 ...

  9. AVR单片机教程——闪烁LED

    上次我们把LED点亮了.你可能已经试过把 LED_RED 换成其他灯,也可能已经用 led_on() 把所有LED一起点亮了.但是LED点亮以后,程序就退出了,之后LED一直没有暗,直到没有供电.这一 ...

随机推荐

  1. 【luoguP2371】 [国家集训队]墨墨的等式

    题目链接 考虑将所有的\(a_1x_1+a_2x_2+--+a_nx_n=B\)对\(a_1\)取模,那么所有可达到的B就分为了\(0\)~\(a_1-1\)类 如果对\(a_1\)取模为\(k\)的 ...

  2. 百度编辑器(ueditor)踩坑,图片转存无法使用

    在使用 百度编辑器 的过程中碰到了一些问题,图片转存功能无法使用, 即便是疯狂地在官方 Demo.文档.论坛甚至是 GitHub 上也没找到理想的答案.(┗|`O′|┛) (真是日了狗) 问题描述 默 ...

  3. Java_jdbc 基础笔记之六 数据库连接 (PreparedStatement)

    reparedStatement 是 Statement 的子接口 * ①需要预编译 SQL 语句:PreparedStatement ps = conn.preparedStatement(sql) ...

  4. semi-join子查询优化 -- LooseScan策略

    LooseScan执行semi-join子查询的一种策略. 我们将通过示例来演示这种松散(LooseScan)策略.假设,我们正在查找拥有卫星的国家.我们可以通过以下查询获得它们(为了简单起见,我们忽 ...

  5. firewall防火墙常用操作

    # firewall防火墙常用操作 - 启动```systemctl start firewalld```- 停止```systemctl stop firewalld```- 重启```system ...

  6. 运维笔记--linux环境提示python: command not found

    场景描述: 新部署的容器环境,终端执行python命令,提示没有该命令. 从报错异常可以看出,可能是python环境未安装. 分析思路: 检查python路径: 方式一:type -a python ...

  7. win10找不到hosts文件(设置显示隐藏文件也找不到)解决方法

    Win10系统中的Hosts文件有很多作用,屏蔽网址,指定解析,跳转等等,所以我们经常会通过编辑Hosts文件来达成一些目的,一般来说hosts文件是隐藏的,我们需要显示受保护的文件才可以,但是有一些 ...

  8. 安卓 android studio 报错 The specified Android SDK Build Tools version (27.0.3) is ignored, as it is below the minimum supported version (28.0.3) for Android Gradle

    今天将项目迁移到另一台笔记本,进行build出现以下问题,导致build失败 报错截图: 大致意思,目前使用的build工具版本27.0.3不合适.因为当前使用Gradle插件版本是3.2.1,这个版 ...

  9. iOS - 点击按钮实现简单的复制功能

    UIPasteboard使用 基本使用: - (void)copyClick { UIPasteboard *pab = [UIPasteboard generalPasteboard]; pab.s ...

  10. Linux中添加新硬盘后对硬盘的分区以及挂载

    转自:https://www.linuxidc.com/Linux/2018-06/152958.htm 我将使用VM来进行模拟 先使用df看下我的电脑硬盘信息: df -h 可以看到只有一个sda1 ...