QSPI驱动移植

由于要用到下载算法,需要先编写QSPI驱动并验证,这一章节使用CubeMx快速验证

Cubemx创建工程如下(只使用到QSPI,理论上工程越简单越好,能驱动QSPI就行,用Cubemx快速驱动起来)

QSPI flash最大频率133Mhz,在cubemx中配置为120Mhz

  • 使用外部晶振25M
  • 开启时钟480M
  • 使用SYSTICK时基

QSPI配置如下

image-20231014000859800

image-20231014000946951

具体参数配置如下

image-20230722141507243

时钟极性 CPOL

Low: 这意味着当QSPI总线处于空闲状态时,时钟线的电平为低。这对应于CPOL = 0。
High: 这意味着当QSPI总线处于空闲状态时,时钟线的电平为高。这对应于CPOL = 1。

目前编直接写qspi驱动较困难,先找一个现成的移植看看,使用反客家的例程进行修改

该驱动带有QSPI初始化,可能引脚不一样, 我们使用自己的,将它屏蔽掉(懒得改)

image-20231014001449197

哈哈我看到了什么,但是实话实说,安富莱的代码非常工整且有好多干货,

image-20231014001557908

稍微修改以后调用初始化进行验证,由于我没有使能串口,就直接使用软件仿真了

调用初始化函数

image-20231014001955521

image-20231014002136118

仿真验证读取ID一致

image-20231014002322866

接下来验证一下擦除,读写以及内存映射模式,提供了以下函数

image-20231014002939642

编写qspi的测试,仿真测试ok的

image-20231014005229942

data_checkou t函数如下,每隔4K验证一个字节,首先写进去,再逐字节读取对比, 成功之后进入内存映射模式再逐字节读取验证 ,验证成功返回0,在上面的函数中仿真可以执行到 state =3; 证明无误, 并没有全部读写验证, 太浪费时间了

#define  QSPI_FLASH_SIZE  (8 * 1024 * 1024)  // 8M字节
#define  INTERVAL         (4 * 1024)         // 4K字节
#define  QSPI_BASE_ADDR   0x90000000UL


int data_checkout(void)
{
    uint8_t writeData = 0xAA;  // 写入的数据
    uint8_t readData;          // 用于存储读取的数据
    int8_t status;             // 用于存储函数的返回状态

    // 遍历整个Flash,每隔4K字节写入数据
    for (uint32_t addr = 0; addr < QSPI_FLASH_SIZE; addr += INTERVAL) {
        status = QSPI_W25Qxx_WriteBuffer(&writeData, addr, 1);  // 写入1字节数据
        if (status != QSPI_W25Qxx_OK) {
            
            return -1;
        }
    }

    // 遍历整个Flash,每隔4K字节读取并验证数据
    for (uint32_t addr = 0; addr < QSPI_FLASH_SIZE; addr += INTERVAL) {
        status = QSPI_W25Qxx_ReadBuffer(&readData, addr, 1);  // 读取1字节数据
        if (status != QSPI_W25Qxx_OK) {
            
            return -1;
        }

        if (readData != writeData) {
            
            return -1;
        }
    }

        
         // 开启内存映射模式
    status = QSPI_W25Qxx_MemoryMappedMode();
    if (status != QSPI_W25Qxx_OK) {
        return -1;
    }

    // 使用内存映射模式验证数据
    for (uint32_t addr = 0; addr < QSPI_FLASH_SIZE; addr += INTERVAL) {
        readData = *(uint8_t *)(QSPI_BASE_ADDR + addr);
        if (readData != writeData) {
            return -1;
        }
    }
   
    return 0;


}
如果觉得我的文章对你有用,请随意赞赏