一 概述
GD25Q32是一種常見的串行閃存器件,它采用SPI(Serial Peripheral Interface)接口協議,具有高速讀寫和擦除功能,可用于存儲和讀取數據。GD25Q32芯片容量為32 Mbit(4 MB),其中名稱后的數字代表不同的容量選項。不同的型號和容量選項可以滿足不同應用的需求,通常被用于嵌入式設備、存儲設備、路由器等高性能電子設備中。
GD25Q32閃存芯片的內存分配是按照扇區(Sector)和塊(Block)進行的,每個扇區的大小為4KB,每個塊包含16個扇區,即一個塊的大小為64KB。
二 物理特性
可以將 1 寫成 0,但是不能將 0 寫成 1,要想將 0 寫成 1,必須進行擦除操作。如果要改變數據,就需要先擦除后寫數據。
如果想要修改小于扇區大小的數據,需要將整個扇區的數據,在內存中進行備份,然后修改內存中的數據,再將數據寫回到原扇區位置。因此,驅動要達到支持自動完成這個過程,用戶可以使用驅動修改任意位置的數據。
三 引腳定義和描述
四 命令概覽
五 組件的使用
1 Gitee鏈接地址
Demo位于amaziot_bloom_os_sdksample3rd2.0_GD25Q20C
Gitee源碼地址:https://gitee.com/ning./hongdou
Github源碼地址:https://github.com/ayumid/hongdou
編譯指令:.build.bat -l .amaziot_bloom_os_sdksample3rd2.0_GD25Q20C
2 組件功能介紹
實現軟件模擬SPI,驅動GD25Q20芯片,實現數據存儲
3 代碼講解
1 drv_gd25q20_delay_us
功能:該函數用于,延時。
參數:
參數 | 釋義 |
count | 死循環次數 |
返回值:無
示例:
//初始化i2c總線 ret = drv_xl9535_i2c_init();
2 drv_gd25q20_gpio_set
功能:該函數用于,模擬SPI設置IO輸出電平。
參數:
參數 | 釋義 |
num | 引腳號 |
val | 0 低電平,1 高電平 |
返回值:0 成功,-1 失敗
示例:
drv_gd25q20_gpio_set(DRV_GD25Q20_SPI_CS, DRV_GD25Q20_GPIO_LOW);
3 drv_gd25q20_byte_wr
功能:該函數用于,SPI寫讀一個字節 mode3。
參數:
參數 | 釋義 |
byte | 發送數據 |
返回值:flash返回數據
示例:
drv_gd25q20_byte_wr(DRV_GD25Q20_DUMMY_BYTE);
4 drv_gd25q20_byte_rd
功能:該函數用于,SPI只讀一個字節。
參數:無
返回值:flash返回數據
示例:
drv_gd25q20_byte_rd(DRV_GD25Q20_DUMMY_BYTE);
5 drv_gd25q20_busy_wait
功能:該函數用于,GD25Q20 忙等待。
參數:無
返回值:無
示例:
while(drv_gd25q20_read_reg1() & BIT_BUSY);
6 drv_gd25q20_read_reg1
功能:該函數用于,讀reg1。
參數:無
返回值:無
示例:
while(drv_gd25q20_read_reg1() & BIT_BUSY);
7 drv_gd25q20_read_identification
功能:該函數用于,讀 GD25Q20 JEDEC_ID(制造商、類型、容量)。
參數:無
返回值:無
示例:
sample_gd25q20_uart_printf("identification is 0x%X, Device id is 0x%X, Manufacturer Device ID is 0x%X", drv_gd25q20_read_identification(), drv_gd25q20_read_device_id(), drv_gd25q20_read_manufacturer_id());
8 drv_gd25q20_read_manufacturer_id
功能:該函數用于,讀 GD25Q20 制造商 ID。
參數:無
返回值:無
示例:
sample_gd25q20_uart_printf("identification is 0x%X, Device id is 0x%X, Manufacturer Device ID is 0x%X", drv_gd25q20_read_identification(), drv_gd25q20_read_device_id(), drv_gd25q20_read_manufacturer_id());
9 drv_gd25q20_read_device_id
功能:該函數用于,讀 GD25Q20 設備 ID。
參數:無
返回值:無
示例:
sample_gd25q20_uart_printf("identification is 0x%X, Device id is 0x%X, Manufacturer Device ID is 0x%X", drv_gd25q20_read_identification(), drv_gd25q20_read_device_id(), drv_gd25q20_read_manufacturer_id());
10 drv_gd25q20_write_enable
功能:該函數用于,寫使能。
參數:無
返回值:無
示例:
sample_gd25q20_uart_printf("identification is 0x%X, Device id is 0x%X, Manufacturer Device ID is 0x%X", drv_gd25q20_read_identification(), drv_gd25q20_read_device_id(), drv_gd25q20_read_manufacturer_id());
11 drv_gd25q20_write_disable
功能:該函數用于,寫失能。
參數:無
返回值:無
示例:
無
12 drv_gd25q20_write_page
功能:該函數用于,頁編程(調用本函數寫入數據前需要先擦除扇區)。
參數:
參數 | 釋義 |
pbuf | 數據 |
addr | 地址 |
len | 長度 |
返回值:無
示例:
drv_gd25q20_write_page(pbuf, addr, pageremain);
13 drv_gd25q20_read
功能:該函數用于,讀閃存數據。
參數:
參數 | 釋義 |
pbuf | 數據 |
addr | 地址 |
len | 長度 |
返回值:無
示例:
drv_gd25q20_read((UINT8*)rx_buff1, 8181, strlen(tx_buff1));
14 drv_gd25q20_sector_erase
功能:該函數用于,扇區擦除。
參數:
參數 | 釋義 |
addr | 地址 |
返回值:無
示例:
drv_gd25q20_sector_erase(secpos * DRV_GD25Q20_SOCTOR_SIZE);
15 drv_gd25q20_chip_rease
功能:該函數用于,FLASH整片擦除(為了安全起見,若要調用,請先調用 drv_gd25q20_write_enable 函數)。
參數:無
返回值:無
示例:
無
16 drv_gd25q20_powr_down
功能:該函數用于,掉電。
參數:無
返回值:無
示例:
無
17 drv_gd25q20_release_powr_down
功能:該函數用于,讀閃存數據。
參數:
參數 | 釋義 |
pbuf | 數據 |
addr | 地址 |
len | 長度 |
返回值:無
示例:
drv_gd25q20_read((UINT8*)rx_buff1, 8181, strlen(tx_buff1));
18 drv_gd25q20_write_nocheck
功能:該函數用于,寫數據。
參數:
參數 | 釋義 |
pbuf | 數據 |
addr | 地址 |
len | 長度 |
返回值:無
示例:
drv_gd25q20_write_nocheck(gd25q20_buffer, secpos * DRV_GD25Q20_SOCTOR_SIZE, DRV_GD25Q20_SOCTOR_SIZE);
19 drv_gd25q20_write
功能:該函數用于,寫閃存數據,可以使任意地址。
參數:
參數 | 釋義 |
pbuf | 數據 |
addr | 地址 |
len | 長度 |
返回值:無
示例:
drv_gd25q20_write((UINT8*)tx_buff1, 8181, strlen(tx_buff1));
20 drv_gd25q20_init
功能:該函數用于,寫數據。
參數:無
返回值:無
示例:
drv_gd25q20_init();
4 Demo實戰
4.1 概述
上電后,按下按鍵,串口會打印出按下了哪一個按鍵
4.2 測試
測試步驟:
參考編譯教程,和文檔開頭的編譯指令,進行編譯
按照編譯教程選擇對應的選項
燒錄
4.3 宏定義介紹
sample_gd25q20_uart_printf
輸出日志到DEBUG 串口,日志比較少,可以輸出到這個串口,如果日志比較多,需要輸出到usb口,以免不必要的問題出現
sample_gd25q20_catstudio_printf
輸出日志到USB 串口,使用catstudio查看,catstudio查看日志需要更新對應版本mdb.txt文件,軟件打開filtter過濾日志,只查看用戶輸出的日志
SAMPLE_GD25Q20_STACK_SIZE
棧空間宏定義
4.4 全局變量介紹
sample_gd25q20_task_ref
任務指針
4.5 函數介紹
Phase1Inits_enter
底層初始化,本例空
Phase1Inits_exit
底層初始化,本例空
Phase2Inits_enter
底層初始化,本例空
Phase2Inits_exit
創建主任務,初始化INT 引腳
代碼片段:
void Phase2Inits_exit(void) { int ret; sample_gd25q20_task_stack = malloc(SAMPLE_GD25Q20_STACK_SIZE); ret = OSATaskCreate(&sample_gd25q20_task_ref, sample_gd25q20_task_stack, SAMPLE_GD25Q20_STACK_SIZE, 88, "sample_gd25q20_task", sample_gd25q20_task, NULL); ASSERT(ret == OS_SUCCESS); }
_task
主任務,代碼發分為兩部分,一部分是發送不定長數據;另一部分是上電后等待其它模塊發送的數據,收到后打印到串口。
代碼片段:
static void sample_gd25q20_task(void *ptr) { int ret = 0; uint32_t identification = 0; // unsigned char writeBuf[30] = {0}; // unsigned char readBuf[30] = {0}; // ret = ql_spi_init(QL_SPI_PORT0, QL_SPI_MODE3, QL_SPI_CLK_812_5KHZ); // sample_gd25q20_catstudio_printf("ql_spi_init ret %d", ret); drv_gd25q20_init(); identification = drv_gd25q20_read_identification(); sample_gd25q20_uart_printf("identification is 0x%X, Device id is 0x%X, Manufacturer Device ID is 0x%X", drv_gd25q20_read_identification(), drv_gd25q20_read_device_id(), drv_gd25q20_read_manufacturer_id()); // while(1) // { // drv_gd25q20_gpio_set(DRV_GD25Q20_SPI_CS, 0); // sample_gd25q20_uart_printf("low"); // OSATaskSleep(5*200); // drv_gd25q20_gpio_set(DRV_GD25Q20_SPI_CS, 1); // sample_gd25q20_uart_printf("high"); // OSATaskSleep(5*200); // } if(identification != RDID) { /* 讀取錯誤處理 */ sample_gd25q20_uart_printf("SPI read-write Error, please check the connection between MCU and SPI Flashn"); } else { //讀取成功處理 char tx_buff1[64] = "abcdefghigklmnopqrstuvwxyz0123456789"; char rx_buff1[64] = {0}; char tx_buff2[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ9876543210"; char rx_buff2[64] = {0}; int i = 0; //測試跨sector寫,并且讀出數據,寫兩次,第二次保留第一次部分數據,證明數據擦除,寫入正常 drv_gd25q20_write((UINT8*)tx_buff1, 8181, strlen(tx_buff1));//從8181地址開始寫數據,需要寫第二和第三個扇區 drv_gd25q20_read((UINT8*)rx_buff1, 8181, strlen(tx_buff1)); sample_gd25q20_uart_printf("read flash:%s", rx_buff1); if(!strncmp(tx_buff1, rx_buff1, strlen(tx_buff1))) { sample_gd25q20_uart_printf("SPI read-write succeed 1"); } //驗證驅動擦除扇區時,可以保留之前有效內容 drv_gd25q20_write((UINT8*)tx_buff2, 8186, strlen(tx_buff2));//從8186地址開始寫數據,需要寫第二和第三個扇區,同時不能擦掉8181 - 8186的5字節數據 drv_gd25q20_read((UINT8*)rx_buff2, 8181, strlen(tx_buff2) + 5); sample_gd25q20_uart_printf("read flash:%s", rx_buff2); if(!strncmp(rx_buff2, "abcdeABCDEFGHIJKLMNOPQRSTUVWXYZ9876543210", strlen("abcdeABCDEFGHIJKLMNOPQRSTUVWXYZ9876543210"))) { sample_gd25q20_uart_printf("SPI read-write succeed 2"); } } while (1) { // memset(writeBuf, 0x00, sizeof(writeBuf)); // memset(readBuf, 0x00, sizeof(readBuf)); // writeBuf[0] = 0x9F; // ret = ql_spi_write_read(QL_SPI_PORT0, readBuf, writeBuf, 1); // sample_gd25q20_catstudio_printf("ql_spi_write_read ret %d, readBuf %02X,%02X,%02Xn", ret, readBuf[0], readBuf[1], readBuf[2]); // ret = ql_spi_write(QL_SPI_PORT0, writeBuf, 1); // sample_gd25q20_catstudio_printf("ql_spi_write_read ret %d, readBuf %02Xn", ret, writeBuf[0]); // ret = ql_spi_read(QL_SPI_PORT0, readBuf, 3); // sample_gd25q20_catstudio_printf("ql_spi_write_read ret %d, readBuf %02X,%02X,%02Xn", ret, readBuf[0], readBuf[1], readBuf[2]); OSATaskSleep(5 * 200); } }
4.6 固件
本文章源自奇跡物聯開源的物聯網應用知識庫Cellular IoT Wiki,更多技術干貨歡迎關注收藏Wiki:Cellular IoT Wiki 知識庫(https://rckrv97mzx.feishu.cn/wiki/wikcnBvAC9WOkEYG5CLqGwm6PHf)
歡迎同學們走進AmazIOT知識庫的世界!
這里是為物聯網人構建的技術應用百科,以便幫助你更快更簡單的開發物聯網產品。
Cellular IoT Wiki初心:
在我們長期投身于蜂窩物聯網 ODM/OEM 解決方案的實踐過程中,一直被物聯網技術碎片化與產業資源碎片化的問題所困擾。從產品定義、芯片選型,到軟硬件研發和測試,物聯網技術的碎片化以及產業資源的碎片化,始終對團隊的產品開發交付質量和效率形成制約。為了減少因物聯網碎片化而帶來的重復開發工作,我們著手對物聯網開發中高頻應用的技術知識進行沉淀管理,并基于 Bloom OS 搭建了不同平臺的 RTOS 應用生態。后來我們發現,很多物聯網產品開發團隊都面臨著相似的困擾,于是,我們決定向全體物聯網行業開發者開放奇跡物聯內部沉淀的應用技術知識庫 Wiki,期望能為更多物聯網產品開發者減輕一些重復造輪子的負擔。
Cellular IoT Wiki沉淀的技術內容方向如下:
奇跡物聯的業務服務范圍:基于自研的NB-IoT、Cat1、Cat4等物聯網模組,為客戶物聯網ODM/OEM解決方案服務。我們的研發技術中心在石家莊,PCBA生產基地分布在深圳、石家莊、北京三個工廠,滿足不同區域&不同量產規模&不同產品開發階段的生產制造任務。跟傳統PCBA工廠最大的區別是我們只服務物聯網行業客戶。
連接我們,和10000+物聯網開發者一起 降低技術和成本門檻
讓蜂窩物聯網應用更簡單~~
哈哈你終于滑到最重要的模塊了,
千萬不!要!劃!走!忍住沖動!~
歡迎加入飛書“開源技術交流群”,隨時找到我們哦~
點擊鏈接如何加入奇跡物聯技術話題群(https://rckrv97mzx.feishu.cn/docx/Xskpd1cFQo7hu9x5EuicbsjTnTf)可以獲取加入技術話題群攻略
Hey 物聯網從業者,
你是否有了解過奇跡物聯的官方公眾號“eSIM物聯工場”呢?
這里是奇跡物聯的物聯網應用技術開源wiki主陣地,歡迎關注公眾號,不迷路~
及時獲得最新物聯網應用技術沉淀發布
注:本文部分內容來源于網絡,如有侵權,請及時聯系我們。
-
閃存
+關注
關注
16文章
1793瀏覽量
114981 -
物聯網
+關注
關注
2909文章
44729瀏覽量
374423 -
路由器
+關注
關注
22文章
3734瀏覽量
113976
發布評論請先 登錄
相關推薦
評論