GD25Q32是一款基于SPI的Flash芯片,容量為32/8=4M bytes。它的引腳如下:
該芯片支持多種SPI操作方式,包括:Standard SPI(標準SPI)
、Dual SPI(雙線 SPI)
和Quad SPI(四線 SPI) 。有關SPI的介紹可以參考:
SPI通信原理-CSDN博客文章瀏覽閱讀302次,點贊5次,收藏7次。而之所以會有雙線SPI和四線SPI的出現,其實主要是因為某些情況下并不需要全雙工,但對通信速度有更高的要求,所以對引腳功能做了些調整。但是既然都叫SPI,說明仍然是符合SPI的協議標準的,本次只講解標準SPI,理解了后感興趣可以自行研究雙線SPI和四線SPI。SPI是一種一主多從的工作模式,不同于IIC,它只有一個主機,讀寫操作全部由主機發起,從機被動響應。假設CPOL為0,那么在第一個上升沿時,發送方往數據線上發送一位數據,在下降沿時接收方讀取一位數據,如此循環8次,一個字節就被發送和接收了。https://blog.csdn.net/u011436603/article/details/136008066其中CS為片選使能腳
SO,WP,SCLK,SI,HOLD為SPI通信引腳,使用標準SPI通信的話,一般只需考慮SCLK,SO和SI就已足夠了。
與標準SPI的引腳對應為:
名稱 | 標準 | GD25Q32 |
片選 | CS | CS# |
時鐘 | CLK | SCLK |
主機發 | MOSI | SI(IO0) |
主機收 | MISO | SO(IO1) |
?GD25Q32屬于FLASH,因此和EEPROM不同的是,它無法按字節寫入,必須按page去寫。擦除的時候可以按扇區或塊擦除。每個page有256bytes,注意到每個block可以有32K或64K bytes,這個在后面會影響具體的操作。
接下來直接展示驅動代碼,具體解析可以看注釋,使用STM32的硬件SPI
//使用spi3讀一個字節,用的標準庫
unsigned char flash_spi_rchar(void)
{while((SPI3->SR&SPI_I2S_FLAG_TXE)==0) ;SPI3->DR = 0xff;while((SPI3->SR&SPI_I2S_FLAG_RXNE)==0) ;return SPI3->DR;
}//使用spi3寫一個字節
void flash_spi_wchar(unsigned char ucChar)
{while((SPI3->SR&SPI_I2S_FLAG_TXE)==0) ;SPI3->DR = ucChar;while((SPI3->SR&SPI_I2S_FLAG_RXNE)==0) ;SPI3->DR;
}
?首先列舉一下芯片的默認指令,后面代碼中出現的指令可以直接對照參考
繼續上代碼,主要是讀寫的驅動函數
unsigned char flash_read_status(void)
{unsigned char ucChar;FLASH_CS_EN;flash_spi_wchar(0x05); //讀取狀態;ucChar = flash_spi_rchar();FLASH_CS_DIS;return ucChar;
}void flash_write_trail(unsigned int nAddress,unsigned char* ucData,unsigned int nLength)
{unsigned int i,n;while(flash_read_status()&0x01); //忙;FLASH_CS_EN;flash_spi_wchar(0x06); //寫使能;FLASH_CS_DIS;FLASH_CS_EN;flash_spi_wchar(0xd8); //擦除BLOCK,按64K擦除;flash_spi_wchar((nAddress>>16)&0xff); //存儲地址flash_spi_wchar((nAddress>>8)&0xff);flash_spi_wchar(nAddress&0xff);FLASH_CS_DIS;while(flash_read_status()&0x01); //忙for(n=1; (n*256)<=nLength; n++) //256的倍數,表示按頁寫{while(flash_read_status()&0x01); //忙FLASH_CS_EN;flash_spi_wchar(0x06); //寫使能;FLASH_CS_DIS;FLASH_CS_EN;flash_spi_wchar(0x02); //寫入數據;flash_spi_wchar(((nAddress+(n-1)*256)>>16)&0xff);flash_spi_wchar(((nAddress+(n-1)*256)>>8)&0xff);flash_spi_wchar((nAddress+(n-1)*256)&0xff);for(i=0; i<256; i++)flash_spi_wchar(*ucData++);FLASH_CS_DIS;}while(flash_read_status()&0x01); //忙FLASH_CS_EN;flash_spi_wchar(0x06); //寫使能;FLASH_CS_DIS;FLASH_CS_EN;flash_spi_wchar(0x02); //寫入數據;flash_spi_wchar(((nAddress+(n-1)*256)>>16)&0xff);flash_spi_wchar(((nAddress+(n-1)*256)>>8)&0xff);flash_spi_wchar((nAddress+(n-1)*256)&0xff);for(i=0; i<(nLength%256); i++)flash_spi_wchar(*ucData++);FLASH_CS_DIS;
}unsigned char flash_read_char(unsigned int nAddress)
{unsigned char ucChar;while(flash_read_status()&0x01); //忙;FLASH_CS_EN;flash_spi_wchar(0x03); //讀數據flash_spi_wchar((nAddress>>16)&0xff); //存儲地址flash_spi_wchar((nAddress>>8)&0xff);flash_spi_wchar(nAddress&0xff);ucChar = flash_spi_rchar();FLASH_CS_DIS;return ucChar;
}
以上就是GD25Q32的驅動代碼,驅動函數中是按64K擦除的,如果需要按32K擦除,則使用0x52指令即可。
差點忘了,FLASH_CS_EN和FLASH_CS_DIS表示片選使能和失能,即CS引腳的拉高或拉低,由于低電平有效,因此FLASH_CS_EN表示的是引腳拉低。