GD32通过SPI和QSPI模式读取GD的NOR Flash

简介: GD32通过SPI和QSPI模式读取GD的NOR Flash

基于GD32微控制器通过SPI和QSPI模式读取GD的NOR Flash,并支持DMA模式和文件系统的实现方案:

硬件连接

以GD32F303为例,其SPI接口与NOR Flash的连接方式如下:

  • NOR Flash的片选信号(CS)连接到GD32的某个GPIO引脚(如PG14),因为PG14不是SPI的NSS管脚,所以需要使用主机NSS软件模式。
  • NOR Flash的SO(数据输出)、SI(数据输入)和SCLK(时钟信号)分别连接到GD32的SPI2_MISO(PB4)、SPI2_MOSI(PB5)和SPI2_CLK(PB3)。

SPI/QSPI初始化

  1. SPI初始化:配置SPI接口的参数,如时钟极性、数据位顺序、帧大小等。例如,设置为全双工模式、8位数据帧格式、硬件NSS管理等。

    void driver_spi_init(typdef_spi_struct *spix)
    {
         
        spi_parameter_struct spi_init_struct;
        rcu_periph_clock_enable(spix->rcu_spi_x);
        spi_i2s_deinit(spix->spi_x);
        driver_gpio_general_init(spix->spi_cs_gpio);
        driver_gpio_general_init(spix->spi_sck_gpio);
        driver_gpio_general_init(spix->spi_mosi_gpio);
        driver_gpio_general_init(spix->spi_miso_gpio);
        if(spix->spi_mode==MODE_DMA)
        {
         
            if(spix->spi_rx_dma!=NULL)
            {
         
                if(spix->frame_size==SPI_FRAMESIZE_8BIT)
                {
         
                    driver_dma_com_init(spix->spi_rx_dma,(uint32_t)&SPI_DATA(spix->spi_x),NULL,DMA_Width_8BIT,DMA_PERIPHERAL_TO_MEMORY);
                }
                else
                {
         
                    driver_dma_com_init(spix->spi_rx_dma,(uint32_t)&SPI_DATA(spix->spi_x),NULL,DMA_Width_16BIT,DMA_PERIPHERAL_TO_MEMORY);
                }
            }
            if(spix->spi_tx_dma!=NULL)
            {
         
                if(spix->frame_size==SPI_FRAMESIZE_8BIT)
                {
         
                    driver_dma_com_init(spix->spi_tx_dma,(uint32_t)&SPI_DATA(spix->spi_x),NULL,DMA_Width_8BIT,DMA_MEMORY_TO_PERIPH);
                }
                else
                {
         
                    driver_dma_com_init(spix->spi_tx_dma,(uint32_t)&SPI_DATA(spix->spi_x),NULL,DMA_Width_16BIT,DMA_MEMORY_TO_PERIPH);
                }
            }
        }
        spi_struct_para_init(&spi_init_struct);
        spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
        spi_init_struct.device_mode = spix->device_mode;
        // 其他参数配置...
        spi_init(spix->spi_x, &spi_init_struct);
        spi_enable(spix->spi_x);
    }
    
  2. QSPI初始化:QSPI的初始化与SPI类似,但QSPI支持更多的数据线和更高的传输速率。以GD32H7为例,其QSPI接口支持四线SPI功能,可以显著提高数据传输速率。

  3. GD32通过SPI和QSPI模式读取GD的NOR Flash,支持DMA模式,和文件系统 代码。

NOR Flash读写操作

  1. 读取操作:通过SPI或QSPI发送读取指令和地址,然后接收数据。例如,使用SPI读取NOR Flash的代码如下:

    void W25QXX_Read(unsigned char* pBuffer,uint32_t ReadAddr,uint16_t NumByteToRead)
    {
         
        gpio_bit_reset(GPIOA,GPIO_PIN_4); // 拉低片选信号
        QSPI_Send_CMD(W25X_FastReadQuad); // 发送快速读取指令
        QSPI_Send_DAT((unsigned char)(ReadAddr>>16)); // 发送地址的高字节
        QSPI_Send_DAT((unsigned char)(ReadAddr>>8)); // 发送地址的中字节
        QSPI_Send_DAT((unsigned char)ReadAddr); // 发送地址的低字节
        QSPI_Receive(pBuffer,NumByteToRead); // 接收数据
        gpio_bit_set(GPIOA,GPIO_PIN_4); // 拉高片选信号
    }
    
  2. 写入操作:写入操作需要先发送写使能指令,然后发送写入指令和地址,最后发送数据。需要注意的是,NOR Flash的写入操作不能跨页,一次最多写入一页。

DMA模式支持

  1. DMA配置:在SPI或QSPI的初始化函数中,配置DMA的相关参数,如内存地址、传输方向、数据宽度等。

    if(spix->frame_size==SPI_FRAMESIZE_8BIT)
    {
         
        driver_dma_com_init(spix->spi_rx_dma,(uint32_t)&SPI_DATA(spix->spi_x),NULL,DMA_Width_8BIT,DMA_PERIPHERAL_TO_MEMORY);
    }
    else
    {
         
        driver_dma_com_init(spix->spi_rx_dma,(uint32_t)&SPI_DATA(spix->spi_x),NULL,DMA_Width_16BIT,DMA_PERIPHERAL_TO_MEMORY);
    }
    
  2. DMA传输:在读写操作中,启动DMA传输,DMA会在后台自动完成数据的传输,无需CPU干预,从而提高系统的效率。

文件系统支持

  1. 文件系统初始化:使用文件系统(如FATFS)来组织和管理存储在NOR Flash中的数据。首先需要初始化文件系统,挂载存储设备。

    FATFS fs;
    FRESULT res = f_mount(&fs, "", 1); // 挂载文件系统
    
  2. 文件操作:通过文件系统提供的API进行文件的创建、读写、删除等操作。例如,创建一个文件并写入数据:

    FIL file;
    res = f_open(&file, "test.txt", FA_CREATE_ALWAYS | FA_WRITE); // 打开文件
    if(res == FR_OK)
    {
         
        char data[] = "Hello, GD32!";
        f_write(&file, data, sizeof(data), &bytes_written); // 写入数据
        f_close(&file); // 关闭文件
    }
    

通过以上步骤,可以实现GD32微控制器通过SPI和QSPI模式读取GD的NOR Flash,并支持DMA模式和文件系统。

相关文章
|
存储 算法 安全
【Freertos基础入门】队列(queue)的使用
【Freertos基础入门】队列(queue)的使用
1217 0
|
存储 安全 API
基于FreeRTOS中的串口不定长接收(使用队列进行数据传输)
基于FreeRTOS中的串口不定长接收(使用队列进行数据传输)
1483 0
【LVGL快速入门】SquareLine Studio安装教程(LVGL官方工具)
【LVGL快速入门】SquareLine Studio安装教程(LVGL官方工具)
3488 0
|
11月前
|
IDE 编译器 开发工具
【C语言】全面系统讲解 `#pragma` 指令:从基本用法到高级应用
在本文中,我们系统地讲解了常见的 `#pragma` 指令,包括其基本用法、编译器支持情况、示例代码以及与传统方法的对比。`#pragma` 指令是一个强大的工具,可以帮助开发者精细控制编译器的行为,优化代码性能,避免错误,并确保跨平台兼容性。然而,使用这些指令时需要特别注意编译器的支持情况,因为并非所有的 `#pragma` 指令都能在所有编译器中得到支持。
1017 41
【C语言】全面系统讲解 `#pragma` 指令:从基本用法到高级应用
基于智能电网系统的PQ并网控制器simulink建模与仿真
在MATLAB 2022a的Simulink环境中构建智能电网PQ并网控制器模型,实现对并网三相电压电流的精确控制及其收敛输出。PQ控制器根据实时需求调节有功与无功功率,确保电力系统稳定。通过测量、计算、比较、控制和执行五大环节,实现PQ参考值的跟踪,保证电能质量和系统稳定性。广泛适用于可再生能源并网场景。
基于智能电网系统的PQ并网控制器simulink建模与仿真
|
10月前
|
存储 负载均衡 NoSQL
搭建高可用及负载均衡的Redis
通过本文介绍的高可用及负载均衡Redis架构,可以有效提升Redis服务的可靠性和性能。主从复制、哨兵模式、Redis集群以及负载均衡技术的结合,使得Redis系统在应对高并发和数据一致性方面表现出色。这些配置和技术不仅适用于小型应用,也能够支持大规模企业级应用的需求。希望本文能够为您的Redis部署提供实用指导和参考。
778 9
|
数据库连接 C++
什么是RAII原则
【10月更文挑战第19天】什么是RAII原则
462 1
|
11月前
|
Unix Linux 开发工具
git中有关old mode 100644、new mode 10075的问题解决小结
在 Git 中处理文件权限变更时,理解 `old mode 100644` 和 `new mode 100755` 的含义是解决问题的关键。通过确认变更的合理性、修改不必要的权限变更,以及配置 Git 忽略权限变更,可以有效管理文件权限,确保版本库的稳定性和一致性。
1192 3
【总结】单片机重点知识总结记录之Keil相对路径(四)
【总结】单片机重点知识总结记录之Keil相对路径(四)
464 0