硬汉嵌入式论坛

 找回密码
 立即注册
查看: 724|回复: 7
收起左侧

[SPI/QSPI] 求助:H743 QSPI无法擦除W25Q64

[复制链接]

1

主题

8

回帖

11

积分

新手上路

积分
11
发表于 2025-3-16 21:15:15 | 显示全部楼层 |阅读模式
MCU:STM32H743IIT6



开发环境:STM32CUBEMX + Keil

操作步骤:
1、读3个状态寄存器
2、写使能(1cmd-1addr-1data    cmd:0x06)
3、3个状态寄存器
4、页擦除,擦除地址0x00000000(1cmd-1addr-1data    cmd:0x20),delay 100ms
5、while(1)里面5ms读一次地址0x00000000的数据(length = 128)(1cmd-1addr-4data    cmd:0x6B)

问题描述:
在步骤1读出来的寄存器(reg1:SRP = 1,其他为0   reg2:SUS = 1,其他为0),在步骤2写使能过后,步骤3再去读状态寄存器没有任何变化,在步骤4擦除后,读出来的数据并没有被擦除

疑问点:
1、步骤3的寄存器为什么没有变化?WEL寄存器不应该要为1吗
2、关于W25Q64接线的问题,WP(写保护)引脚是低电平有效,但是在开发板上并没有硬件上拉,而是直连MCU的IO口,作为QSPI的IO2使用,那岂不是一直处于硬件写保护吗,个人感觉这里出问题的可能性最大,如果真是这个问题,有没有什么解决办法吗?

关键代码:

void W25Q64_EnableWrite(void)/* 1cmd-1addr-1data */
{
    QSPI_AutoPollingTypeDef st_config = {0u};
    /* 基本配置 */
    st_cmdQSPI.InstructionMode =            QSPI_INSTRUCTION_1_LINE;          /* 1 线方式发送指令 */
    st_cmdQSPI.AddressSize =                QSPI_ADDRESS_24_BITS;             /* 24 位地址 */
    st_cmdQSPI.AlternateByteMode =          QSPI_ALTERNATE_BYTES_NONE;        /* 无交替字节 */
    st_cmdQSPI.DdrMode =                    QSPI_DDR_MODE_DISABLE;            /* W25Q256JV 不支持 DDR */
    st_cmdQSPI.DdrHoldHalfCycle =           QSPI_DDR_HHC_ANALOG_DELAY;        /* DDR 模式,数据输出延迟 */
    st_cmdQSPI.SIOOMode =                   QSPI_SIOO_INST_EVERY_CMD;         /* 每次传输要发指令 */
    /* 读取数据 */
    st_cmdQSPI.Instruction =                W25Q64_CMD_WRITE_ENABLE;
    st_cmdQSPI.DummyCycles =                0u;                                 /* 空周期 */
    st_cmdQSPI.AddressMode =                QSPI_ADDRESS_NONE;                  /* 没有地址 */
    st_cmdQSPI.DataMode =                   QSPI_DATA_NONE;                     /* 没有数据 */
    st_cmdQSPI.NbData =                     0u;                                 /*  */
    st_cmdQSPI.Address =                    0u;                                 /* 读取数据的起始地址 */
    if (HAL_QSPI_Command(&hqspi, &st_cmdQSPI, 10000) != HAL_OK)
    {

    }
}



void W25Q64_EraseOneSector(uint32_t u32_addr)/* 1cmd-1addr-1data */
{
    W25Q64_ReadStatusReg();
    W25Q64_EnableWrite();
    W25Q64_ReadStatusReg();
    /* 基本配置 */
    st_cmdQSPI.InstructionMode =            QSPI_INSTRUCTION_1_LINE;          /* 1 线方式发送指令 */
    st_cmdQSPI.AddressSize =                QSPI_ADDRESS_24_BITS;             /* 24 位地址 */
    st_cmdQSPI.AlternateByteMode =          QSPI_ALTERNATE_BYTES_NONE;        /* 无交替字节 */
    st_cmdQSPI.DdrMode =                    QSPI_DDR_MODE_DISABLE;            /* W25Q256JV 不支持 DDR */
    st_cmdQSPI.DdrHoldHalfCycle =           QSPI_DDR_HHC_ANALOG_DELAY;        /* DDR 模式,数据输出延迟 */
    st_cmdQSPI.SIOOMode =                   QSPI_SIOO_INST_EVERY_CMD;         /* 每次传输要发指令 */
    /* 读取数据 */
    st_cmdQSPI.Instruction =                W25Q64_CMD_ERASE_SECTOR;
    st_cmdQSPI.DummyCycles =                6u;                                 /* 空周期 */
    st_cmdQSPI.AddressMode =                QSPI_ADDRESS_1_LINE;                /* 1 线地址 */
    st_cmdQSPI.DataMode =                   QSPI_DATA_NONE;                     /* 没有数据 */
    st_cmdQSPI.NbData =                     0u;                             /* 读取的数据大小 */
    st_cmdQSPI.Address =                    u32_addr;                       /* 擦除数据的起始地址 */

    if (HAL_QSPI_Command(&hqspi, &st_cmdQSPI, 10000) != HAL_OK)
    {
        bool_QSPI_SendFail = 1u;
    }
}



void W25Q64_ReadBuffer(uint8_t *pBuff,uint32_t u32_readAddr,uint16_t u16_length)/* 1 1 4 */
{
    /* 基本配置 */
    st_cmdQSPI.InstructionMode =            QSPI_INSTRUCTION_1_LINE;          /* 1 线方式发送指令 */
    st_cmdQSPI.AddressSize =                QSPI_ADDRESS_24_BITS;             /* 24 位地址 */
    st_cmdQSPI.AlternateByteMode =          QSPI_ALTERNATE_BYTES_NONE;        /* 无交替字节 */
    st_cmdQSPI.DdrMode =                    QSPI_DDR_MODE_DISABLE;            /* W25Q256JV 不支持 DDR */
    st_cmdQSPI.DdrHoldHalfCycle =           QSPI_DDR_HHC_ANALOG_DELAY;        /* DDR 模式,数据输出延迟 */
    st_cmdQSPI.SIOOMode =                   QSPI_SIOO_INST_EVERY_CMD;         /* 每次传输要发指令 */
    /* 读取数据 */
    st_cmdQSPI.Instruction =                W25Q64_CMD_READ_BY_ADDRESS;
    st_cmdQSPI.DummyCycles =                6u;                                 /* 空周期 */
    st_cmdQSPI.AddressMode =                QSPI_ADDRESS_1_LINE;                /* 1 线地址 */
    st_cmdQSPI.DataMode =                   QSPI_DATA_4_LINES;                  /* 4 线数据 */
    st_cmdQSPI.NbData =                     u16_length;                         /* 读取的数据大小 */
    st_cmdQSPI.Address =                    u32_readAddr;                       /* 读取数据的起始地址 */

    if (HAL_QSPI_Command(&hqspi, &st_cmdQSPI, 10000) != HAL_OK)
    {
        bool_QSPI_SendFail = 1u;
    }
    /* 读取 */
    if (HAL_QSPI_Receive(&hqspi, pBuff, 10000) != HAL_OK)
    {
        bool_QSPI_SendFail = 1u;
    }
}




回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117530
QQ
发表于 2025-3-17 05:40:57 | 显示全部楼层
楼主的这个驱动代码,读取QSPI Flash的ID正常不。
回复

使用道具 举报

5

主题

229

回帖

249

积分

高级会员

积分
249
发表于 2025-3-17 08:42:44 | 显示全部楼层
本帖最后由 旮旯旭 于 2025-3-17 08:52 编辑

bsp_w25qxx_qspi.c (18.82 KB, 下载次数: 4)
bsp_w25qxx_qspi.h (6.94 KB, 下载次数: 1)
你的函数W25Q64_EnableWrite处理有问题,06命令还需要发送数据,你只处理了命令,数据是寄存器REG1:S1下的WEL需要使能
代码给你参考下

回复

使用道具 举报

1

主题

8

回帖

11

积分

新手上路

积分
11
 楼主| 发表于 2025-3-17 21:26:30 | 显示全部楼层
eric2013 发表于 2025-3-17 05:40
楼主的这个驱动代码,读取QSPI Flash的ID正常不。

试了一下,似乎不太对
回复

使用道具 举报

1

主题

8

回帖

11

积分

新手上路

积分
11
 楼主| 发表于 2025-3-17 21:29:10 | 显示全部楼层
鼓捣好几天没调好,附件上传了,希望有空的大佬能指点一下

bootloader.7z

2.12 MB, 下载次数: 1

回复

使用道具 举报

1

主题

8

回帖

11

积分

新手上路

积分
11
 楼主| 发表于 2025-3-17 21:29:39 | 显示全部楼层
旮旯旭 发表于 2025-3-17 08:42
你的函数W25Q64_EnableWrite处理有问题,06命令还需要发送数据,你只处理了命令,数据是寄存器REG1:S1 ...

直接复制你的,还是不行
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117530
QQ
发表于 2025-3-18 08:50:34 | 显示全部楼层
Marlboro 发表于 2025-3-17 21:26
试了一下,似乎不太对

那这个不行,考虑先检测下硬件,要保证先可以正确读取ID
回复

使用道具 举报

0

主题

9

回帖

9

积分

新手上路

积分
9
发表于 2025-3-18 10:03:15 | 显示全部楼层
根据描述,reg1:SRP = 1,其他为0   reg2:SUS = 1,其他为0。状态寄存器2里面有一个bit为QE,它现在是0。QE为0时,/HOLD或/RESET这个脚功能是起作用的,而不是IO3。如果IO3是低电平,这个Flash应该是复位状态,又不应该能读到状态寄存器的值。
建议:
1.确认一下Flash型号,后缀为SIM的QE出厂为0,SIQ出厂为1。
2.如果不确定,可以将IO3配成普通IO,用2线或者SPI读一下状态寄存器2。如果QE为0,建议写成1,或者你用2线也没什么问题。
3.没有以上问题,先读一下器件ID,看看是否是和手册上一致,确保硬件IO口没什么问题。
4.使用逻辑分析仪,看数据和IO状态很方便。数据流程有问题能直观看出来。有时候比看代码找问题来的快。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 20:42 , Processed in 0.047405 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表