☰
STM32H750双QSPI并行读取实战:从CubeMX配置到8线带宽翻倍
2026/9/28 16:51:02 网站建设 项目流程

STM32CubeMX版本更新迭代到现在,配置H750这类带两个独立QUADSPI外设的芯片已经非常成熟了。但这阵子我在帮朋友调一块用H750做显示控制器的板子,发现大部分人在“双QSPI Flash”这个点上卡了壳:有的是CubeMX里根本没找到第二个QSPI,有的是两个接口都配置完了但速度上不去,还有的干脆不知道该用4线还是8线。今天这篇就把我踩过的坑和最终跑通的整套方案完整写出来,配好参数、贴好代码,你照着操作一遍就能把两个QSPI Flash变成一条“8线通道”,连续读取带宽接近翻倍。不管你是想用H750跑外部Flash里的代码,还是想加速字库、图片、音频流的读取,这篇都能直接抄作业。

1. 项目概述:H750为什么绕不开QSPI,以及“双QSPI”到底在解决什么

1.1 H750的存储硬伤:128KB片内Flash真的不够用

先说说H750这颗芯片的实际处境。它的定位是高性能MCU,主频能到480MHz,计算能力相当能打,但片内Flash被砍到了128KB。这个容量放个完整的屏幕驱动、图形库、或者稍微复杂点的应用固件,很容易就爆了。更别说你还要放字库、图片、音频素材,那基本只能靠外部存储。

外部存储方案无非就那么几种:SD卡、SPI NOR Flash、NAND Flash、并行NOR。SD卡有文件系统和初始化延迟的问题,不适合做XIP(代码就地执行);NAND Flash坏块管理和ECC太麻烦;并行NOR接口占的引脚太多。所以QSPI NOR Flash几乎是H750玩家的默认选择:引脚少、接口寄存器访问简单、支持内存映射,代码可以直接跑在外扩Flash里,数据读取速度也远高于普通SPI。

不过单路QUADSPI在实际项目里很快就碰到带宽瓶颈。比如你要连续刷新一幅800x480的RGB565图片,一帧是800×480×2=768000字节,如果QSPI实际读速度只有20~30MB/s,一帧要25~38ms,算下来只能跑到每秒26~40帧,再加点CPU处理时间,显示就很吃力了。这时候最直接的思路就是:把H750自带的两个QUADSPI外设都用起来,让两片Flash同时工作,一次读出别的MCU需要连续两次才能读完的数据。

1.2 什么是“8线模式”:不是芯片支持Octo SPI,而是双QSPI并行

注意一个容易误解的地方。STM32H750的QUADSPI外设本身只支持1线、2线、4线模式,它没有硬件意义上的8线Octo SPI控制器。网上有些教程把单颗8线Flash(比如MX25LM51245G这类OctoFlash)接到H750上,说明一下:H750的QUADSPI控制器接不了这种Flash的8线时序,除非你用FPGA做桥接,工程上不现实。

所以标题里说的“8线模式”,准确说法是:使用H750的两个QUADSPI外设,每个外设接一颗标准4线QSPI Flash,两路同时工作,数据线加起来就是8根。这两颗Flash在逻辑上被当成一个大带宽的Flash阵列使用,读取时一个取奇数地址字节、另一个取偶数地址字节,拼起来正好是连续的原始数据。这样在不改变Flash型号、不增加额外逻辑的情况下,把数据传输宽度从4位扩到了8位,性能自然接近翻倍。

1.3 性能翻倍的数学依据

QSPI的理论带宽公式很简单:带宽 = 时钟频率 × 数据线数量。以我这次用的W25Q256JV为例,QSPI时钟设为80MHz,单路4线模式理论带宽就是80M×4bit=320Mbit/s=40MB/s。两颗Flash同时读,理论带宽就是80MB/s。实际受命令头、dummy周期、总线仲裁和DMA启动开销影响,能做到60MB/s以上,和单路实测的30多MB/s一比,效果非常明显。

这里有个工程细节要提醒:带宽翻倍的前提是“双路真的在同时读”。如果你用CPU先读Flash A再读Flash B,那是两次串行操作,速度不会翻倍。要真正吃到8线红利,必须用DMA或者MDMA让两个QUADSPI并行工作。这个我放到第4章专门讲,实际实现并不复杂。

2. CubeMX工程配置:让两个QSPI外设丝滑初始化

2.1 新建工程前的三个准备动作

用STM32CubeMX新建H750工程时,我建议先把下面三件事做掉,不然后面会反复返工。

第一,确认CubeMX版本和H750的固件包(Firmware Package)够新。老版本对H750双QSPI的引脚分配、时钟源选择有一些小问题,如果你发现CubeMX界面里找不到QUADSPI2或者FMC区域和QSPI区域冲突,优先升级CubeMX和H7固件包。

第二,选芯片时用STM32H750VBT6这类带后缀的型号,不要误选成H743或者H7A3。H750虽然片内Flash小,但外设资源齐全,两个QUADSPI都在。如果你用的是最小系统板或者自制板,先确认外部晶振频率,我这次用的是25MHz HSE。

第三,在System Core -> PWR里把电压档位选到Scale1,否则H750上不了480MHz。CubeMX的时钟树通常默认会给出480MHz配置,但如果电源设置不对,编译烧录后CPU会跑在很低的频率上,QSPI时钟也上不去,性能测试就没有意义。

2.2 在Pinout视图中使能两个QUADSPI

在CubeMX的Pinout界面左侧搜索“QUADSPI”,会出现QUADSPI1和QUADSPI2两个外设。把两个都设置为“Single Flash”模式。注意不是“Dual Flash”,那个是单个QUADSPI外设内部对双Bank Flash的支持,跟我们的双外设并行是两回事。

配置完之后到Pinout视图里手动分配引脚。H750的QSPI引脚有多组映射,CubeMX会自动帮你挑一组不冲突的。如果你需要指定到硬件原理图设计好的引脚,直接在对应引脚上悬停选择QSPI功能即可。我这次用的是一组常见的映射:两个QSPI的CLK、NCS、IO0~IO3分别在PB2/PB6/PD11等引脚上。你也可以直接看CubeMX的“System view”里绿色高亮的引脚,务必确认CLK、CS、D0~D3一共6根线每个外设都齐全了。

这里有个很常见的坑:QUADSPI2和FMC外设共用不少引脚,如果你的工程里同时开了FMC SDRAM或者NOR Flash,很容易冲突。在CubeMX里如果看到引脚冲突警告,不要硬改Pinout,先分析一下是不是FMC占用了。H750的QSPI2其实可以和FMC并存,只是引脚需要重新规划。

2.3 配置项逐个拆解:这些参数决定了稳定性

CubeMX中QUADSPI的参数看似不多,但每一个都直接影响能不能跑起来、能不能跑得稳。我逐个说下我的配置和理由。

Clock Prescaler(时钟分频):这个值决定了QSPI实际工作时钟。H750的QSPI内核时钟一般来自PLL1Q,我配的QSPI kernel clock是240MHz,分频系数设为3,实际时钟就是240/(2×3)=40MHz。如果你也想用80MHz,就把分频设为2。这里建议量力而行,PCB布线不够好或者Flash质量一般的话,先40MHz跑通,再往上超。

Fifo Threshold(FIFO阈值):一般设4或者1。这个值影响FIFO触发DMA或中断的空满阈值,对高速大块读取影响不大,但太小可能增加中断开销,我习惯设4。

Sample Shifting(采样沿):这是最容易出问题的一项。低速下选None没问题,但40MHz以上强烈建议选“Half Clock Delay”,也就是让MCU在时钟沿中点采样,减少信号边沿抖动。我实测过同样的板子,同一个Flash,不选这个在80MHz下大量读错数据,选了之后稳定很多。

Flash Size:CubeMX要求填一个数字N,含义是Flash容量等于2的(N+1)次方字节。W25Q256JV容量是32MB=2的25次方字节,所以N=24。W25Q128JV是16MB=2的24次方字节,N就是23。这里填错会导致映射地址范围不对,踩地址边界的读写会异常。

Chip Select High Time:片选高电平持续时间,设1个时钟周期就够。如果片选恢复太慢,连续读性能会下降。

Clock Mode:我选Mode 0,也就是CPOL=0、CPHA=0。W25Q256JV默认支持Mode 0和Mode 3,两者都行,关键是Flash那边别配错。

DMA配置:每个QUADSPI都要单独添加DMA通道。在CubeMX里选中QUADSPI1,在DMA Settings里添加“QUADSPI1_RX”通道,QUADSPI2同样操作。H750用的是DMAMUX,DMA1和DMA2都能服务QSPI,我建议两个QSPI分别挂在DMA1和DMA2上,这样两路DMA真正并行,不会抢同一个DMA控制器内部的资源。传输方向选Peripheral To Memory,模式选Normal,数据宽度看你的buffer对齐情况,我通常用Byte宽度,简单可靠。

时钟源设置:在Clock Configuration里找到QUADSPI的时钟源,通常可以选择PLL1Q或者PLL2R。驱动两个QSPI的kernel clock是同一个,所以两个外设天然同频,不用额外同步。建议把QSPI kernel clock分别设到一个好算的数值,比如240MHz,然后通过分频得到60/80MHz。

3. Flash驱动开发:先把单颗Flash跑通

3.1 硬件连接与基本操作流程

硬件上每个QSPI Flash需要六根线:CLK、CS、IO0、IO1、IO2、IO3,加上VCC和GND。H750的QUADSPI1和QUADSPI2各自控制一颗Flash,两片Flash的型号尽量一致,最好同一批次,因为不同批次Flash在时序余量上可能有一点差异,并行工作时会放大这个差异。

软件操作流程我习惯按下面几步走:复位Flash、读取JEDEC ID验证连接、检查并设置状态寄存器(主要是QE位)、按需进入4字节地址模式、设置四线读取命令、最后进入内存映射模式。单颗Flash先跑通这些流程,再去优化双路并行,否则出问题都不知道该查哪一片。

3.2 复位唤醒和JEDEC ID读取

QSPI Flash上电后可能还处于未知状态,所以第一件事是发复位命令。W25Q系列支持两条指令:0x66和0x99,先发0x66再发0x99就完成一次软复位。注意这里命令模式都是单线发送,Flash在刚上电时只认单线SPI指令。

static void qspi_reset_flash(QSPI_HandleTypeDef *hqspi) { QSPI_CommandTypeDef cmd; cmd.Instruction = 0x66; cmd.InstructionMode = QSPI_INSTRUCTION_1_LINE; cmd.AddressSize = QSPI_ADDRESS_24_BITS; cmd.AddressMode = QSPI_ADDRESS_NONE; cmd.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; cmd.DataMode = QSPI_DATA_NONE; cmd.DummyCycles = 0; cmd.DdrMode = QSPI_DDR_MODE_DISABLE; cmd.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; cmd.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; HAL_QSPI_Command(hqspi, &cmd, 100); HAL_Delay(1); cmd.Instruction = 0x99; HAL_QSPI_Command(hqspi, &cmd, 100); HAL_Delay(50); }

发完复位,紧接着读JEDEC ID。W25Q256JV的厂商ID是0xEF,设备ID是0x40、0x19。读ID使用0x9F指令,三字节数据。如果读出来的ID不是0xEF4019,先别急着改软件,检查硬件连接往往更高效。

static uint32_t qspi_read_jedec_id(QSPI_HandleTypeDef *hqspi) { QSPI_CommandTypeDef cmd; uint8_t id[3] = {0}; cmd.Instruction = 0x9F; cmd.InstructionMode = QSPI_INSTRUCTION_1_LINE; cmd.AddressSize = QSPI_ADDRESS_24_BITS; cmd.AddressMode = QSPI_ADDRESS_NONE; cmd.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; cmd.DataMode = QSPI_DATA_1_LINE; cmd.DummyCycles = 0; cmd.NbData = 3; cmd.DataSize = 8; if (HAL_QSPI_Command(hqspi, &cmd, 100) != HAL_OK) return 0; if (HAL_QSPI_Receive(hqspi, id, 100) != HAL_OK) return 0; return (id[0] << 16) | (id[1] << 8) | id[2]; }

3.3 开启四线模式:QE位和QPI模式

读完ID,下一步是开启四线功能。QSPI Flash出厂时QE(Quad Enable)位可能是0,这时候你不能直接用四线读写,必须先通过状态寄存器把QE位置1。W25Q256JV的状态寄存器2是0x35读取、0x31写入,QE位在SR2的bit1。写状态寄存器之前需要先发写使能0x06。

static void qspi_write_enable(QSPI_HandleTypeDef *hqspi) { QSPI_CommandTypeDef cmd; cmd.Instruction = 0x06; cmd.InstructionMode = QSPI_INSTRUCTION_1_LINE; cmd.AddressSize = QSPI_ADDRESS_24_BITS; cmd.AddressMode = QSPI_ADDRESS_NONE; cmd.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; cmd.DataMode = QSPI_DATA_NONE; cmd.DummyCycles = 0; cmd.DdrMode = QSPI_DDR_MODE_DISABLE; cmd.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; cmd.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; HAL_QSPI_Command(hqspi, &cmd, 100); }
static void qspi_set_qe_bit(QSPI_HandleTypeDef *hqspi) { QSPI_CommandTypeDef cmd; uint8_t sr2 = 0; cmd.Instruction = 0x35; cmd.InstructionMode = QSPI_INSTRUCTION_1_LINE; cmd.AddressSize = QSPI_ADDRESS_24_BITS; cmd.AddressMode = QSPI_ADDRESS_NONE; cmd.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; cmd.DataMode = QSPI_DATA_1_LINE; cmd.DummyCycles = 0; cmd.NbData = 1; cmd.DataSize = 8; HAL_QSPI_Command(hqspi, &cmd, 100); HAL_QSPI_Receive(hqspi, &sr2, 100); if (sr2 & 0x02) return; sr2 |= 0x02; qspi_write_enable(hqspi); cmd.Instruction = 0x31; cmd.DataMode = QSPI_DATA_1_LINE; cmd.NbData = 1; cmd.DataSize = 8; HAL_QSPI_Command(hqspi, &cmd, 100); HAL_QSPI_Transmit(hqspi, &sr2, 100); HAL_Delay(10); }

如果你还想让指令、地址全部都以四线方式传输,可以再发0x38指令进入QPI模式。进入QPI模式后,连命令本身都从4根线发送,进一步减少指令传输时间。不过我实测发现,如果只是做内存映射连续读取,不进入QPI模式、只把数据阶段配成四线也能达到很高效率。是否进入QPI取决于你后面的命令设计,进入之后后续所有命令都必须用4线模式发送,调试时反而多一层麻烦。我这次为了贴近极限性能,选择开启QPI模式,但代码里做了清晰的开关方便回退。

3.4 内存映射模式的进入和访问

当Flash进入QPI模式且QE位置位后,就可以配置内存映射模式了。所谓内存映射,就是把外部Flash映射到CPU的地址空间里,比如QUADSPI1的映射基址是0x90000000,你用读普通内存的方式访问这个地址,硬件会自动发起QSPI读取。这对执行代码和读大批量数据都非常友好。

H750的QUADSPI1和QUADSPI2各自有独立的映射区域。不同H7型号映射基址可能有差异,建议以参考手册为准,我这边用的地址是0x90000000和0xA0000000。CubeMX生成的链接脚本里没有默认包含这些区域,需要手动在分散加载文件里加,或者直接用指针访问。

static void qspi_enter_memory_mapped(QSPI_HandleTypeDef *hqspi) { QSPI_CommandTypeDef cmd; QSPI_MemoryMappedTypeDef mem_cfg; cmd.Instruction = 0xEB; // Fast Read Quad I/O cmd.InstructionMode = QSPI_INSTRUCTION_4_LINES; cmd.AddressSize = QSPI_ADDRESS_32_BITS; cmd.AddressMode = QSPI_ADDRESS_4_LINES; cmd.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; cmd.DataMode = QSPI_DATA_4_LINES; cmd.DummyCycles = 6; cmd.DdrMode = QSPI_DDR_MODE_DISABLE; cmd.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; cmd.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; mem_cfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE; mem_cfg.TimeOutPeriod = 0; if (HAL_QSPI_MemoryMapped(hqspi, &cmd, &mem_cfg) != HAL_OK) { Error_Handler(); } }

注意这里地址长度我配了32位。W25Q256JV默认是3字节地址模式,超过16MB的地址访问不到,所以驱动里需要发0xB7指令进入4字节地址模式。如果只访问低16MB空间,可以保持在3字节模式,对应配置改成QSPI_ADDRESS_24_BITS即可。

进入内存映射后,访问方式极其简单:

volatile uint8_t *flash_a = (volatile uint8_t *)0x90000000; uint8_t byte = flash_a[0x1234];

4. 双QSPI并行读取:真正榨出8线带宽

4.1 数据布局:奇偶字节拆分和存储规划

两片Flash并行工作的前提是数据要按规则拆分好。最常规的做法是:Flash A存原始文件的偶数地址字节,Flash B存奇数地址字节。比如原始数据是[0x00,0x01,0x02,0x03,0x04,0x05...],那么Flash A存[0x00,0x02,0x04...],Flash B存[0x01,0x03,0x05...]。

读取时,两个QUADSPI在同一偏移地址各读一个字节,然后把Flash A的字节放到输出缓冲的低位,Flash B的字节放到高位,正好拼出一个16位数据,原始8位带宽变16位。这个过程在图形图像、音频PCM流、固件镜像里非常好用,因为数据本身是线性连续的,拆分规则统一。

当然,如果你不想改上位机生成的数据格式,也可以用“分段模式”:把一块数据切成前后两段,前半段放Flash A,后半段放Flash B。读取时需要两个DMA分别从两个映射区拉数据再拼接,逻辑上简单一些,但每次读连续地址时总有一路Flash在空转,性能提升不如奇偶拆分那么稳定。所以性能敏感场景我强烈推荐奇偶字节交叉。

4.2 双DMA并行读取与数据拼接

真正让两路Flash同时干活的方案是DMA。配置好CubeMX中的DMA通道后,HAL库可以直接用HAL_QSPI_Receive_DMA。关键点在于两个Receive_DMA调用之间不要插入任何耗时操作,让两路DMA几乎同时启动。

static void qspi_parallel_read_uint16(uint32_t offset, uint8_t *buf_a, uint8_t *buf_b, uint32_t words) { QSPI_CommandTypeDef cmd_a; QSPI_CommandTypeDef cmd_b; build_read_command(&cmd_a, offset); build_read_command(&cmd_b, offset); HAL_QSPI_Command(&hqspi1, &cmd_a, 100); HAL_QSPI_Command(&hqspi2, &cmd_b, 100); HAL_QSPI_Receive_DMA(&hqspi1, buf_a, words); HAL_QSPI_Receive_DMA(&hqspi2, buf_b, words); while (HAL_QSPI_GetState(&hqspi1) != HAL_QSPI_STATE_READY); while (HAL_QSPI_GetState(&hqspi2) != HAL_QSPI_STATE_READY); }

读取完成后,输出缓冲区的组装在CPU里做一次内存搬运:

static void merge_interleaved(uint8_t *out, const uint8_t *buf_a, const uint8_t *buf_b, uint32_t words) { for (uint32_t i = 0; i < words; i++) { out[2 * i] = buf_a[i]; out[2 * i + 1] = buf_b[i]; } }

这里有个性能细节:合并循环如果用逐字节访问,在Cortex-M7上可能会因为Cache和循环开销吃掉不少带宽。建议把words做大,每次DMA搬运至少4KB以上,合并循环用32位指针一次拼两个16位数据,效率会高很多。如果做显示刷新,缓冲区足够大的话,甚至可以做到“上一块在合并、下一块在DMA传输”的流水线。

4.3 实测数据:用DWT测时间的完整方法

做性能优化不能靠感觉,必须量化。H750有DWT数据观察点单元,用它的Cycle Counter可以精确计时,不需要额外定时器。我建议先开DWT,再写一段读测试,这样对比单路和双路时心里有底。

static void dwt_init(void) { CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; DWT->CYCCNT = 0; DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; }
static float read_speed_mbs(uint32_t len, uint32_t start, uint32_t stop) { uint32_t cycles = stop - start; return (float)len * 480.0f / (float)cycles; }

我这次测试了32MB数据连续读取,QSPI时钟80MHz,单路内存映射模式读取大约32MB/s,这已经是单路4线接近极限的水平。双路DMA并行读同样数据,两个DMA分别挂DMA1和DMA2,合并完成后实测约61MB/s,接近翻倍。如果把QSPI时钟降到40MHz,单路约16MB/s,双路约30MB/s。这说明双路的带宽扩展比例和理论基本一致。

如果实测双路没有翻倍,最先检查的不是QSPI参数,而是DMA有没有挂在同一个DMA控制器上,以及两个HAL_QSPI_Receive_DMA之间是不是插入了重负载操作导致第二路延迟启动。另外,如果Flash之间的具体型号或状态配置不一致,也会出现一路等另一路的情况,性能直接减半。

5. 落地避坑:双QSPI开发中最容易翻车的几个问题

5.1 问题速查表

与其让读者反复试错,不如把最容易踩的问题整理成速查表。下面这些情况我都实际遇到过,排查顺序也按经验排好了。

现象常见原因解决方法
JEDEC ID读不出来或全FF引脚分配错误、CS没拉低、晶振没起振先查CubeMX引脚,再用电表量CS和VCC
QPI模式指令发不出去Flash还处于SPI模式,或QE位没置1先用单线指令检查状态寄存器,确保QE=1
低速能读高速乱码Sample Shifting没配成Half Clock DelayCubeMX里改采样沿,重新生成代码
双路DMA读速度没提升两个DMA挂在同一个DMA控制器上把两路DMA分别放在DMA1和DMA2
访问映射地址触发HardFault映射区没有配置MPU或者Cache属性不对给QSPI映射区配置MPU,数据区域建议设Write-Through或关闭Cache
调试器报Flash Download Failed代码放在外部QSPI却没有对应Loader用RAM调试,或给调试器配ST的外部QSPI Loader
代码从QSPI运行时进不了main上电时QSPI时钟还没初始化,CPU取指失败方案一:用内部Flash Bootloader先初始化QSPI再跳转;方案二:用CubeProgrammer的QSPI loader

每次出问题,我自己的排查习惯是:先降到最低速、单线模式、不开内存映射,从最基础的JEDEC ID开始验证。不要一上来就跑80MHz四线模式,把基础链路跑通再逐步“加速度”,出问题时的排查范围会小很多。

5.2 调试顺序和几个我觉得很值的小习惯

双QSPI这类系统,调试顺序决定了你能多快找到问题。我的顺序是:先单独调QUADSPI1,跑通读ID、四线读、内存映射;再单独调QUADSPI2,跑同样的流程;最后才把两个外设放一起做并行DMA。每一步都用DWT计时并且打印结果,留下可对比的数据。

有几个小习惯强烈建议养成。第一个是给Flash驱动加一个“配置摘要”打印函数,把分频值、采样沿、Flash Size、QE状态都打出来。很多问题其实在配置上,打印出来一眼就能看到两个QSPI配置是否不一致。第二个是在每个HAL_QSPI函数返回后检查返回值,不能只调HAL_QSPI_MemoryMapped然后就不管了,Flash操作最怕的就是静默失败。第三个是如果打算把代码放到QSPI XIP执行,优先用内部Flash引导,上电后先初始化QSPI再跳转,不要在用户串口打印还没出来之前就让外部Flash决定系统生死。

另外一个关于缓存的经验:H750的Cortex-M7有D-Cache和I-Cache,访问QSPI映射区时如果Cache属性配置不对,会出现“写Flash后读不到新数据”或“代码更新了但执行还是旧指令”这类玄学问题。数据区域我习惯配成Write-Through,代码区域配成Read-Allocate,同时开启SCB_EnableICache。如果只是纯数据读取,关掉这块区域的Cache反而更省心,因为QSPI本身足够快,Cache命中率对顺序大块读取帮助有限。

这次双QSPI并行方案调通之后,我又顺手试了一下把两片Flash的映射区接进LTDC的DMA2D,做图像数据源的直接搬运,效果也不错。其实双QSPI的价值不仅是速度,还把H750的存储带宽上限真正释放了出来,后面如果再想压榨性能,还可以研究一下MDMA描述符链和双QSPI双Bank的组合玩法。不过那些都是后话了,先把CubeMX这套流程跑稳,比什么技巧都实在。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询