前言:
很感謝深圳雷龍發(fā)展有限公司為博主提供的兩片SD NAND的存儲(chǔ)芯片,在這里博主記錄一下自己的使用過程以及部分設(shè)計(jì)。
深入了解該產(chǎn)品:
拿到這個(gè)產(chǎn)品之后,我大致了解了下兩款芯片的性能。CSNP4GCR01-AMW是一種基于NAND閃存和SD控制器的4Gb密度嵌入式存儲(chǔ);而CSNP32GCR01-AOW是一種基于NAND閃存和SD控制器的32Gb密度嵌入式存儲(chǔ)。與原始NAND相比其具有嵌入式壞塊管理和更強(qiáng)的嵌入式ECC。即使在異常斷電,它仍然可以安全地保存數(shù)據(jù)。作為一個(gè)存儲(chǔ)芯片,它確實(shí)做到了小巧,LGA-8的封裝對(duì)比我之前用到過的TF卡,只占到了其面積的三分之一,這樣對(duì)于一些嵌入式的設(shè)計(jì)就方便了很多。
雷龍官方還很貼心的提供了樣品的測(cè)試板,在這款測(cè)試板上,我焊接了4GB的CSNP4GCR01-AMW上去,并且跑了一下分,對(duì)于一款小的存儲(chǔ)芯片而言,實(shí)在難得。
(上圖為測(cè)試板焊接圖)
博主日前在設(shè)計(jì)基于H616與NB-IOT的嵌入式智能儲(chǔ)物柜的時(shí)候考慮過存儲(chǔ)方面的問題,當(dāng)時(shí)在SD NAND和EMMC與TF卡中徘徊,以下是幾個(gè)存儲(chǔ)類型的對(duì)比。
經(jīng)過多方對(duì)比,本著不需要頻繁更換的原則,同時(shí)也為了更好的防水和成本考慮,最終決定使用雷龍公司的SD NAND 作為設(shè)計(jì)樣品的存儲(chǔ)部分。
此外,SD NAND還具有不用寫驅(qū)動(dòng)程序自帶壞塊管理的NAND FLASH(貼片式TF卡),不標(biāo)準(zhǔn)的SDIO接口,也同時(shí)兼容SPI/SD接口,10萬(wàn)次的SLC晶圓擦寫壽命,通過一萬(wàn)次的隨機(jī)掉電測(cè)試耐高低溫,經(jīng)過跑分測(cè)得,速度級(jí)別Class10。標(biāo)準(zhǔn)的SD2.0協(xié)議,普通的SD卡可以直接驅(qū)動(dòng),支持TF卡啟動(dòng)的SOC都可以用SD NAND,而且雷龍官方還貼心的提供了STM32參考例程和原廠技術(shù)支持,這對(duì)于剛上手的小白而言,十分友好。
設(shè)計(jì)理念:
使用H616作為主控CPU并搭配NB-IOT來(lái)向申請(qǐng)下來(lái)的云端傳輸數(shù)據(jù),當(dāng)WIFI正常時(shí),儲(chǔ)物數(shù)據(jù)每擱兩小時(shí)向云端傳輸一次,當(dāng)有人取出物品時(shí)再次向云端發(fā)送一次數(shù)據(jù)(不保留在SD NAND中);一旦系統(tǒng)檢測(cè)到WIFI出現(xiàn)問題,儲(chǔ)物數(shù)據(jù)轉(zhuǎn)而存儲(chǔ)到SD NAND中,取物時(shí)輸入的物品ID和取出時(shí)間一并放入SD NAND中(我也是看中了SD NAND與原始NAND相比其具有嵌入式壞塊管理和更強(qiáng)的嵌入式ECC。即使在異常斷電,它仍然可以安全地保存數(shù)據(jù)這一點(diǎn))。
部分SD NAND的參考設(shè)計(jì)
根據(jù)官方數(shù)據(jù)手冊(cè)提供的SD NAND參考設(shè)計(jì),只占用8個(gè)GPIO,對(duì)于H616來(lái)說,確實(shí)很友好
這里為了不泄露他人的勞動(dòng)成果,我也就不粘PCB設(shè)計(jì)了。
采用H616驅(qū)動(dòng)SD NAND的示例代碼
下面是關(guān)于H616驅(qū)動(dòng)SD NAND的示例代碼,這里記錄一下自己當(dāng)初的學(xué)習(xí)過程(注:這個(gè)代碼不能直接拿過來(lái)就用,而是要根據(jù)自己的需求修改)
- #include
- #include
- #include
- #include
- #include "h616_sdio.h"
- // 定義SDIO引腳
- #define SDIO_CMD_PIN 0
- #define SDIO_CLK_PIN 1
- #define SDIO_D0_PIN 2
- #define SDIO_D1_PIN 3
- #define SDIO_D2_PIN 4
- #define SDIO_D3_PIN 5
- // 定義NAND芯片命令
- #define CMD_READ 0x00
- #define CMD_WRITE 0x80
- #define CMD_ERASE 0x60
- #define CMD_STATUS 0x70
- #define CMD_RESET 0xff
- // 定義NAND芯片狀態(tài)
- #define STATUS_READY 0x40
- #define STATUS_ERROR 0x01
- // 初始化SDIO控制器
- void sdio_init()
- {
- // 設(shè)置SDIO引腳模式和速率
- h616_sdio_set_pin_mode(SDIO_CMD_PIN, H616_SDIO_PIN_MODE_SDIO);
- h616_sdio_set_pin_mode(SDIO_CLK_PIN, H616_SDIO_PIN_MODE_SDIO);
- h616_sdio_set_pin_mode(SDIO_D0_PIN, H616_SDIO_PIN_MODE_SDIO);
- h616_sdio_set_pin_mode(SDIO_D1_PIN, H616_SDIO_PIN_MODE_SDIO);
- h616_sdio_set_pin_mode(SDIO_D2_PIN, H616_SDIO_PIN_MODE_SDIO);
- h616_sdio_set_pin_mode(SDIO_D3_PIN, H616_SDIO_PIN_MODE_SDIO);
- h616_sdio_set_clock(H616_SDIO_CLOCK_FREQ_25MHZ);
- // 初始化SDIO控制器
- h616_sdio_init();
- }
- // 發(fā)送NAND芯片命令
- void nand_send_cmd(uint8_t cmd)
- {
- // 設(shè)置SDIO控制器傳輸模式和命令碼
- h616_sdio_set_transfer_mode(H616_SDIO_TRANSFER_MODE_WRITE);
- h616_sdio_set_command_code(cmd);
- // 發(fā)送命令
- h616_sdio_send_command();
- }
- // 發(fā)送NAND芯片地址
- void nand_send_addr(uint32_t addr)
- {
- // 設(shè)置SDIO控制器傳輸模式和地址
- h616_sdio_set_transfer_mode(H616_SDIO_TRANSFER_MODE_WRITE);
- h616_sdio_set_address(addr);
- // 發(fā)送地址
- h616_sdio_send_address();
- }
- // 讀取NAND芯片數(shù)據(jù)
- void nand_read_data(uint8_t *data, uint32_t size)
- {
- // 設(shè)置SDIO控制器傳輸模式
- h616_sdio_set_transfer_mode(H616_SDIO_TRANSFER_MODE_READ);
- // 讀取數(shù)據(jù)
- h616_sdio_read_data(data, size);
- }
- // 寫入NAND芯片數(shù)據(jù)
- void nand_write_data(const uint8_t *data, uint32_t size)
- {
- // 設(shè)置SDIO控制器傳輸模式
- h616_sdio_set_transfer_mode(H616_SDIO_TRANSFER_MODE_WRITE);
- // 寫入數(shù)據(jù)
- h616_sdio_write_data(data, size);
- }
- // 讀取NAND芯片狀態(tài)
- uint8_t nand_read_status()
- {
- uint8_t status;
- // 發(fā)送讀取狀態(tài)命令
- nand_send_cmd(CMD_STATUS);
- // 讀取狀態(tài)
- nand_read_data(&status, 1);
- return status;
- }
- // 等待NAND芯片準(zhǔn)備就緒
- void nand_wait_ready()
- {
- uint8_t status;
- // 循環(huán)讀取狀態(tài),直到NAND芯片準(zhǔn)備就緒
- do {
- status = nand_read_status();
- } while ((status & STATUS_READY) == 0);
- }
- // 讀取NAND芯片數(shù)據(jù)
- void nand_read(uint32_t page, uint32_t column, uint8_t *data, uint32_t size)
- {
- // 發(fā)送讀取命令和地址
- nand_send_cmd(CMD_READ);
- nand_send_addr(column | (page << 8));
- // 等待NAND芯片準(zhǔn)備就緒
- nand_wait_ready();
- // 讀取數(shù)據(jù)
- nand_read_data(data, size);
- }
- // 寫入NAND芯片數(shù)據(jù)
- void nand_write(uint32_t page, uint32_t column, const uint8_t *data, uint32_t size)
- {
- // 發(fā)送寫入命令和地址
- nand_send_cmd(CMD_WRITE);
- nand_send_addr(column | (page << 8));
- // 寫入數(shù)據(jù)
- nand_write_data(data, size);
- // 等待NAND芯片準(zhǔn)備就緒
- nand_wait_ready();
- }
- // 擦除NAND芯片塊
- void nand_erase(uint32_t block)
- {
- // 發(fā)送擦除命令和地址
- nand_send_cmd(CMD_ERASE);
- nand_send_addr(block << 8);
- // 等待NAND芯片準(zhǔn)備就緒
- nand_wait_ready();
- }
- // 復(fù)位NAND芯片
- void nand_reset()
- {
- // 發(fā)送復(fù)位命令
- nand_send_cmd(CMD_RESET);
- // 等待NAND芯片準(zhǔn)備就緒
- nand_wait_ready();
- }
- // 示例程序入口
- int main()
- {
- uint8_t data[2048];
- memset(data, 0x5a, sizeof(data));
- // 初始化SDIO控制器
- sdio_init();
- // 復(fù)位NAND芯片
- nand_reset();
- // 擦除第0塊
- nand_erase(0);
- // 寫入第0頁(yè)
- nand_write(0, 0, data, sizeof(data));
- // 讀取第0頁(yè)
- nand_read(0, 0, data, sizeof(data));
- return 0;
- }
-
芯片
+關(guān)注
關(guān)注
455文章
50714瀏覽量
423131 -
存儲(chǔ)
+關(guān)注
關(guān)注
13文章
4296瀏覽量
85798 -
內(nèi)存卡
+關(guān)注
關(guān)注
0文章
62瀏覽量
14752
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論