IO扩展芯片应用及方案选型 (74HC595,74HC165,8255,CH351等)
参考书籍《振南技术干货集:单片机–基础·进阶·创业·十年》作者:于振南
在我们进行单片机开发的时候, 经常会发现I/O 口不够用。 一方面是因为我们产品中往往都包括很多的功能, 又有显示, 又有存储等等; 另一方面是我们所使用的单片机芯片确实I/ O 资源不多。 有人说, 你可以选I/O 口比较多的芯片, 比如说把 STM32F103C8T6 换成同型号大封装的, 或者直接换 F407。 没错, 如果在成本允许的情况下, 确实是I/O 不够一换了之。但成本往往是需要考虑的首要因素。 越是上量的产品, 就越是对成本敏感。 尤其是2020 年前后这几年芯片严重短缺, 新冠病毒的国际大流行和美国芯片法案是最重要因素。 这导致很多存量芯片的价格飞涨, 那些不常用的、 高端的芯片价格更是离谱, 而且不好买。 在这种特殊的背景下, 我们会尽量用中低端的、 常用的、 市场存量大、 交货周期短的芯片。 这个时候, 我们去自己通过廉价的方案扩展出一些必要的硬件资源, 就显得更加迎合时宜了。
振南写这一章做足了功课, 花了大量精力收集了市面上主要的一些I/O 扩展方案,同时不乏创新性。通过网页链接进行学习:》》》 振南技术干货集 《《《
1. 基于74 系列芯片的廉价方案
用惯了各种高大上的芯片, 似乎我们已经忘记了那些基础简单而又极为重要的芯片, 比如74 系列芯片。 我认为芯片没有低高端之分, 只有是否用得好之别。
1.1 并行输出端口扩展
回想我们使用8 位单片机的时候, 比如51 、AVR、PIC 等, 它们的I/O 端口是8 位的。 但是很多器件是16 位接口的, 比如一些液晶屏, 或是存储器。 此时我们一般会把两个I/O 端口拼起来, 形成16 位。 但前提是我们的I/O 比较富裕。 如果只剩下一个I/O 端口了, 那怎么办? 我们可以使用74HC573 、74HC373 这类的锁存芯片, 请看图5.1 。
对于74HC573 想必大家都比较熟悉了, 振南就不赘述了。 这里简单介绍一下上图的操作逻辑。 单片机首先通过8 位I/O 端口输出16 位的高字节ByteH, 同时将 OE 置低,LE 由低置高, 这样 ByteH 就被锁存输出到了 Dout(锁存后的 Dout 不会再随 Din 变化而变化)。 然后单片机再将8 位端口输出16 位的低字节 ByteL,[ByteH ByteL]就拼成了16 位输出。
这算是I/O 扩展的最基础、 最常用的方法。 大家可以回想一下 51 单片机是如何扩展SRAM 的, 比如62256 之类的芯片。 对, 它就是使用了一片8 位锁存芯片, 由 P0 来产生访存地址的低8 位(P2 产生高8 位), 请看图5.2。
简单描述:51 单片机为了节省引脚, 在外部访存中对 P0 进行了复用。 P0 首先输出16 位地址的低8 位 A0~A7, 其通过锁存由8 位锁存器输出, 其与 P2 输出的高8 位 A8~A15 共同形成了16 位访存地址。 随后P0 将要写入到外部存储器的8 位数据从P0 输出, 在#WE 信号的作用下, 数据被写入到相应地址单元中。 这是一个xdata uint8 数据赋值操作单片机在背后所产生的一系列动作, 当然这些时序都是它自动产生的, 属于 CPU 的访存原子操作。
是不是现在很多初学者已经对51 单片机不太熟悉了? 而是直接使用STM32 来入门, 那上面的这个例子, 对这些人来说可能就不好理解了。
有人问“那我想扩展出32 个I/O 怎么做呢?”如法炮制, 请看图5.3 。
那是不是我们可以通过这种堆砌74HC573 的方法, 扩展出无限的I/O? 理论上是的, 但实际上需要考虑器件的负载能力, 一般来说 CMOS 电路可同时接8 个负载。
除了8 位锁存器, 还有16 位锁存器, 比如74ALVCH162373 , 芯片示意如图5.4 所示。
乍一看, 像条蜈蚣一样, 一共有48 个引脚。 可以看到, 它有两个8 位输入端口1D1~1D8 2D1~2D8, 两个8 位输出端口1Q1~1Q8 2Q1~2Q8, 同时还有两个#OE 和两个 LE。 通过它我们可以把16 位I/O 端口, 扩展为32 位。 其实这一芯片比较小众, 需要32 位端口的应用场景并不多。 什么? 驱动大量LED 或数码管? OK, 这算一个。 但实际上这种应用场景下, 使用这种方案来扩展I/O 也并不可取。 因为它需要单片机能够先提供16 个I/O 出来, 而这在I/O 资源本就很拮据的前提下, 显然是困难的。
通常我们会使用8 位锁存器+ 译码器的方式来实现。 原理很简单, 用译码器的输出作为8 位锁存器的锁存信号, 如图5.5 所示。
关于原理振南就不再赘述了, 大家应该都明白。 另外关于译码器, 我们常用的是74HC138,3-8 译码器, 上图中就是。 其实还有更多路的译码器, 比如CD54HC154, 它是4 16 译码器。 使用译码器, 或者称数据选择器, 可以适当减少在并行I/O 扩展过程中所需要额外分配的I/O 数量(如果不用译码器, 每增加一片74HC573 就需要多拿出一个I/O 来控制其LE)。
1.2 串行输出端口扩展
上面介绍了一些并行输出端口扩展的方法, 可能有一些读者有这样的疑问:“你这有点押注的感觉, 要想得到, 先得搭进去一些, 如果我单片机连8 个I/O 都不剩了, 那怎么办?”可以用串行扩展方式, 如图5.6 所示。
大家对74HC595 应该很了解了, 它是串行转8 位并行的位移缓存器, 也称移位寄存器。它最大的特点就是支持菊花链(daisy chain)。 仔细观察图5.6 , 可以看到74HC595 除了8 位并行输出之外, 还有一个 Q7’, 它可以连接到下一个74HC595 的 DS 上, 这样串行数据位就可以在时钟SHCP 的作用下, 像流水一样贯穿多片74HC595 。 有了这一机制, 理论上我们就可以仅用 3 个 I/O 扩 展 出 无 数 的 输 出 端 口 来。 同 样 的, 也 有 16 位 的 串 转 并 芯 片, 比 如NJU3716 , 但也属于小众芯片。
我们在作产品研发的时候, 在器件选型方面要考虑它的功能性能是否满足我们的设计需要, 同时还要考虑器件的可替代性和供应链的情况。 一要使用主流的, 最好有多个厂商都生产的芯片, 比如74 系列芯片, 作为最基础的入门电路, 欧森美、TI、NXP 等厂商都在生产; 再比如这几年炒得沸沸扬扬的STM32, 它不光有 ST 在生产, 相关的兼容型号也有很多其他厂商在生产, 比如国内的兆易创新生产的 GD32 系列、 国民技术的 N32 系列、 灵动微的 MM32 系列、艾派克的 APM32 系列等等, 这样就使得用 STM32 设计产品比较安全。 因为兼容型号很多,市场存量非常大, 这样就算在半导体极端行情的背景下, 我们产品的物料元件也不至于断供。
同时, 尽量使用最畅销, 最常用的型号, 比如STM32F103。 因为在极端情况下, 半导体厂商会削减产能, 把有限的生产能力放到那些出货量最大的型号上。 所以, 在我看来, 那些高端的芯片, 比如STM32L/F4、H7 系列都是有风险的。 还有不要使用特异封装, 比如 VFQFPN、 WLCSP、UFBGA 等。 一方面是这些特异封装用量小, 特殊时期可能因为厂商减产采购不到, 就算能采购到, 交货周期也会很长。 另一方面, 这些封装都需要比较高的加工焊接工艺, 能接单的板家比较少, 而且周期长, 次品率高。 不要一味地猎奇, 或者过分的在意电路尺寸, 给自己制造麻烦。
说了这么多, 可能很多人还是认识不深刻, 容易被正常时期的供应链充沛状态所蒙蔽。 说两个活生生的例子。 在很久以前, 有一款单片机非常流行, 知名度非常高, 性能也比同期的其他芯片要高。 基于它, 国内外的工程师开发和发布了很多优秀的硬件开源项目和商业产品, 甚至有人在用它作音视频编解码、 图像识别、 跑 Linux。 对, 它就是 AVR, Atmel 的当家花旦, 就如同 Microchip 的PIC,SiliconLab 的C8051F 一样的历史地位。 但是在2015 年前后,AVR 的供货急转直下, 甚至一片难求。 究其原因应该是 Atmel 与 Microchip 的并购导致的市场动荡。用 Atmel 自己的话说是: 原因在于这一收购案过程的不确定性, 导致经销商降低库存水位, 特别是在亚洲地区。 这样的芯片短缺状态持续了2 年左右, 导致大量的 AVR 用户不得不转向其他芯片。 一方面是供货周期过长, 另一方面是因为经销商惜售而造成的高价格。 又鉴于当时STM32 以及很多国产 8 位 MCU 已经崛起, 从而使得 AVR 惨遭抛弃。 昔 日 那 些 基 于AVR 的开源项目和社区论坛, 比如国内比较有名的ourAVR 就此没落, 从而开始寻求综合化论坛的发展路径, 也因此改名为ourDEV。
另一个例子是发生在我身上的。 前面我说过, 有好几年我一直在做智能传感器。 因为涉及的产品非常多, 有加速度、倾角、温度、 应变等等, 所以我所带领的硬件团队考虑做一个通用的核心板, 而把通信和采集做成模块, 方便插接集成和复用, 希望通过这种模块化的架构来提高整体的研发效率(详细的内容可以去看“硬件研发半个月出产品, 我做到了!”一章)。 核心板主芯片选型时, 考虑到尽量把PCB 做小, 以便可以直接利用现有的外壳, 以及为电池留出更多的空间。 我们最终选定了STM32L452RET6 UFBGA 封装(一种pitch 非常小的BGA 封装), 如图5.7所示。
产品不断上量, 困境也随之而来。 先不说 UFBGA 的高加工费, 当然加工费可以用产品批量均摊掉。 随着2019 年年末席卷而来的新冠疫情, 因ST 芯片产能的限制, 整个STM32 的供应链出现了很大的问题。 供应链团队是直接向ST 原厂订货的, 周期已经排到了2 年以后, 而且能排上已经是谢天谢地了。 而2019~2020 年正处于公司 B 轮融资的极速扩张期, 大量的项目订单纷至沓来, 而库存芯片仅有1000 多片, 一个项目就可能倾数耗尽。 起初尝试向兆易创新咨询是否有替代型号, 但是 L452 这款芯片并不常用, 无果而终。 最后逼得没有办法, 开始替换为STM32L452REY6 , 其封装为 WLCSP, 它的pitch 更小, 加工焊接需要的工艺更高。但是我们确实发现这一封装的市场存量比较大, 可以支撑产品渡过困难期。 我考虑, 就是因为这种封装不易焊接, 才作为库存一直压在经销商手上。
经过这些事情, 一改我对供应链的观念。 以前我对供应链的认识就是买买买, 但实际上并没那么简单。 它直接关系到我们的研发成果是否有实际批量意义。 因为某个关键器件供货出问题, 而不得不整体改版的事情我见得太多了, 所以请大家一定要谨慎选型。
关于74HC595 可能有人会问:“串转并, 那速度不会很慢吗?”并行一定比串行快, 这是一个认知误区。 其实串行比并行更加稳定, 而且速度不慢。 这也是现在串行总线大行其道的原因, 比如 USB、SATA 等。 我们可以用硬件 SPI 向 74HC595 写入数据, 串行时钟可以达到10MHz, 这样转为并行, 也有1MBps 的数据速率了。 这对于一般的应用是足够了。 如果你非要用级联几百个74HC595 去驱动 LED 大屏, 还要实现显示特效的话, 我们就需要性能更高、速度更快的控制器了(大多使用专门的 ASIC 芯片或 FPGA)。 74HC595 的时钟频率支持到100Mhz 是没有问题的。
1.3 并行输入端口扩展
前面我们介绍的都是输出端口扩展, 输入也同样重要。 我们可以使用数据选择器来实现。请看图5.8。
图5.8 中 D00~D70 是一个8 位并行输入端口,D01~D71 是第二个端口。 单片机通过控制数据选择引脚SEL, 来切换两个输入端口。 如果要扩展更多的端口, 可以使用更多路的数据选择器, 比如4 选1 或8 选1 。
OK, 同样的套路, 我们来看看如果通过串行方式来扩展并行输入端口。
1.4 串行输入端口扩展
74HC595 是数据串行输入, 并行输出。 那是否有芯片可以实现数据并行输入, 串行输出呢? 当然有,74HC165 , 而且它也支持菊花链。 来看一下它的脚引分布, 如图5.9 所示。
D0~D7 是8 位并行输入,DS 与 CP 是串行数据与时钟, #PL 是数据装载, 它为低电平时D0~D7 输入状态将被读入到内部的移位寄存器中。 Q7 这个引脚很重要, 它是移位寄存器的输出, 通过它我们就可以实现菊花链级联, 如图5.10 所示。
以上振南介绍了输出端口与输入端口的扩展方法, 但它们单独拿出来都算不上是I/O 扩展, 因为它们只能输出或输入。 那如何实现可以输出同时又能输入的真正意义上的I/O 扩展呢? 很简单把输出和输入端口拼在一起就行了。 但是要注意一点, 当它用于输入的时候, 输出端口要保持高阻状态。 拿74HC595+74HC165 这样的组合来说, 当使用74HC165 读取并行数据的时候,74HC595 要将#OE 拉高, 使其输出呈现高阻态。 否则, 它会影响74HC165 的电平读取。
有人还是在顾虑串行速率的问题“我用51 单片机, 没有硬件 SPI, 只能用I/O 模拟, 怎么让串转并速度快一些?”既然你使用这么古老的51 芯片(STC51 基本上都支持硬件 SPI, 但是如果51 芯片过于古老, 那确实没有硬件SPI), 还奢求速度? 好吧。 51 单片机有一个被很多人忽视的功能, 即 UART 的 模 式 0, 它 就 是 一 种 硬 件 同 步 串 行 接 口, 大 家 可 以 去 了 解 一 下(UART 的0 模式可以用来充当硬件SPI)。
2. 基于专门I/O 扩展芯片的方案
使用74 系列芯片固然成本低, 而且安全, 但是它有一个很大的问题, 比较占用 PCB 面积。一个板子, 放眼望去有很多片74 芯片, 这无形之中拉低了板子的档次。 I/O 短缺其实是行业内一个很常见的问题, 因此芯片厂商专门研发了一些I/O 扩展芯片。 它们功能丰富, 集成度高, 同时价格可控, 对于一些成本不是极为严苛的项目和产品, 不失为是终极解决方案。
以下的讲解振南不会去细述芯片的具体使用方法, 只会简单介绍其主要功能, 因为复述芯片手册是一件毫无营养的事情。 振南主要进行一些芯片的推荐, 大家可以依自己的实际情况灵活选型。
2.1 并行I/O 扩展芯片
这一类的专用芯片不多, 我仅以我知道的说一下。
1. 8255
8255 是一个代号, 或者说别称, 它不是芯片型号, 而是指与之兼容的由不同厂家生产的多个型号, 如图5.11 所示。
8255 是一个功能强大而又古老的芯片(振南曾经在一些比较老型号的打印机中见到过应用), 最初由Intel 开发, 基本与8051 是同时代的产品。 它有多种工作模式, 我们这里仅介绍其最简单最常用的一种, 即模式0。
先来看一下8255 的引脚分布, 如图5.12 所示。
D0~D7 是8 位输入输出端口, 用于与单片机连接, 以实现对内部寄存器的读写。 PA、PB和 PC 为3 个8 位输入输出端口, 即扩展端口。 A1 A0 是两位的地址码, 用于寄存器寻址, 所以8255 有4 个寄存器, 分别是 PA、PB 和 PC 的数据寄存器, 和控制寄存器。
我们先来看一下8255 的基本操作, 如图5.13 所示。
控制寄存器是比较重要的寄存器, 通过它我们可以设置扩展端口的工作模式、 输入输出方向等, 如图5.14 所示。
比起现在芯片动辄几百个寄存器,8255 相对要简单多了。 如图5.15 所示, 从控制寄存器的定义中可以看到,PC 端口被砍成了两段 UPPER 与 LOWER, 分别为4 位, 可以单独设置它们的方向。 而且更强大的是,PC 端口是支持位操作的, 置位或者清零, 类似于51 单片机sbit位寻址或者是STM32 的bitband 位带。
这样的设计非常实用。 我们在使用I/O 端口进行数据读写的时候, 通常还要配有相应的控制信号, 比如8080 总线除了数据线还有控制线#RD 和#WR。 所以PC 口就可以充当控制线, 位控制可以提供执行效率。
关于8255 更多的功能, 大家可以去它的数据手册。
哪里可以找到它的数据手册? 官网、21icsearch、alldatasheet、 百度。
2. CH351
前面说过8255 是比较老的芯片, 实际上现在可能也不太好买, 而且市面上散料比较多(所谓散料就是拆机件)。 我再推荐一款芯片 CH351 , 来自于南京沁恒。 对于这个公司大家应该比较熟悉, 起码有所耳闻。 它主要是研发接口扩展、 转换、 桥接这一类的芯片。 最有名的, 也是用量最大的就是他的CH341(USB 转 TTL 串口桥接芯片)。 有必要跟大家说一下国内的几个我们经常用到的芯片和器件供应商及其代表产品, 如表5.1 所列。
可以看到国内半导体产业其实并不弱, 不管是研发设计, 还是晶圆生产封装测试, 整个产业链是很完整的。 平时大家说的中国芯片落后是指高端和尖端的芯片设计和制造, 其实一般性的芯片, 比如汽车、 功率器件等等自给自足是完全没有问题的。 一定要对国产器件有信心,选型多选国产, 因为自己的才是最安全的。
CH351 可以扩展出32 个I/O, 请看图5.16 。
具体的使用方法振南就不赘述了, 大家可以到沁恒官网去下载芯片手册。
2.2 串行I/O 扩展芯片
串行I/O 扩展芯片是I/O 扩展的主流方案, 它最大的优势是使用极少的I/O 即可扩展出大量I/O, 而且集成度高, 性价比高。 按照所使用的串行接口, 振南对这些芯片进行罗列, 请看表5.2。
其中 TCA9555 有非常多的兼容型号, 比如 PCA9555 、AT9555 、XL9555 、NCA9555 等等。
上面只是罗列了常见的一些串行I/O 扩展芯片, 实际市面上的芯片种类要比这里看到的要多得多。 可见,I/O 扩展是业内的一个普遍问题, 各大芯片厂商都有自己的方案, 但其实它们都是大同小异。 具体哪一款适合你, 大家可以根据自己的产品功能与成本需求进行选型。
除了这些专用IC, 其实还有人用 CPLD 或 FPGA 器件来实现I/O 扩展, 也是一种很好的方案, 因为它具有很好的灵活性。 而且现在FPGA 这块也不是老美 Xilinx 和 Altera 独揽的局面, 很多国产 FPGA 具有很高的性价比, 比如 AGM 系列、 安路 FPGA 系列等。 同时, 在可编程逻辑器件这方面, 有一个比较新的概念 CIMC, 即可编程混合信号芯片, 感兴趣的读者可以关注一下, 据说性价比巨高。
3. 文章参考
参考书籍《振南技术干货集:单片机–基础·进阶·创业·十年》作者:于振南
以上内容来自于振南老师的课程,可以扫码注册官网账号,来进行学习。还有更多的嵌入式C语言教程,以及RTOS架构双体系课程,帮助于从入门到精通FreeRTOS,另外振南老师还是znFAT嵌入式文件系统的开源贡献者,在国内有非常高的声望。通过下述| 二 | 维 | 码 即可注册网站。或通过网页链接进行学习:》》》 振南技术干货集 《《《