4、硬件接口设计:MCU与Flash的硬件连接、电平匹配(3.3V vs 1.8V)、去耦电容与PCB布局建议、信号完整性注意事项
好,咱们这一章聊硬件接口。说实话,很多做驱动的朋友觉得硬件是硬件工程师的事,自己只管写代码。但我个人的经验是——不懂硬件连接的驱动工程师,迟早要踩坑。你想想看,Flash读写不稳定,有时候不是代码问题,而是你的SPI信号本身就歪了。
4.1 MCU与Flash的硬件连接:标准四线制
SPI NOR Flash的硬件连接,说白了就四根线加一根片选。我列个标准接法给你看:
| Flash引脚 | MCU引脚 | 说明 |
|---|---|---|
| CS# | GPIO / SPI_NSS | 片选,低电平有效 |
| SCLK | SPI_SCK | 时钟,由Master提供 |
| SI (MOSI) | SPI_MOSI | 主机输出,从机输入 |
| SO (MISO) | SPI_MISO | 主机输入,从机输出 |
| WP# | VCC 或 GPIO | 写保护,建议拉高 |
| HOLD# | VCC 或 GPIO | 保持,建议拉高 |
| VCC | 电源 | 供电引脚 |
| GND | 地 | 共地 |
这里有个细节我要强调一下:WP#和HOLD#这两个引脚,很多人直接悬空。我在项目中遇到过,悬空导致Flash莫名其妙进入保护模式,写操作死活不成功。我的习惯是——这两个引脚直接上拉到VCC,用10kΩ电阻就行。省心。
4.2 电平匹配:3.3V vs 1.8V
嗯,这里是个大坑。现在的MCU和Flash,电压五花八门。你MCU是3.3V,Flash是1.8V,直接连?不行,会烧芯片。
为什么会有电平不匹配?
低功耗设备越来越多,很多Flash为了省电,核心电压降到1.8V。但老一点的MCU或者某些高性能MCU,IO口还是3.3V。这就尴尬了。
我的处理方案:
- 方案一:电平转换芯片。比如TXS0102、SN74LVC1T45。我一般用TXS0102,两路双向,正好覆盖MOSI和MISO。CS和SCLK是单向的,可以用电阻分压。
- 方案二:电阻分压。3.3V转1.8V,用两个电阻分压就行。但注意,MISO是从Flash往MCU送数据,这个方向是1.8V到3.3V,需要MCU支持1.8V输入高电平阈值。很多MCU的VIH是0.7×VCC,3.3V下约2.3V,1.8V信号够不到。所以MISO方向必须用电平转换。
- 方案三:直接使用支持双电压的MCU。有些MCU的IO口可以配置成1.8V或3.3V,比如STM32的某些系列。那就简单了,统一设成1.8V。
4.3 去耦电容与PCB布局建议
去耦电容,说白了就是给Flash一个干净的电源。Flash在擦写操作时,电流会突然增大,如果电源不稳,数据就可能写错。
我的标准配置:
- 每个Flash芯片旁边放一个0.1μF(104)陶瓷电容,尽量靠近VCC引脚,距离不超过2mm。
- 如果板子空间允许,再加一个4.7μF或10μF的钽电容,做低频去耦。
- 电容的接地过孔要直接打到地平面,不要绕路。
PCB布局建议:
- Flash尽量靠近MCU,SPI走线越短越好。我一般控制在3cm以内。
- SCLK和MOSI/MISO不要平行走太远,避免串扰。如果必须平行,中间加地线隔离。
- CS#线要单独走,不要跟其他信号扎堆。片选信号一旦被干扰,Flash就会误动作。
- 电源和地线要粗,至少15mil以上。我习惯用20mil。
4.4 信号完整性注意事项
信号完整性,听起来高大上,其实就三件事:反射、串扰、时序。
反射问题:
SPI时钟频率高了之后,信号在线上会反射。反射会导致信号过冲或下冲,严重时MCU读到错误的数据。我的做法是:
- 在SCLK和MOSI上串联一个22Ω或33Ω的电阻,靠近MCU端放。这个电阻能吸收反射能量。
- 如果频率超过50MHz,建议做阻抗匹配。PCB走线控制50Ω阻抗。
串扰问题:
SCLK是时钟,跳变沿很陡,容易干扰旁边的数据线。我建议:
- SCLK和MISO/MOSI之间保持3倍线宽的距离。
- 如果板子层数够,把SCLK放在内层,上下都是地平面,屏蔽效果最好。
时序问题:
这个最容易被忽略。SPI有四种模式(CPOL和CPHA的组合),MCU和Flash必须匹配。我遇到过好几次,代码怎么调都不对,最后发现是SPI模式配错了。
另外,走线长度不一致会导致时钟和数据到达时间不同。比如SCLK走了5cm,MISO走了8cm,那MISO的数据就晚到一点。频率低时没事,频率高了就会出错。我的经验是:同一组SPI信号,走线长度差控制在1cm以内。
嗯,这一章就到这里。下一章咱们开始讲SPI协议层的驱动实现,那才是真正写代码的地方。到时候我会把初始化、读写、擦除的代码一行一行拆给你看。