2. 硬件接口与引脚功能:SPI接口详解(CS、CLK、MOSI、MISO)、Parallel接口详解(地址线、数据线、控制线)、电源与去耦电容设计、硬件连接实战(以W25Q64为例)
好,咱们进入第二章。这一章我打算把NOR Flash的硬件接口彻底讲透。
你想想看,驱动写得再漂亮,如果硬件连错了,一切都是白搭。我在早期项目中就吃过这个亏——软件调了三天,最后发现是SPI的CS引脚虚焊了。嗯,从那以后,我拿到板子第一件事就是拿万用表量引脚通断。
2.1 SPI接口详解
SPI,全称Serial Peripheral Interface。说白了就是四根线搞定一切通信。我特别喜欢SPI接口,因为它简单、可靠,而且占用的GPIO少。
这四根线分别是:
- CS (Chip Select):片选信号。低电平有效。我习惯叫它“片选”,也有人叫“使能”。每次通信前,主机把CS拉低,告诉从机:“我要跟你说话啦!”通信结束再拉高。
- CLK (Clock):时钟信号。由主机产生。SPI是同步通信,所有数据都在时钟的边沿采样。时钟频率决定了通信速度。W25Q64最高支持104MHz,但实际要看你的MCU能不能跑那么快。
- MOSI (Master Out Slave In):主机输出,从机输入。数据从主机流向从机。
- MISO (Master In Slave Out):主机输入,从机输出。数据从从机流向主机。
重要提醒:SPI是全双工的。什么意思?就是MOSI和MISO可以同时传输数据。主机发一个字节的同时,从机也在发一个字节。很多新手会忽略这一点,以为要分开发送和接收。其实不用,你发一个字节,读回来的就是对方同时发过来的字节。
SPI有四种模式,由时钟极性(CPOL)和时钟相位(CPHA)决定。W25Q64支持模式0和模式3。我个人习惯用模式0,因为大多数MCU默认就是这个模式,省事。
| SPI模式 | CPOL | CPHA | 时钟空闲电平 | 数据采样边沿 |
|---|---|---|---|---|
| 模式0 | 0 | 0 | 低电平 | 上升沿 |
| 模式1 | 0 | 1 | 低电平 | 下降沿 |
| 模式2 | 1 | 0 | 高电平 | 下降沿 |
| 模式3 | 1 | 1 | 高电平 | 上升沿 |
小技巧:如果你不确定当前MCU的SPI模式配置,可以先发一个0xFF试试。因为W25Q64在收到0xFF时,会返回状态寄存器的值。如果返回0x00,说明模式可能不对。
2.2 Parallel接口详解
Parallel接口,也就是并行接口。它比SPI快得多,但占用的引脚也多。我只有在做高速数据采集或者代码执行在Flash上的场景才会用Parallel接口。
Parallel接口主要分三组信号:
- 地址线 (A0~Axx):用来选择要访问的存储单元。比如一个8MB的NOR Flash,需要23根地址线(2^23 = 8M)。地址线越多,能寻址的空间越大。
- 数据线 (DQ0~DQ15):用来传输数据。8位宽就是8根线,16位宽就是16根线。我建议能用8位就别用16位,因为PCB布线会简单很多。
- 控制线:包括片选(CE#)、输出使能(OE#)、写使能(WE#)等。这些信号控制着读写的时序。
Parallel接口的时序比SPI复杂。读操作时,先给地址,然后拉低CE#和OE#,等一段时间(访问时间),数据就会出现在数据线上。写操作类似,但需要拉低WE#。
注意:Parallel接口的时序参数非常关键。比如地址建立时间、数据保持时间、脉冲宽度等。我在一个项目中曾经因为OE#的脉冲宽度不够,导致读出来的数据全是0xFF。查了两天才发现是时序问题。
2.3 电源与去耦电容设计
NOR Flash的电源设计,看似简单,其实坑不少。W25Q64的工作电压是2.7V~3.6V,典型值3.3V。
去耦电容,我习惯在每个电源引脚旁边放一个0.1μF的陶瓷电容。为什么是0.1μF?因为这个容值的电容自谐振频率在几十MHz,正好覆盖Flash的工作频段。
另外,我建议在PCB的电源入口处放一个10μF的电解电容或者钽电容。这个电容用来滤除低频纹波。
我的经验:去耦电容的摆放位置比容值更重要。电容要尽量靠近Flash的电源引脚,走线要短而粗。我见过有人把电容放在PCB的另一面,中间还隔了几个过孔——那基本等于没放。
还有一点,VCC和GND之间不要只靠电容连接。电源走线要足够宽,至少20mil以上。如果条件允许,用电源层和地层是最好的。
2.4 硬件连接实战:以W25Q64为例
好,咱们来点实际的。以W25Q64为例,看看怎么把它连到MCU上。
W25Q64是8脚封装,引脚定义如下:
| 引脚号 | 引脚名 | 功能 | 连接建议 |
|---|---|---|---|
| 1 | CS# | 片选 | 接MCU的GPIO |
| 2 | DO (IO1) | 数据输出 (MISO) | 接MCU的MISO |
| 3 | WP# (IO2) | 写保护 | 接VCC或GPIO |
| 4 | GND | 地 | 接GND |
| 5 | DI (IO0) | 数据输入 (MOSI) | 接MCU的MOSI |
| 6 | CLK | 时钟 | 接MCU的SCK |
| 7 | HOLD# (IO3) | 保持 | 接VCC或GPIO |
| 8 | VCC | 电源 | 接3.3V,加去耦电容 |
连接的时候,有几点要注意:
- WP#和HOLD#:这两个引脚如果不使用,一定要拉高到VCC。悬空的话,Flash可能会误动作。我见过有人把这两个脚悬空,结果写操作老是失败。
- CS#:不要直接接地。虽然接地后Flash一直使能,但多个SPI设备共用总线时就会冲突。
- 去耦电容:在VCC和GND之间放一个0.1μF的电容,尽量靠近引脚。
下面是一个典型的连接示意图:
这张图里,我特意画了上拉电阻和去耦电容。上拉电阻一般用10kΩ,确保CS#在空闲时是高电平。去耦电容我放在了VCC和GND之间,位置尽量靠近Flash。
实战建议:第一次焊接完,先别急着上电。用万用表量一下VCC和GND之间有没有短路。我每次都会做这一步,因为PCB打样回来,偶尔会有焊盘连锡的情况。
好了,硬件连接这部分就讲到这里。记住,硬件是基础,基础不牢,地动山摇。下一章咱们开始写驱动代码,到时候你会感谢今天认真看硬件连接的自己。
总结一下本章要点:
- SPI接口四根线:CS、CLK、MOSI、MISO,全双工通信
- Parallel接口三组线:地址线、数据线、控制线,速度快但引脚多
- 去耦电容要靠近电源引脚,0.1μF是标配
- W25Q64的WP#和HOLD#不能悬空,必须拉高