一 概述
GD25Q32是一種常見的串行閃存器件,它采用SPI(Serial Peripheral Interface)接口協(xié)議,具有高速讀寫和擦除功能,可用于存儲和讀取數(shù)據(jù)。GD25Q32芯片容量為32 Mbit(4 MB),其中名稱后的數(shù)字代表不同的容量選項。不同的型號和容量選項可以滿足不同應(yīng)用的需求,通常被用于嵌入式設(shè)備、存儲設(shè)備、路由器等高性能電子設(shè)備中。
GD25Q32閃存芯片的內(nèi)存分配是按照扇區(qū)(Sector)和塊(Block)進行的,每個扇區(qū)的大小為4KB,每個塊包含16個扇區(qū),即一個塊的大小為64KB。
二 物理特性
可以將 1 寫成 0,但是不能將 0 寫成 1,要想將 0 寫成 1,必須進行擦除操作。如果要改變數(shù)據(jù),就需要先擦除后寫數(shù)據(jù)。
如果想要修改小于扇區(qū)大小的數(shù)據(jù),需要將整個扇區(qū)的數(shù)據(jù),在內(nèi)存中進行備份,然后修改內(nèi)存中的數(shù)據(jù),再將數(shù)據(jù)寫回到原扇區(qū)位置。因此,驅(qū)動要達到支持自動完成這個過程,用戶可以使用驅(qū)動修改任意位置的數(shù)據(jù)。
三 引腳定義和描述
四 命令概覽
五 組件的使用
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 組件功能介紹
實現(xiàn)軟件模擬SPI,驅(qū)動GD25Q20芯片,實現(xiàn)數(shù)據(jù)存儲
3 代碼講解
1 drv_gd25q20_delay_us
功能:該函數(shù)用于,延時。
參數(shù) | 釋義 |
count | 死循環(huán)次數(shù) |
返回值:無
示例:
//初始化i2c總線 ret = drv_xl9535_i2c_init();
2 drv_gd25q20_gpio_set
功能:該函數(shù)用于,模擬SPI設(shè)置IO輸出電平。
參數(shù):
參數(shù) | 釋義 |
num | 引腳號 |
val | 0 低電平,1 高電平 |
返回值:0 成功,-1 失敗
示例:
drv_gd25q20_gpio_set(DRV_GD25Q20_SPI_CS, DRV_GD25Q20_GPIO_LOW);
3 drv_gd25q20_byte_wr
功能:該函數(shù)用于,SPI寫讀一個字節(jié) mode3。
參數(shù):
參數(shù) | 釋義 |
byte | 發(fā)送數(shù)據(jù) |
返回值:flash返回數(shù)據(jù)
示例:
drv_gd25q20_byte_wr(DRV_GD25Q20_DUMMY_BYTE);
4 drv_gd25q20_byte_rd
功能:該函數(shù)用于,SPI只讀一個字節(jié)。
參數(shù):無
返回值:flash返回數(shù)據(jù)
示例:
drv_gd25q20_byte_rd(DRV_GD25Q20_DUMMY_BYTE);
5 drv_gd25q20_busy_wait
功能:該函數(shù)用于,GD25Q20 忙等待。
參數(shù):無
返回值:無
示例:
while(drv_gd25q20_read_reg1() & BIT_BUSY);
6 drv_gd25q20_read_reg1
功能:該函數(shù)用于,讀reg1。
參數(shù):無
返回值:無
示例:
while(drv_gd25q20_read_reg1() & BIT_BUSY);
7 drv_gd25q20_read_identification
功能:該函數(shù)用于,讀 GD25Q20 JEDEC_ID(制造商、類型、容量)。
參數(shù):無
返回值:無
示例:
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
功能:該函數(shù)用于,讀 GD25Q20 制造商 ID。
參數(shù):無
返回值:無
示例:
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
功能:該函數(shù)用于,讀 GD25Q20 設(shè)備 ID。
參數(shù):無
返回值:無
示例:
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
功能:該函數(shù)用于,寫使能。
參數(shù):無
返回值:無
示例:
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
功能:該函數(shù)用于,寫失能。
參數(shù):無
返回值:無
示例:
無
12 drv_gd25q20_write_page
功能:該函數(shù)用于,頁編程(調(diào)用本函數(shù)寫入數(shù)據(jù)前需要先擦除扇區(qū))。
參數(shù):
參數(shù) | 釋義 |
pbuf | 數(shù)據(jù) |
addr | 地址 |
len | 長度 |
返回值:無
示例:
drv_gd25q20_write_page(pbuf, addr, pageremain);
13 drv_gd25q20_read
功能:該函數(shù)用于,讀閃存數(shù)據(jù)。
參數(shù):
參數(shù) | 釋義 |
pbuf | 數(shù)據(jù) |
addr | 地址 |
len | 長度 |
返回值:無
示例:
drv_gd25q20_read((UINT8*)rx_buff1, 8181, strlen(tx_buff1));
14 drv_gd25q20_sector_erase
功能:該函數(shù)用于,扇區(qū)擦除。
參數(shù):
參數(shù) | 釋義 |
addr | 地址 |
返回值:無
示例:
drv_gd25q20_sector_erase(secpos * DRV_GD25Q20_SOCTOR_SIZE);
15 drv_gd25q20_chip_rease
功能:該函數(shù)用于,F(xiàn)LASH整片擦除(為了安全起見,若要調(diào)用,請先調(diào)用 drv_gd25q20_write_enable 函數(shù))。
參數(shù):無
返回值:無
示例:
無
16 drv_gd25q20_powr_down
功能:該函數(shù)用于,掉電。
參數(shù):無
返回值:無
示例:
無
17 drv_gd25q20_release_powr_down
功能:該函數(shù)用于,讀閃存數(shù)據(jù)。
參數(shù):
參數(shù) | 釋義 |
pbuf | 數(shù)據(jù) |
addr | 地址 |
len | 長度 |
返回值:無
示例:
drv_gd25q20_read((UINT8*)rx_buff1, 8181, strlen(tx_buff1));
18 drv_gd25q20_write_nocheck
功能:該函數(shù)用于,寫數(shù)據(jù)。
參數(shù):
參數(shù) | 釋義 |
pbuf | 數(shù)據(jù) |
addr | 地址 |
len | 長度 |
返回值:無
示例:
drv_gd25q20_write_nocheck(gd25q20_buffer, secpos * DRV_GD25Q20_SOCTOR_SIZE, DRV_GD25Q20_SOCTOR_SIZE);
19 drv_gd25q20_write
功能:該函數(shù)用于,寫閃存數(shù)據(jù),可以使任意地址。
參數(shù):
參數(shù) | 釋義 |
pbuf | 數(shù)據(jù) |
addr | 地址 |
len | 長度 |
返回值:無
示例:
drv_gd25q20_write((UINT8*)tx_buff1, 8181, strlen(tx_buff1));
20 drv_gd25q20_init
功能:該函數(shù)用于,寫數(shù)據(jù)。
參數(shù):無
返回值:無
示例:
drv_gd25q20_init();
4 Demo實戰(zhàn)
4.1 概述
上電后,按下按鍵,串口會打印出按下了哪一個按鍵
4.2 測試
測試步驟:
參考編譯教程,和文檔開頭的編譯指令,進行編譯
按照編譯教程選擇對應(yīng)的選項
燒錄
4.3 宏定義介紹
sample_gd25q20_uart_printf
輸出日志到DEBUG 串口,日志比較少,可以輸出到這個串口,如果日志比較多,需要輸出到usb口,以免不必要的問題出現(xiàn)
sample_gd25q20_catstudio_printf
輸出日志到USB 串口,使用catstudio查看,catstudio查看日志需要更新對應(yīng)版本mdb.txt文件,軟件打開filtter過濾日志,只查看用戶輸出的日志
SAMPLE_GD25Q20_STACK_SIZE
棧空間宏定義
4.4 全局變量介紹
sample_gd25q20_task_ref
任務(wù)指針
4.5 函數(shù)介紹
Phase1Inits_enter
底層初始化,本例空
Phase1Inits_exit
底層初始化,本例空
Phase2Inits_enter
底層初始化,本例空
Phase2Inits_exit
創(chuàng)建主任務(wù),初始化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
主任務(wù),代碼發(fā)分為兩部分,一部分是發(fā)送不定長數(shù)據(jù);另一部分是上電后等待其它模塊發(fā)送的數(shù)據(jù),收到后打印到串口。
代碼片段:
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寫,并且讀出數(shù)據(jù),寫兩次,第二次保留第一次部分數(shù)據(jù),證明數(shù)據(jù)擦除,寫入正常 drv_gd25q20_write((UINT8*)tx_buff1, 8181, strlen(tx_buff1));//從8181地址開始寫數(shù)據(jù),需要寫第二和第三個扇區(qū) 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"); } //驗證驅(qū)動擦除扇區(qū)時,可以保留之前有效內(nèi)容 drv_gd25q20_write((UINT8*)tx_buff2, 8186, strlen(tx_buff2));//從8186地址開始寫數(shù)據(jù),需要寫第二和第三個扇區(qū),同時不能擦掉8181 - 8186的5字節(jié)數(shù)據(jù) 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 固件
本文章源自奇跡物聯(lián)開源的物聯(lián)網(wǎng)應(yīng)用知識庫Cellular IoT Wiki,更多技術(shù)干貨歡迎關(guān)注收藏Wiki:Cellular IoT Wiki 知識庫(https://rckrv97mzx.feishu.cn/wiki/wikcnBvAC9WOkEYG5CLqGwm6PHf)
歡迎同學(xué)們走進AmazIOT知識庫的世界!
這里是為物聯(lián)網(wǎng)人構(gòu)建的技術(shù)應(yīng)用百科,以便幫助你更快更簡單的開發(fā)物聯(lián)網(wǎng)產(chǎn)品。
Cellular IoT Wiki初心:
在我們長期投身于蜂窩物聯(lián)網(wǎng) ODM/OEM 解決方案的實踐過程中,一直被物聯(lián)網(wǎng)技術(shù)碎片化與產(chǎn)業(yè)資源碎片化的問題所困擾。從產(chǎn)品定義、芯片選型,到軟硬件研發(fā)和測試,物聯(lián)網(wǎng)技術(shù)的碎片化以及產(chǎn)業(yè)資源的碎片化,始終對團隊的產(chǎn)品開發(fā)交付質(zhì)量和效率形成制約。為了減少因物聯(lián)網(wǎng)碎片化而帶來的重復(fù)開發(fā)工作,我們著手對物聯(lián)網(wǎng)開發(fā)中高頻應(yīng)用的技術(shù)知識進行沉淀管理,并基于 Bloom OS 搭建了不同平臺的 RTOS 應(yīng)用生態(tài)。后來我們發(fā)現(xiàn),很多物聯(lián)網(wǎng)產(chǎn)品開發(fā)團隊都面臨著相似的困擾,于是,我們決定向全體物聯(lián)網(wǎng)行業(yè)開發(fā)者開放奇跡物聯(lián)內(nèi)部沉淀的應(yīng)用技術(shù)知識庫 Wiki,期望能為更多物聯(lián)網(wǎng)產(chǎn)品開發(fā)者減輕一些重復(fù)造輪子的負擔(dān)。
Cellular IoT Wiki沉淀的技術(shù)內(nèi)容方向如下:
奇跡物聯(lián)的業(yè)務(wù)服務(wù)范圍:基于自研的NB-IoT、Cat1、Cat4等物聯(lián)網(wǎng)模組,為客戶物聯(lián)網(wǎng)ODM/OEM解決方案服務(wù)。我們的研發(fā)技術(shù)中心在石家莊,PCBA生產(chǎn)基地分布在深圳、石家莊、北京三個工廠,滿足不同區(qū)域&不同量產(chǎn)規(guī)模&不同產(chǎn)品開發(fā)階段的生產(chǎn)制造任務(wù)。跟傳統(tǒng)PCBA工廠最大的區(qū)別是我們只服務(wù)物聯(lián)網(wǎng)行業(yè)客戶。
連接我們,和10000+物聯(lián)網(wǎng)開發(fā)者一起 降低技術(shù)和成本門檻
讓蜂窩物聯(lián)網(wǎng)應(yīng)用更簡單~~
哈哈你終于滑到最重要的模塊了,
千萬不!要!劃!走!忍住沖動!~
歡迎加入飛書“開源技術(shù)交流群”,隨時找到我們哦~
點擊鏈接如何加入奇跡物聯(lián)技術(shù)話題群(https://rckrv97mzx.feishu.cn/docx/Xskpd1cFQo7hu9x5EuicbsjTnTf)可以獲取加入技術(shù)話題群攻略
Hey 物聯(lián)網(wǎng)從業(yè)者,
你是否有了解過奇跡物聯(lián)的官方公眾號“eSIM物聯(lián)工場”呢?
這里是奇跡物聯(lián)的物聯(lián)網(wǎng)應(yīng)用技術(shù)開源wiki主陣地,歡迎關(guān)注公眾號,不迷路~
及時獲得最新物聯(lián)網(wǎng)應(yīng)用技術(shù)沉淀發(fā)布
注:本文部分內(nèi)容來源于網(wǎng)絡(luò),如有侵權(quán),請及時聯(lián)系我們。
-
閃存
+關(guān)注
關(guān)注
16文章
1799瀏覽量
115113 -
物聯(lián)網(wǎng)
+關(guān)注
關(guān)注
2913文章
44923瀏覽量
377018 -
路由器
+關(guān)注
關(guān)注
22文章
3744瀏覽量
114476
發(fā)布評論請先 登錄
相關(guān)推薦
評論