GD25Qxx芯片详解

一、GD25Qxx芯片简单介绍

  • W25Q64存储容量共 :64M-bit/ 8M-byte
  • W25Q128存储容量共 :128M-bit / 16M-Byte 
  • 页:256 Bytes
  • 扇区:16 Pages(4KB)
  • 块:16 Sector(64KB)
  • High Speed Clock Frequency (SPI最大时钟频率)
  • - 133MHz for fast read with 30PF load 
  • - Dual I/O Data transfer up to 266Mbits/s 
  • - Quad I/O Data transfer up to 532Mbits/s 
  • 双倍SPI指令:使用”Fast Read Dual Output and Dual I/O(3B和BBhex)”指令支持双倍速SPI操作。这些指令允许数据以正常速度的两到三倍的在设备间传输。双倍读指令适用于 上电时快速加载代码到RAM 或者 直接从SPI总线上执行代码(XIP) 的情形。当使用双倍速SPI指令时,DI和DO引脚将充当 IO 0和IO 1.
  • 四倍速SPI指令:使用”Fast Read Quad Output”、” Fast Read Quad I/O” 、”Word Read Quad I/O” 和 “Octal Word Quad I/O”指令(6B、EB、E7、E3)支持四倍速SPI操作。这些指令允许数据以正常速度的四到六倍的在设备间传输。四倍读指令显著提升连续和随机访问传输速度,这速度满足将代码快速加载到RAM或者直接在SPI总线上执行(XIP)。使用四倍速SPI指令时,DI和DO引脚将充当 IO 0和IO 1 ,WP和HOLD充当IO2 和IO 3。四倍速SPI指令要求状态寄存器2中的QE功能位打开
  • 数据写入的时候只能按照Page来写入,最多一次只能写256个字节,也就是一个页的空间。每次写入都要先擦除
  • 数据擦除只能按扇区擦除或按块擦除。可以按 16 页一组(4KB 扇区擦除)、128 页一组(32KB 块擦除)、256 页一组(64KB 块擦除)或者整片擦除(chip erase)。

二、如何读取FLASH_ID

#define SFLASH_ID                0xC83015	//W25X16
#define SFLASH_ID                0xC84015	//W25Q16
#define SFLASH_ID                0xC84018	//W25Q128

三、标准SPI读写代码

offChipFlash.h

#ifndef __OFFCHIPFLASH_H
#define __OFFCHIPFLASH_H

#include "head.h"

#define  SPI_FLASH_PAGE_SIZE       0x100
#define  SPI_FLASH_CS_LOW()        gpio_bit_reset(GPIOA,GPIO_PIN_15)
#define  SPI_FLASH_CS_HIGH()       gpio_bit_set(GPIOA,GPIO_PIN_15)


void spi_flash_init(void);
uint32_t spi_flash_read_id(void);
void spi_flash_sector_erase(uint32_t sector_addr);
void spi_flash_buffer_write(uint8_t* pbuffer, uint32_t write_addr, uint16_t num_byte_to_write);
void spi_flash_buffer_read(uint8_t* pbuffer, uint32_t read_addr, uint16_t num_byte_to_read);

#endif

offChipFlash.c

#include "offChipFlash.h"

#define WRITE            0x02     /* write to memory instruction */
#define QUADWRITE        0x32     /* quad write to memory instruction */
#define WRSR             0x01     /* write status register instruction */
#define WREN             0x06     /* write enable instruction */

#define READ             0x03     /* read from memory instruction */
#define QUADREAD         0x6B     /* read from memory instruction */
#define RDSR             0x05     /* read status register instruction */
#define RDID             0x9F     /* read identification */

#define SE               0x20     /* sector erase instruction */
#define BE               0xC7     /* bulk erase instruction */

#define WIP_FLAG         0x01     /* write in progress(wip) flag */

#define DUMMY_BYTE       0xA5

void spi_flash_init(void)
{
    spi_parameter_struct spi_init_struct;
    rcu_periph_clock_enable(RCU_GPIOA);
	rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_SPI2);

    gpio_af_set(GPIOB, GPIO_AF_6, GPIO_PIN_3|GPIO_PIN_4| GPIO_PIN_5);
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE,  GPIO_PIN_3|GPIO_PIN_4| GPIO_PIN_5);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ,  GPIO_PIN_3|GPIO_PIN_4| GPIO_PIN_5);

    gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_15);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_15);

    /* chip select invalid */
    SPI_FLASH_CS_HIGH();

    /* SPI2 parameter config */
    spi_init_struct.trans_mode           = SPI_TRANSMODE_FULLDUPLEX;
    spi_init_struct.device_mode          = SPI_MASTER;
    spi_init_struct.frame_size           = SPI_FRAMESIZE_8BIT;
    spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
    spi_init_struct.nss                  = SPI_NSS_SOFT;
    spi_init_struct.prescale             = SPI_PSC_32;
    spi_init_struct.endian               = SPI_ENDIAN_MSB;
    spi_init(SPI2, &spi_init_struct);

    spi_enable(SPI2);
}

uint32_t spi_flash_read_id(void)
{
    uint32_t temp = 0, temp0 = 0, temp1 = 0, temp2 = 0;

    /* select the flash: chip select low */
    SPI_FLASH_CS_LOW();

    /* send "RDID " instruction */
    spi_flash_send_byte(RDID);

    /* read a byte from the flash */
    temp0 = spi_flash_send_byte(DUMMY_BYTE);

    /* read a byte from the flash */
    temp1 = spi_flash_send_byte(DUMMY_BYTE);

    /* read a byte from the flash */
    temp2 = spi_flash_send_byte(DUMMY_BYTE);

    /* deselect the flash: chip select high */
    SPI_FLASH_CS_HIGH();

    temp = (temp0 << 16) | (temp1 << 8) | temp2;

    return temp;
}

void spi_flash_sector_erase(uint32_t sector_addr)
{
    /* send write enable instruction */
    spi_flash_write_enable();

    /* sector erase */
    /* select the flash: chip select low */
    SPI_FLASH_CS_LOW();
    /* send sector erase instruction */
    spi_flash_send_byte(SE);
    /* send sector_addr high nibble address byte */
    spi_flash_send_byte((sector_addr & 0xFF0000) >> 16);
    /* send sector_addr medium nibble address byte */
    spi_flash_send_byte((sector_addr & 0xFF00) >> 8);
    /* send sector_addr low nibble address byte */
    spi_flash_send_byte(sector_addr & 0xFF);
    /* deselect the flash: chip select high */
    SPI_FLASH_CS_HIGH();

    /* wait the end of flash writing */
    spi_flash_wait_for_write_end();
}

void spi_flash_buffer_write(uint8_t* pbuffer, uint32_t write_addr, uint16_t num_byte_to_write)
{
    uint8_t num_of_page = 0, num_of_single = 0, addr = 0, count = 0, temp = 0;

    addr          = write_addr % SPI_FLASH_PAGE_SIZE;
    count         = SPI_FLASH_PAGE_SIZE - addr;
    num_of_page   = num_byte_to_write / SPI_FLASH_PAGE_SIZE;
    num_of_single = num_byte_to_write % SPI_FLASH_PAGE_SIZE;

    /* write_addr is SPI_FLASH_PAGE_SIZE aligned */
    if(0 == addr){
        /* num_byte_to_write < SPI_FLASH_PAGE_SIZE */
        if(0 == num_of_page){
            spi_flash_page_write(pbuffer,write_addr,num_byte_to_write);
        }else{
            /* num_byte_to_write >= SPI_FLASH_PAGE_SIZE */
            while(num_of_page--){
                spi_flash_page_write(pbuffer,write_addr,SPI_FLASH_PAGE_SIZE);
                write_addr += SPI_FLASH_PAGE_SIZE;
                pbuffer += SPI_FLASH_PAGE_SIZE;
            }
            spi_flash_page_write(pbuffer,write_addr,num_of_single);
        }
    }else{
        /* write_addr is not SPI_FLASH_PAGE_SIZE aligned */
        if(0 == num_of_page){
            /* (num_byte_to_write + write_addr) > SPI_FLASH_PAGE_SIZE */
            if(num_of_single > count){
                temp = num_of_single - count;
                spi_flash_page_write(pbuffer,write_addr,count);
                write_addr += count;
                pbuffer += count;
                spi_flash_page_write(pbuffer,write_addr,temp);
            }else{
                spi_flash_page_write(pbuffer,write_addr,num_byte_to_write);
            }
        }else{
            /* num_byte_to_write >= SPI_FLASH_PAGE_SIZE */
            num_byte_to_write -= count;
            num_of_page = num_byte_to_write / SPI_FLASH_PAGE_SIZE;
            num_of_single = num_byte_to_write % SPI_FLASH_PAGE_SIZE;

            spi_flash_page_write(pbuffer,write_addr, count);
            write_addr += count;
            pbuffer += count;

            while(num_of_page--){
                spi_flash_page_write(pbuffer,write_addr,SPI_FLASH_PAGE_SIZE);
                write_addr += SPI_FLASH_PAGE_SIZE;
                pbuffer += SPI_FLASH_PAGE_SIZE;
            }

            if(0 != num_of_single){
                spi_flash_page_write(pbuffer,write_addr,num_of_single);
            }
        }
    }
}

void spi_flash_buffer_read(uint8_t* pbuffer, uint32_t read_addr, uint16_t num_byte_to_read)
{
    /* select the flash: chip slect low */
    SPI_FLASH_CS_LOW();

    /* send "read from memory " instruction */
    spi_flash_send_byte(READ);

    /* send read_addr high nibble address byte to read from */
    spi_flash_send_byte((read_addr & 0xFF0000) >> 16);
    /* send read_addr medium nibble address byte to read from */
    spi_flash_send_byte((read_addr& 0xFF00) >> 8);
    /* send read_addr low nibble address byte to read from */
    spi_flash_send_byte(read_addr & 0xFF);

    /* while there is data to be read */
    while(num_byte_to_read--){
        /* read a byte from the flash */
        *pbuffer = spi_flash_send_byte(DUMMY_BYTE);
        /* point to the next location where the byte read will be saved */
        pbuffer++;
    }

    /* deselect the flash: chip select high */
    SPI_FLASH_CS_HIGH();
}

main.c

#include "head.h"

#define BUFFER_SIZE              256
#define FLASH_WRITE_ADDRESS      0x000000
uint8_t tx_buffer[256];
uint8_t rx_buffer[256];

int main(void)
{
    systick_config();//时钟配置
	gd_485_com_init(PCS_COM,9600);
	gd_485_com_en(1);//发送使能
	
    spi_flash_init();
	
    while(1)
	{
        for(int i = 0; i < BUFFER_SIZE; i++) {tx_buffer[i] = i;}
        spi_flash_sector_erase(FLASH_WRITE_ADDRESS);
        spi_flash_buffer_write(tx_buffer, FLASH_WRITE_ADDRESS, BUFFER_SIZE);
        delay_1ms(10);
        spi_flash_buffer_read(rx_buffer, FLASH_WRITE_ADDRESS, BUFFER_SIZE);
		for(int i = 0; i < BUFFER_SIZE; i++) {printf("0x%x",rx_buffer[i]);}
		printf("\r\n");
	}
}


  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
gd25q128是一款常见的串行闪存芯片,广泛应用于各种电子设备中。它的主要特点是容量大、读写速度快以及稳定性高。为了能够充分发挥gd25q128的功能,需要安装相应的驱动程序。 gd25q128的驱动程序可以通过厂家官方网站下载获取。在下载驱动程序之前,首先要确定操作系统的版本和架构(32位或64位),以确保下载的驱动程序与操作系统兼容。一旦确定了正确的驱动程序版本,就可以下载并解压驱动文件。 安装gd25q128驱动程序的步骤如下: 1. 连接gd25q128芯片至电脑。使用串行接口(SPI)或者USB适配器连接芯片与电脑。 2. 打开设备管理器。在Windows操作系统中,可以通过控制面板或者右键点击“我的电脑”选择“属性”来打开设备管理器。 3. 找到闪存芯片设备。在设备管理器的列表中,找到与gd25q128相关的闪存芯片设备。 4. 右键点击闪存芯片设备,选择“更新驱动程序”。 5. 选择“浏览计算机以查找驱动程序软件”选项。 6. 在新的窗口中选择驱动程序所在文件夹。 7. 点击“下一步”进行驱动程序安装。 8. 等待驱动程序安装完成,系统将会自动识别并加载gd25q128闪存芯片。 安装完成之后,电脑即可正常使用gd25q128芯片进行读取和写入操作。确保驱动程序的安装和更新可以提高gd25q128的性能和稳定性,并确保电脑与gd25q128芯片之间的通信无误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值