例如,如果您有一个带有 4 个数字 IO 引脚的 Arduino,您如何独立点亮 > 4 个 LED,或读取 > 4 个按钮的状态?
当 IO 在 uC 上受限时,如何将逻辑从 uC 移开?
布鲁诺给出了一个很好的答案,但我想做一些笔记。
臭名昭著的70 mA 74HC595通常用作 I/O 扩展,并经常用于控制一系列 LED。经常被忽视的是,您可能会以这种方式操作它超出规范。数据表显示总电源电流不应超过 70 mA,即绝对最大额定值 (AMR),因此您最好远离该值。因此 10 mA 时 8 个 LED 太多了,而在 20 mA 时,您将超过 AMR 不少于 130 %!限制可能是由于键合线的电流容量,然后过高的电流可能不仅会降低零件的性能,而且如果该线断裂,则会永久性地使其无法正常工作。
但是昨晚我醒了,因为我有了一个想法。70 mA 限制适用于 Icc 和接地电流,那么为什么不将我们的总电流或 80 mA 分开,让 Icc 占一半,接地电流占另一半呢?您所要做的就是将 4 个 LED 接地(高电平有效),将另外 4 个 LED 接地(低电平有效)。然后前者的电流来自Icc,其他的电流接地。您将能够以这种方式使用 15 mA LED。(这太简单了,我觉得自己像个白痴一样没有早点想到它。)
组合时钟
我认为布鲁诺通过将移位寄存器的时钟与锁存器的时钟组合起来节省了一个额外的 I/O 引脚。似乎我误解了他的回答。我仍然想扩展这个选项。
那会发生什么?数据表第 5 页上的表格显示:
移位寄存器的内容被移过;移位寄存器的先前内容被传送到存储寄存器和并行输出级
(由我突出显示)
所以不是新数据而是先前被锁存的数据。这不是一个真正的问题,只需确保移入一个额外的虚拟位以锁存最后的数据,否则一切都会是一个引脚错误。
结合时钟还意味着在您将新数据移入时,输出将一直切换。锁存器的功能实际上是为了避免这种情况。在许多情况下,如果你能快速做到这一点,这不会是一个问题,但在最坏的情况下,你可能会得到不希望的效果。最坏的情况可能是使用 74HC595 以非常高的扫描频率对显示器进行多路复用 + 具有非常长的移位寄存器链 + 除了一个 0 之外的所有 1,一个关闭的 LED + 一个黑暗的房间。由于该 LED 在黑暗的房间中经常看到所有 1 的通过,因此它可能会非常微弱地亮起。
或者,如果您将高频多路复用与继电器控制输出相结合。继电器全为零,然后是 1,这可能意味着继电器的输出不够长,无法吸合。
当然,这些都是极端情况,但如果您想多路复用或以其他方式具有高更新率,我会尽可能将串行时钟和锁存时钟分开。
我同意 Ignacio 关于使用 74XX595、串行并行输出移位寄存器进行输出扩展的观点,但实际上您需要 3 个连接,一个用于数据,一个用于时钟,一个用于锁存器使能,用于从内部移位寄存器传输数据到输出锁存器。
对于输入的扩展,您可以使用 74XX165,并行输入串行输出移位寄存器,这将允许每个 74XX165 最多有 8 个按钮。
这种方法的好处是您可以菊花链式连接多个移位寄存器,从而增加输入或输出的数量,更好的是,您可以混合使用 74XX595 和 74XX165,从而获得任意数量的输入或输出。
除此之外,您可以共享时钟和锁存信号,从而减少所需的连接数量并大大简化软件。这样,对于任意数量的任何移位寄存器,您只需要 4 个连接:
- 时钟(与所有移位寄存器共享)
- 锁存器使能(与所有移位寄存器共享)
- 数据输入(连接到链中最后一个移位寄存器的串行输出)
- 数据输出(连接到链中第一个移位寄存器的串行输入)
编辑
当我在搜索图表时,我在这个网站上发现了一种非常聪明的方法,可以将所需的连接数量减少到 3 个。它包括使用相同的引脚进行数据输入和输出。
该软件将对每个时钟脉冲执行以下操作:
- 将引脚配置为输出
- 设置数据值
- 发送时钟脉冲
- 将引脚配置为输入
- 读取数据
Nick 提到了 I/O 扩展器,它们绝对值得研究。Digikey 列出了一千多个,我会选择一个带有 I2C 接口的作为示例,因为它需要最少的 I/O 引脚;最少两个。
NXP PCA9505有 40 个可配置 I/O 引脚,相当于 5 个 74HC595。这是一个稍微昂贵的解决方案,但您可以获得更多功能:
- 任何 I/O 引脚均可配置为输入或输出
- 所有 I/O 引脚上的 100 kΩ 上拉电阻(PCA9506 没有上拉电阻,这可能与低功耗应用有关)
- 所有输出可同时灌入 15 mA,封装总电流为 600 mA
- 变化时中断输出使连续扫描输入变得多余
- 只有两条线连接到微控制器。
进一步阅读
GPIO 扩展器,NXP 手册
PCA9505 数据表
诸如74595之类的移位寄存器将允许您通过 2 个连接来获得多个输出:一个数据引脚和一个时钟引脚。您将数据引脚设置为要移入寄存器的下一个值,然后脉冲时钟引脚。