STM32CubeMX配置SPI读写FLASH实战:从原理图到代码实现全流程

STM32CUBEIDE之SPI读写FLASH进阶串行FLASH文件系统FatFs 步骤 步骤讲解与结果截图 步骤1:创建STM32CUBEIDE工程(根据自己的开发板,配置RCC,选择最低版本固件库) 2:查看FLASH与自己板子的接线图 3:根据FLASH时序特点,这个芯片采用MSB先行,一般采用模式0(初始低电平,采集第一个边沿)与模式3(初始高电平,采集第二个边沿)的时钟,SPI采用的摩托罗拉的设计,所以我们将SPI配置如下 4:调整引脚 由于我们发现系统配置的SPI1的引脚与我们开发板的引脚标号PB3,PB4,PB5不一致,所以我们要对SPI1... 阅读详情

STM32CubeMX配置SPI读写FLASH实战:从原理图到代码实现全流程

在嵌入式开发的世界里,外部存储器扩展是绕不开的课题。无论是存储设备固件、记录运行日志,还是缓存传感器数据,一块可靠的非易失性存储器都至关重要。W25Qxx系列SPI FLASH芯片以其高性价比、大容量和简单的四线接口,成为了STM32开发者最常打交道的“老朋友”之一。然而,从看懂原理图到在代码中流畅地读写数据,中间往往横亘着配置、时序、调试等多重关卡。对于习惯了HAL库和图形化工具的现代开发者而言,如何高效地打通这条路径,将硬件能力转化为稳定的软件功能,正是本文要解决的核心问题。

本文不会停留在通信协议的枯燥对比上,而是聚焦于一个完整的、可复现的工程实践。我们将手把手地,从硬件连接分析开始,借助STM32CubeMX这一强大工具完成SPI外设的图形化配置,并深入HAL库函数,编写出健壮的读写、擦除代码。更重要的是,我们会探讨如何利用DMA解放CPU,以及如何应对实际调试中那些令人头疼的常见问题,比如数据错位、读写失败等。无论你是刚刚接触STM32的初学者,还是希望优化现有驱动代码的进阶者,这篇融合了工具链实操与真实硬件调试经验的内容,都将为你提供清晰的路线图。

1. 硬件连接与原理图解析

在敲下第一行代码之前,我们必须和硬件“对话”。理解原理图上的每一个连接,是后续所有软件工作的基石。SPI(Serial Peripheral Interface)作为一种同步、全双工的串行通信协议,其硬件连线相比UART(异步)更为固定,通常包含四条信号线。

1.1 SPI信号线定义与W25Qxx引脚

一个标准的SPI接口包含以下四条线:

  • SCK (Serial Clock): 串行时钟线,由主设备(这里是STM32)产生,用于同步数据位传输。
  • MOSI (Master Out Slave In): 主设备输出、从设备输入数据线。
  • MISO (Master In Slave Out): 主设备输入、从设备输出数据线。
  • CS/SS (Chip Select / Slave Select): 片选线,低电平有效。主设备通过拉低此线来选中特定的从设备进行通信。

对于W25Q128FV这款常见的128Mbit(16MB)FLASH芯片,我们关注其与SPI相关的引脚。通常,它的封装是SOIC-8,引脚定义如下表所示:

引脚编号引脚名称类型功能描述
1CS#输入片选信号,低电平有效。
2DO (IO1)输出数据输出(MISO),在标准SPI模式下为输出。
3WP# (IO2)输入写保护,低电平有效。通常接高电平(VCC)禁用保护。
4GND电源地。
5DI (IO0)输入数据输入(MOSI),在标准SPI模式下为输入。
6CLK输入串行时钟输入(SCK)。
7HOLD# (IO3)输入保持信号,低电平有效。通常接高电平(VCC)禁用。
8VCC电源电源(2.7V - 3.6V)。

注意:WP#和HOLD#引脚在标准SPI模式下并非必须,为了简化,通常通过一个10K电阻上拉到VCC,使其保持无效状态。但在使用QPI或Dual SPI等高速模式时,这些引脚会复用为数据IO。

1.2 与STM32的连接实战

现在,我们将W25Qxx的引脚映射到STM32的SPI外设上。假设我们使用STM32F407系列,并选择SPI1。一个典型的连接方式如下:

  1. W25Qxx CS -> STM32任意GPIO (如 PA4)。这里非常关键:片选引脚不能直接连接到STM32 SPI外设硬件NSS引脚并配置为硬件模式,除非你非常清楚硬件NSS的复杂行为(自动管理、多主模式等)。对于大多数单主单从的应用,更推荐使用软件控制,即将CS配置为普通的推挽输出GPIO,由代码手动拉低或拉高,这样控制最灵活、最直观。
  2. W25Qxx CLK -> STM32 SPI1_SCK (PA5)。
  3. W25Qxx DO (MISO) -> STM32 SPI1_MISO (PA6)。
  4. W25Qxx DI (MOSI) -> STM32 SPI1_MOSI (PA7)。
  5. W25Qxx VCC -> 3.3V。
  6. W25Qxx GND -> GND。
  7. W25Qxx WP# 和 HOLD# -> 通过10K电阻上拉到 3.3V。

检查原理图时,务必确认电源去耦电容(通常一个0.1uF和一个10uF的电容靠近芯片VCC引脚放置)已正确添加,这是保证芯片稳定工作的基础。

2. 使用STM32CubeMX进行工程配置

硬件了然于胸后,我们转向软件配置的利器——STM32CubeMX。它将繁琐的寄存器配置转化为直观的图形操作。

2.1 创建工程与SPI外设初始化

首先,在CubeMX中选择你的目标芯片型号(例如STM32F407ZGTx)。在Pinout & Configuration标签页下,找到Connectivity -> SPI1。

  1. 模式选择:将Mode设置为“Full-Duplex Master”。这意味着STM32作为主设备,可以同时收发数据。
  2. 硬件参数配置:切换到Configuration标签下的Parameter Settings子标签。
    • Clock Prescaler: 时钟预分频器,决定了SCK的频率。SCK频率 = APBx总线时钟 / Prescaler。W25Qxx在标准SPI模式下最高支持约50MHz(3.3V供电时)。对于初始调试,建议选择一个较低的分频,如PCLK2 / 16,确保通信稳定。
    • Data Size: 数据大小,选择8 Bits。W25Qxx的指令、地址、数据都以8位为单位传输。
    • First Bit: 首比特顺序,选择MSB First。这是SPI设备最常见的规定。
    • Clock Polarity (CPOL) 和 Clock Phase (CPHA): 这是SPI配置的核心,决定了数据采样的时钟边沿。W25Qxx芯片手册规定,它支持模式0 (CPOL=0, CPHA=0) 和模式3 (CPOL=1, CPHA=1)。我们通常选择模式0。简单理解:CPOL=0表示SCK空闲时为低电平;CPHA=0表示数据在SCK的第一个边沿(即上升沿)被采样。
  3. 片选引脚(CS)配置:回到Pinout视图,找到我们计划用作CS的引脚(如PA4)。右键点击它,选择GPIO_Output。然后在左侧System Core -> GPIO中配置其初始输出电平为高电平(High),因为CS是低电平有效。

2.2 时钟树与DMA配置(可选但推荐)

时钟树配置:在Clock Configuration标签页,确保为SPI1提供时钟的APB2总线(对于F4系列)运行在你期望的频率上。一个常见的配置是HSE外部晶振8MHz,经过PLL倍频到168MHz系统时钟,APB2总线时钟为84MHz。这样,之前配置的PCLK2 / 16分频将得到约5.25MHz的SCK,非常适合调试。

DMA配置:对于大量数据的读写(如写入一整个页),使用DMA可以极大减轻CPU负担,实现“后台”传输。在Connectivity -> SPI1的DMA Settings标签页中,点击Add添加DMA请求。

  • 为SPI1_TX添加一个DMA流(如DMA2 Stream3),方向为Memory To Peripheral。
  • 为SPI1_RX添加一个DMA流(如DMA2 Stream0),方向为Peripheral To Memory。
  • 模式均选择Normal(单次传输),优先级Medium,内存数据宽度为Byte。

最后,生成工程代码,选择你熟悉的IDE(如Keil MDK或STM32CubeIDE)。CubeMX会自动生成SPI和GPIO的初始化代码,以及DMA的初始化代码(如果配置了)。

3. HAL库驱动代码编写与解析

工程生成后,我们进入Core/Src目录下的main.c或自己创建的flash_driver.c/h文件中,开始编写W25Qxx的驱动层代码。

3.1 底层通信函数封装

首先,我们需要封装最基本的SPI收发函数。由于我们使用软件片选,需要先控制CS引脚。

/* 定义CS引脚操作宏,假设CS连接在PA4 */
#define FLASH_CS_LOW()    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET)
#define FLASH_CS_HIGH()   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET)

/**
  * @brief  向FLASH发送一个字节并接收一个字节
  * @param  tx_data: 要发送的数据
  * @retval 接收到的数据
  */
uint8_t SPI_FLASH_SendByte(uint8_t tx_data)
{
    uint8_t rx_data;
    HAL_SPI_TransmitReceive(&hspi1, &tx_data, &rx_data, 1, HAL_MAX_DELAY);
    return rx_data;
}

/**
  * @brief  读取FLASH的状态寄存器
  * @retval 状态寄存器值
  */
uint8_t W25Qxx_ReadStatusReg(void)
{
    uint8_t status;
    FLASH_CS_LOW();
    SPI_FLASH_SendByte(0x05); // 发送读状态寄存器1指令
    status = SPI_FLASH_SendByte(0xFF); // 发送dummy字节,同时读取状态
    FLASH_CS_HIGH();
    return status;
}

提示:HAL_SPI_TransmitReceive是一个阻塞式函数,会等待传输完成。HAL_MAX_DELAY表示无限等待。在实际产品代码中,应考虑使用超时机制。

3.2 核心功能实现:读、写、擦除

W25Qxx的操作基于指令集。我们需要实现几个最关键的指令:写使能、读数据、页编程、扇区擦除。

/**
  * @brief  写使能
  */
void W25Qxx_WriteEnable(void)
{
    FLASH_CS_LOW();
    SPI_FLASH_SendByte(0x06); // WREN 指令
    FLASH_CS_HIGH();
}

/**
  * @brief  等待芯片空闲(检查BUSY位)
  */
void W25Qxx_WaitForBusy(void)
{
    while ((W25Qxx_ReadStatusReg() & 0x01) == 0x01) // 检查状态寄存器第0位(BUSY)
    {
        // 可以加入超时退出机制
    }
}

/**
  * @brief  读取数据
  * @param  pBuffer: 数据存储缓冲区指针
  * @param  ReadAddr: 读取起始地址
  * @param  NumByteToRead: 要读取的字节数
  */
void W25Qxx_ReadData(uint8_t* pBuffer, uint32_t ReadAddr, uint32_t NumByteToRead)
{
    FLASH_CS_LOW();
    SPI_FLASH_SendByte(0x03); // 发送读数据指令
    SPI_FLASH_SendByte((ReadAddr >> 16) & 0xFF); // 发送24位地址的高8位
    SPI_FLASH_SendByte((ReadAddr >> 8) & 0xFF);  // 中8位
    SPI_FLASH_SendByte(ReadAddr & 0xFF);         // 低8位

    // 连续读取数据
    for (uint32_t i = 0; i < NumByteToRead; i++)
    {
        pBuffer[i] = SPI_FLASH_SendByte(0xFF); // 发送dummy时钟,读取数据
    }
    FLASH_CS_HIGH();
}

/**
  * @brief  页编程(写入数据)。注意:写入前必须确保目标区域已被擦除(值为0xFF)。
  * @param  pBuffer: 要写入的数据缓冲区指针
  * @param  WriteAddr: 写入起始地址
  * @param  NumByteToWrite: 要写入的字节数(不能超过256,且不能跨页)
  */
void W25Qxx_PageProgram(uint8_t* pBuffer, uint32_t WriteAddr, uint32_t NumByteToWrite)
{
    W25Qxx_WriteEnable(); // 第一步:写使能

    FLASH_CS_LOW();
    SPI_FLASH_SendByte(0x02); // 页编程指令
    SPI_FLASH_SendByte((WriteAddr >> 16) & 0xFF);
    SPI_FLASH_SendByte((WriteAddr >> 8) & 0xFF);
    SPI_FLASH_SendByte(WriteAddr & 0xFF);

    for (uint32_t i = 0; i < NumByteToWrite; i++)
    {
        SPI_FLASH_SendByte(pBuffer[i]);
    }
    FLASH_CS_HIGH();

    W25Qxx_WaitForBusy(); // 等待编程完成
}

/**
  * @brief  扇区擦除(4KB)
  * @param  SectorAddr: 扇区地址(必须是4KB对齐的)
  */
void W25Qxx_SectorErase(uint32_t SectorAddr)
{
    W25Qxx_WriteEnable();

    FLASH_CS_LOW();
    SPI_FLASH_SendByte(0x20); // 扇区擦除指令
    SPI_FLASH_SendByte((SectorAddr >> 16) & 0xFF);
    SPI_FLASH_SendByte((SectorAddr >> 8) & 0xFF);
    SPI_FLASH_SendByte(SectorAddr & 0xFF);
    FLASH_CS_HIGH();

    W25Qxx_WaitForBusy(); // 等待擦除完成,擦除时间较长(几十ms)
}

3.3 使用DMA进行大数据量传输

当需要读写几KB甚至几十KB的数据时,使用DMA效率更高。以下是一个使用DMA进行数据读取的示例:

/**
  * @brief  使用DMA读取数据(非阻塞式)
  * @param  pBuffer: 数据存储缓冲区指针
  * @param  ReadAddr: 读取起始地址
  * @param  NumByteToRead: 要读取的字节数
  * @retval HAL status
  */
HAL_StatusTypeDef W25Qxx_ReadData_DMA(uint8_t* pBuffer, uint32_t ReadAddr, uint32_t NumByteToRead)
{
    uint8_t cmd_and_addr[4];
    cmd_and_addr[0] = 0x03; // Read指令
    cmd_and_addr[1] = (ReadAddr >> 16) & 0xFF;
    cmd_and_addr[2] = (ReadAddr >> 8) & 0xFF;
    cmd_and_addr[3] = ReadAddr & 0xFF;

    FLASH_CS_LOW();

    // 1. 先使用阻塞式发送发送指令和地址
    if (HAL_SPI_Transmit(&hspi1, cmd_and_addr, 4, 100) != HAL_OK)
    {
        FLASH_CS_HIGH();
        return HAL_ERROR;
    }

    // 2. 然后启动DMA接收数据
    if (HAL_SPI_Receive_DMA(&hspi1, pBuffer, NumByteToRead) != HAL_OK)
    {
        FLASH_CS_HIGH();
        return HAL_ERROR;
    }

    // 注意:CS需要在DMA传输完成回调函数中拉高!
    // 我们需要在SPI接收完成回调函数里处理CS。
    return HAL_OK;
}

// 在stm32f4xx_hal_msp.c或主程序中重写SPI接收完成回调函数
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
    if (hspi->Instance == SPI1)
    {
        FLASH_CS_HIGH(); // DMA接收完成,拉高CS
        // 可以在这里设置一个标志位,通知主程序数据已就绪
    }
}

使用DMA写入的流程类似,但需要先发送写使能指令和页编程指令及地址,然后启动DMA发送数据。务必处理好指令/地址阶段和数据阶段的CS电平控制,以及等待BUSY的时机。

4. 实战调试与常见问题排查

代码写好了,下载到板子上,却可能发现读写不对。这是硬件调试中最常见的阶段。下面是一些典型的“坑”和排查思路。

4.1 基础通信检查:能否读取到设备ID?

首先实现一个读取JEDEC ID的函数。这是验证SPI物理层通信是否成功的最直接方法。W25Q128FV的JEDEC ID通常是0xEF 0x40 0x18。

void W25Qxx_ReadID(uint8_t *ID)
{
    FLASH_CS_LOW();
    SPI_FLASH_SendByte(0x9F); // JEDEC ID指令
    ID[0] = SPI_FLASH_SendByte(0xFF);
    ID[1] = SPI_FLASH_SendByte(0xFF);
    ID[2] = SPI_FLASH_SendByte(0xFF);
    FLASH_CS_HIGH();
}

在main函数初始化后调用它,并通过串口打印出来。如果读出的ID是0xFF 0xFF 0xFF或0x00 0x00 0x00,说明根本就没通信上。

排查步骤:

  1. 电源与地:用万用表测量FLASH芯片VCC和GND引脚电压是否为稳定的3.3V。
  2. 信号线连接:确认SCK、MOSI、MISO、CS四根线是否与STM32连接正确,没有虚焊或接错。
  3. SPI模式:这是最高频的错误来源! 确认CubeMX中SPI的CPOL和CPHA设置与芯片手册要求一致(模式0或模式3)。用逻辑分析仪或示波器抓取SCK和MOSI的波形是最权威的方法。观察空闲时SCK电平(CPOL),以及数据在哪个边沿稳定(CPHA)。
  4. 片选时序:确保在发送指令前CS已拉低,在整个指令-地址-数据周期完成后才拉高。用逻辑分析仪看CS的波形是否完整包裹了SPI时钟。
  5. 引脚配置:确认STM32的SPI引脚是否被正确复用到SPI功能,而不是普通的GPIO。

4.2 读写数据异常排查

如果ID能正确读取,但写入后再读出的数据不对,问题可能出在软件逻辑或FLASH操作流程上。

  • 现象:写入成功,但读出全是0xFF。

    • 原因:可能根本没有成功执行“写使能”指令。在每次页编程或擦除前,必须发送0x06指令。检查W25Qxx_WriteEnable函数是否被正确调用,并且期间CS的时序正确。
    • 排查:在写使能后,可以读取状态寄存器(指令0x05),检查第1位(WEL,写使能锁存位)是否被置1。如果没有,说明写使能失败。
  • 现象:写入的数据错位或部分错误。

    • 原因1:地址计算错误。FLASH的地址是24位的,确保发送地址的三字节顺序正确(先发最高字节)。
    • 原因2:跨页写入。页编程指令最多连续写入256字节,且不能跨越物理页边界(每个页的起始地址是256字节对齐的)。如果你的写入操作起始地址是250,要写20个字节,这20个字节会被写入到地址250-255和0-13(下一页的开头),这通常会导致非预期的结果。驱动代码中应加入地址边界检查。
    • 原因3:未擦除直接写入。FLASH的特性是只能将位从1变成0,不能从0变成1。擦除操作会将整个扇区(4KB)的所有位置1(变为0xFF)。因此,在向一个非0xFF的地址写入数据前,必须先进行擦除。一个常见的错误是,第一次写入正常(因为出厂时全是0xFF),第二次在同一个地址写入不同数据时失败。
  • 现象:擦除或写入后,读出的数据是随机的,或者操作后芯片无响应。

    • 原因:可能没有正确等待芯片内部操作完成。页编程和扇区擦除都是耗时操作(us到ms级),指令发完后必须轮询状态寄存器的BUSY位,直到其为0,才能进行下一次操作。W25Qxx_WaitForBusy函数中的轮询循环是必须的。
    • 排查:在擦除或编程后,增加一个延时(如100ms)再读取,或者严格使用W25Qxx_WaitForBusy函数。同时检查函数中读取状态寄存器的逻辑是否正确。

4.3 使用工具辅助调试

工欲善其事,必先利其器。在调试SPI这类时序接口时,有几个工具能极大提升效率:

  • 逻辑分析仪:几十块钱的USB逻辑分析仪配合软件(如Saleae Logic)就能图形化地显示SPI的波形。你可以清晰地看到CS、SCK、MOSI、MISO四路信号,解码出传输的每一个字节,直接对比与你代码预期是否一致。这是定位时序、模式问题的最强手段。
  • 示波器:可以观察信号质量,检查是否有过冲、振铃或电平不标准的问题,特别是SCK频率较高时。
  • 串口打印:在代码关键节点(如发送指令前、等待忙后)通过串口打印状态信息或变量值,是最基础的调试方法。确保你的printf重定向到了串口。

调试过程就像破案,需要根据现象(读不出ID、数据错误)提出假设(线接错了、模式不对、没等忙),然后用工具(逻辑分析仪看波形、串口打印状态)去验证假设。我个人的习惯是,任何新的FLASH芯片,第一件事就是用逻辑分析仪抓取一遍完整的读ID和读数据波形,确保物理层通信100%正确,然后再去啃上层的数据逻辑问题,这样能避免很多无谓的折腾。

STM32单片机基础18——使用硬件QSPI读写SPI Flash(W25Q64) 本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件QSPI外设与 SPI Flash 通信(W25Q64)。 1. 准备工作 硬件准备 开发板 首先需要准备一个开发板,这里我准备的是STM32L4的开发板(BearPi): SPI Flash 小熊派开发板板载一片SPI Flash,型号为 W25Q64,大小为 8 MB,最大支持 80 Mhz的操作频率。... 阅读详情

相关推荐

亲测可用 STM32 CubeMX配置 外置Flash 25Q64 虚拟U盘 以及FatFs 挂载Flash

本文介绍了基于STM32F103C8T6通过SPI2接口连接W25Q64 Flash芯片,并利用USB接口将其虚拟为U盘的实现方案。硬件方面,详细说明了SPI和USB的电路连接要点;软件方面,通过STM32CubeMX配置了时钟、SPI、USB和FatFs文件系统,并重点修改了USB存储接口和文件系统驱动函数。文中提供了完整的代码实现,包括SPI读写函数、W25Q64驱动、USB存储接口适配以及FatFs文件系统接口修改。最后给出了调试过程中可能遇到的问题及解决方案,如U盘无法识别、格式化失败等。

weixin_43895267的博客 1177

STM32CubeMX教程中SPI接口初始化图解说明

通过图文详解SPI接口在STM32CubeMX中的配置与初始化步骤,帮助开发者快速掌握stm32cubemx教程中的关键操作,提升嵌入式开发效率。

weixin_30481539的博客 574

STM32HAL库学习笔记九——LCD显示

本文不会对驱动编写做特别详细的描述,以记录CubeMX的部署流程为主。

weixin_44762233的博客 6918

STM32CubeMX学习笔记(10)——SPI接口使用(读写SPI Flash W25Q64)

一、SPI简介 SPI(Serial Peripheral Interface) 协议是由摩托罗拉公司提出的通讯协议,即串行外围设备接口,是一种高速全双工的通信总线。它被广泛地使用在 ADC、LCD 等设备与 MCU 间,要求通讯速率较高的场合。 芯片的管脚上只占用四根线。 MISO: 主器件数据输出,从器件数据输入。 MOSI:主器件数据输入,从器件数据输出。 SCK: 时钟信号,由主设备控制发出。 NSS(CS): 从设备选择信号,由主设备控制。当NSS为低电平则选中从器件。 二、引脚分布 ST

Leung的博客 3万+

【STM32 CubeMX】SPI HAL库编程

STM32 CubeMX 是一款由 STMicroelectronics 提供的图形化配置工具,用于生成 STM32 微控制器的初始化代码和项目框架。在 STM32 开发中,使用 CubeMX 可以大大简化初始化过程,并帮助开发者快速构建应用程序。其中,SPI(串行外设接口)是一种常用的通信协议,它在连接外部设备时非常有用。本文将介绍如何使用 CubeMX 结合 SPI HAL 库进行 STM32 SPI 的初始化和编程。

m0_62599305的博客 3317

使用STM32进行SPI读写串行FLASH

串行FLASH是其中一种常见的外部设备,它提供了非易失性存储,可以用于存储程序代码、配置信息等。使用STM32CubeMX或者CubeIDE生成初始化代码,选择对应的SPI外设和引脚,并配置SPI模式、时钟速度等参数。类似地,我们还需要编写一个函数,用于向串行FLASH中写入数据。接下来,我们需要编写一个函数,用于从串行FLASH中读取数据。在写入数据之后,我们需要等待串行FLASH完成写入操作,以确保数据被正确写入。通过以上步骤,我们就可以在STM32上实现SPI读写串行FLASH的功能。

ZwcCsharp的博客 259

【STM32】HAL库 STM32CubeMX教程十四---SPI

前言: 本系列教程将HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 在我们的HAL库中,对硬件SPI函数做了很好的集成,使得之前SPI几百行代码,在HAL库中,只需要寥寥几行就可以完成 那么这篇文章将带你去感受下它的优异之处,这些优异的函数,也正是HAL库的优点所在 所用工具: 1、芯片: STM32F103ZET6 2、STM32CubeMx软件 3、IDE:...

Z小旋 12万+

【STM32 CubeMX】SPI_Flash_W25Q64的操作方法

在嵌入式系统开发中,使用外部 SPI Flash 存储器可以为 STM32 微控制器提供额外的存储空间,以存储程序代码、配置数据等。W25Q64 是一款常见的 SPI Flash 存储器,具有64Mb容量和SPI接口。本文将介绍如何使用 STM32 CubeMX 结合 SPI 库与 W25Q64 SPI Flash 进行集成,以便在 STM32 微控制器上实现外部存储器的读写功能。

m0_62599305的博客 2477

STM32Cube学习笔记-SPI通讯

引言 使用STM32Cube开发东西最怕的就是写的代码太多,为什么呢?因为不会写,我深有体会。SPI通讯是一种常用的常用的通讯方式,同步、串行。同步代表着实时性好,串行代表着接线少,很多的设备愿意采用这种方法,废话少说,关于SPI通讯的由来,基本的原理可以百度,我这里介绍用STM32F103ZET6和W25Q64开发SPI通讯。 使用的工具 SMT32F103的开发板,SPI连接了W25Q64的Flash芯片;用到了串口作为调试; 软件是STM32Cube MX,和Keil 5,用到了串口调试助手;.

qq_25207883的博客 7490

STM32CubeMX | 30-使用硬件SPI读写FLASH(W25Q64)

本篇详细的记录了如何使用STM32CubeMX配置 STM32G070RBT6 的硬件SPI外设与 SPI Flash 通信(W25Q64)。 1. 准备工作 硬件准备 开发板 首先需要准备一个开发板,这里我准备的是STM32G070RB的开发板 SPI Flash 开发板板载一片SPI Flash,型号为 W25Q64JV,大小为 8 MB。 软件准备 需要安装好Keil - MDK及芯片对应的包,以便编译和下载生成的代码; 准备一个串口调试助手,这里我使用的是Serial Port Ut

Mculover666的博客(嵌入式) 6250

【STM32Cube-18】使用硬件QSPI读写SPI Flash(W25Q64)

本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件QSPI外设与 SPI Flash 通信(W25Q64)。

Mculover666的博客(嵌入式) 9463

STM32CubeMX教程20 SPI - W25Q128驱动

使用STM32CubeMX软件配置STM32F407开发板的SPI1与W25Q128芯片通信,以轮询方式读写W25Q128 FLASH芯片

lc_guo的博客 4994

【STM32 CubeMX】SPI层次结构SPI协议与SPI控制器结构

随着嵌入式系统的迅猛发展,STM32系列微控制器在各种应用中得到广泛应用。在嵌入式系统设计中,串行外设接口(SPI)是一种常见且重要的通信协议。为了更便捷地配置和使用SPI,STMicroelectronics提供了一款强大的工具——STM32 CubeMX。本文将着重介绍STM32 CubeMX中SPI的层次结构、SPI协议以及SPI控制器的结构。STM32 CubeMX作为一款强大的开发工具,为嵌入式系统设计提供了便利。

m0_62599305的博客 2161

如何用STM32CubeMX快速配置STM32L431RCT6的SPI Flash读写功能

本文详细介绍了如何使用STM32CubeMX图形化工具,为STM32L431RCT6开发板快速配置SPI Flash的读写功能。通过从工程创建、时钟树配置、SPI外设参数设定到代码生成的全流程讲解,帮助开发者高效完成底层硬件初始化,并提供了在Keil环境中编写验证代码的完整示例与调试技巧,大幅提升嵌入式开发效率。

1a2s3d4f5g的博客 1013

【STM32CubeMX学习指南---SPI】

本文介绍了STM32通过SPI接口与CY15B064Q存储芯片的通信配置方法。主要内容包括硬件连接检查、STM32CubeMX中的SPI参数设置(主模式、时钟极性与相位等),以及使用HAL库实现读写操作的代码示例。重点说明了NSS信号管理、字节读写函数实现和注意事项,并提供了完整工程下载链接。适用于需要在STM32平台上驱动CY15B064Q的开发人员参考。

智闲电子设计的博客 1992

基于Python爬虫的新闻热点分析与挖掘

本文介绍了基于Python爬虫的新闻热点分析与挖掘方法,主要包括数据收集、预处理、热点分析和可视化四个部分。首先通过爬虫抓取新浪新闻数据,利用文本清洗和存储技术进行数据预处理;接着采用TF-IDF和LDA算法进行关键词提取与主题建模;最后通过词云图和主题分布图实现数据可视化。该方法能有效识别新闻热点,为信息筛选和决策提供支持。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1544

【STM32学习】基于STM32F411CEU6的USB储存设备

【STM32学习】基于STM32的USB储存设备 1. 实现动机 最近打算做一下lvgl在stm32上的移植,考虑到lvgl可能会用到一些图片资源,这样一来文件系统就很有必要了,于是想在手头的一块小板子上实现一下FatFs和USB Mass Storage Class,利用板上的FLASH芯片存储文件。其实大部分的工作都是由STM32CubeMX这个软件实现的。 2. 硬件平台 这里使用的是WeAct Studio的STM32F411CEU6核心板,长这个样子: 下面还有两张实物图, 这是正面。USB接口

Slade99X的博客 9904

HBF凭什么能挑战HBM?

最近AI圈聊得最多的,除了大模型迭代,就是“算力瓶颈”。大家都知道GPU不够用、HBM抢疯了,但很少有人注意到,存储层正在酝酿一场革命——高带宽闪存(HBF)。今天就结合HBM之父Joungho Kim教授的最新观点,跟大家好好盘盘这门技术:它不是HBM的替代品,却可能重塑AI推理的游戏规则,甚至在2038年超越HBM市场规模。先澄清一个核心认知:HBF不是凭空冒出来的新技术,而是站在HBM肩膀上的“优化款”。

存储随笔 2130

【STM32】HAL库中的实现(九):SPI(串行外设接口)

SPI(Serial Peripheral Interface)是一种全双工主从通信协议,采用4线制(SCK时钟、MOSI主发从收、MISO主收从发、CS片选),支持多从机连接。W25Qxx系列SPI Flash存储器(如W25Q64)具有大容量、长寿命特性。本文通过STM32 HAL库实现了SPI驱动W25Qxx的完整方案。

猫猫的小茶馆 2564

ADS2016子电路封装避坑指南:手把手教你制作可复用的自定义Symbol

本文详细介绍了在ADS2016中制作可复用的自定义Symbol的全流程,重点解析了子电路封装的常见问题与解决方案。从电路模块的标准化处理、Hierarchy创建技巧到Symbol视觉优化和库管理策略,帮助工程师提升射频与微波电路设计效率。特别针对Symbol比例适配和引脚优化等核心问题,提供了实用的避坑指南和工程验证方法。

weixin_30275415的博客 212

OpenWrt南京电信PPPoE IPv6配置:从零搭建稳定双栈网络

本文详细指导如何在南京电信PPPoE宽带环境下,为OpenWrt路由器配置稳定的IPv6双栈网络。核心在于正确设置WAN6接口为DHCPv6客户端,并请求/60前缀,同时配置LAN口分发地址并放行防火墙关键流量,确保内网设备获得原生IPv6连接。

water的专栏 1339

STM32CubeMX学习笔记(39)——FSMC接口使用(TFT-LCD屏触摸)

一、TFT-LCD简介 TFT-LCD(Thin Film Transistor-Liquid Crystal Display) 即薄膜晶体管液晶显示器。TFT-LCD 与无源 TN-LCD、 STN-LCD 的简单矩阵不同,它在液晶显示屏的每一个象素上都设置有一个薄膜晶体管(TFT),可有效地克服非选通时的串扰,使显示液晶屏的静态特性与扫描线数无关,因此大大提高了图像质量。 TFT-LCD 也被叫做真彩液晶显示器。 虽然TFT-LCD被统称为LCD,不过它是种主动式矩阵LCD,被应用在电视、平面显示器及

Leung的博客 1万+

深入解析STM32F103R6的USB OTG_FS双重角色设备(DRD)设计与应用

本文深入解析了STM32F103R6的USB OTG_FS双重角色设备(DRD)设计与应用。详细阐述了其作为USB主机和设备双重角色的硬件设计要点,包括VBUS电源管理与ID引脚配置,并提供了设备模式(如虚拟串口CDC)与主机模式(如读取U盘文件)的软件实现实战指南,帮助开发者充分发挥该芯片的OTG潜力。

weixin_29195615的博客 265
上一篇: 深入解析恒烁CX32L003单片机的GPIO配置与LED控制实践
下一篇: uniapp与Flutter跨平台交互实战:H5页面与原生应用的数据通信
python9snake
博客等级 码龄1天 0粉丝 1724原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值