<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

淺析spi flash驅動及其程序

ss ? 作者:工程師譚軍 ? 2018-10-07 11:26 ? 次閱讀
SPI Flash
首先它是個Flash,Flash是什么東西就不多說了(非易失性存儲介質),分為NOR和NAND兩種(NOR和NAND的區別本篇不做介紹)。SPI一種通信接口。那么嚴格的來說SPI Flash是一種使用SPI通信的Flash,即,可能指NOR也可能是NAND。但現在大部分情況默認下人們說的SPI Flash指的是SPI NorFlash。早期Norflash的接口是parallel的形式,即把數據線和地址線并排與IC的管腳連接。但是后來發現不同容量的Norflash不能硬件上兼容(數據線和地址線的數量不一樣),并且封裝比較大,占用了較大的PCB板位置,所以后來逐漸被SPI(串行接口)Norflash所取代。同時不同容量的SPI Norflash管腳也兼容封裝也更小。,至于現在很多人說起NOR flash直接都以SPI flash來代稱。
NorFlash根據數據傳輸的位數可以分為并行(Parallel,即地址線和數據線直接和處理器相連)NorFlash和串行(SPI,即通過SPI接口和處理器相連)NorFlash;區別主要就是:1、SPI NorFlash每次傳輸一bit位的數據,parallel連接的NorFlash每次傳輸多個bit位的數據(有x8和x16bit兩種); 2、SPI NorFlash比parallel便宜,接口簡單點,但速度慢。
NandFlash是地址數據線復用的方式,接口標準統一(x8bit和x16bit),所以不同容量再兼容性上基本沒什么問題。但是目前對產品的需求越來越小型化以及成本要求也越來越高,所以SPI NandFlash漸漸成為主流,并且采用SPI NANDFlash方案,主控也可以不需要傳統NAND控制器,只需要有SPI接口接口操作訪問,從而降低成本。另外SPI NandFlash封裝比傳統的封裝也小很多,故節省了PCB板的空間。
怎么用說白了對于Flash就是讀寫擦,也就是實現flash的驅動。先簡單了解下spi flash的物理連接。
之前介紹SPI的時候說過,SPI接口目前的使用是多種方式(具體指的是物理連線有幾種方式),Dual SPI、Qual SPI和標準的SPI接口(這種方式肯定不會出現在連接外設是SPI Flash上,這玩意沒必要全雙工),對于SPI Flash來說,主要就是Dual和Qual這兩種方式。具體項目具體看了,理論上在CLK一定的情況下, 線數越多訪問速度也越快。我們項目采用的Dual SPI方式,即兩線。
淺析spi flash驅動及其程序

移植需要更改sendrcv函數里面內容,宏定義內容

[cpp] view plain copy《code class=“language-cpp”》#define DRV_SPI_FLASH_WRITE_ENABLE (0x06) //Write Enable

#define DRV_SPI_FLASH_WRITE_DISABLE (0x04) //Write Disable

#define DRV_SPI_FLASH_READ_STATUS_REG (0x05) //Read Status Register

#define DRV_SPI_FLASH_WRITE_STATUS_REG (0x01) //Write Status Register

#define DRV_SPI_FLASH_READ_DATA (0x03) //Read Data

#define DRV_SPI_FLASH_FAST_READ (0x0B) //Fast Read

#define DRV_SPI_FLASH_FAST_READ_DUAL_OUTPUT (0x3B) //Fast Read Dual Output

#define DRV_SPI_FLASH_PAGEPROGRAM (0x02) //Page Program

#define DRV_SPI_FLASH_BLOCK_ERASE (0xD8) //Block Erase(64KB)

#define DRV_SPI_FLASH_HALF_BLOCK_ERASE (0x52) //Half Block Erase(32KB)

#define DRV_SPI_FLASH_SECTOR_ERASE (0x20) //Sector Erase(4KB)

#define DRV_SPI_FLASH_CHIP_ERASE (0xC7) //Chip Erase

#define DRV_SPI_FLASH_JEDEC_ID (0x9F) //JEDEC ID

#define APP_SPI3_CS_LOW SCU_SetSpiCsn(SPI3_CSN,LOW)

#define APP_SPI3_CS_HIGH SCU_SetSpiCsn(SPI3_CSN,HIGH)

uint8_t DrvFlashSendRcvByte(uint8_t ucData)

{

uint8_t ucTemp;

while(SPI_GetFlagStatus(SGCC_SPI3_P,SPI_FLAG_RFNE))

ucTemp = SPI_ReceiveData(SGCC_SPI3_P);

SPI_SendData(SGCC_SPI3_P, ucData);

while(0 == SPI_GetFlagStatus(SGCC_SPI3_P,SPI_FLAG_RFNE));

ucTemp = SPI_ReceiveData(SGCC_SPI3_P);

return ucTemp;

}

uint32_t DrvFlashReadID(void)

{

uint32_t ulDevID = 0;

APP_SPI3_CS_LOW;

DrvFlashSendRcvByte(DRV_SPI_FLASH_JEDEC_ID);

ulDevID |= DrvFlashSendRcvByte(0xFF) 《《 16;

ulDevID |= DrvFlashSendRcvByte(0xFF) 《《 8;

ulDevID |= DrvFlashSendRcvByte(0xFF);

APP_SPI3_CS_HIGH;

return ulDevID;

}

uint8_t DrvFlashReadStausReg(void)

{

uint8_t ucReg;

APP_SPI3_CS_LOW;

DrvFlashSendRcvByte(DRV_SPI_FLASH_READ_STATUS_REG);

ucReg = DrvFlashSendRcvByte(0xFF);

APP_SPI3_CS_HIGH;

return ucReg;

}

void DrvFlashWaitBusy(void)

{

while((DrvFlashReadStausReg() & 0x01) == 0x01);

}

void DrvFlashWriteEnable(void)

{

APP_SPI3_CS_LOW;

DrvFlashSendRcvByte(DRV_SPI_FLASH_WRITE_ENABLE);

APP_SPI3_CS_HIGH;

}

void DrvFlashWriteDisable(void)

{

APP_SPI3_CS_LOW;

DrvFlashSendRcvByte(DRV_SPI_FLASH_WRITE_DISABLE);

APP_SPI3_CS_HIGH;

}

void DrvFlashReadData(uint8_t* pRcvBuf, uint32_t ulReAddr, uint16_t usReNum)

{

uint16_t i;

APP_SPI3_CS_LOW;

DrvFlashSendRcvByte(DRV_SPI_FLASH_READ_DATA);

DrvFlashSendRcvByte((uint8_t)((ulReAddr)》》16));

DrvFlashSendRcvByte((uint8_t)((ulReAddr)》》8));

DrvFlashSendRcvByte((uint8_t)ulReAddr);

for(i=0; i 《 usReNum; i++)

{

pRcvBuf[i] = DrvFlashSendRcvByte(0XFF);

}

APP_SPI3_CS_HIGH;

}

void DrvFlashPageWrite(uint8_t* pWrBuf, uint32_t ulWrAddr, uint16_t usWrNum)

{

uint16_t i;

DrvFlashWriteEnable();

APP_SPI3_CS_LOW;

DrvFlashSendRcvByte(DRV_SPI_FLASH_PAGEPROGRAM);

DrvFlashSendRcvByte((uint8_t)((ulWrAddr)》》16));

DrvFlashSendRcvByte((uint8_t)((ulWrAddr)》》8));

DrvFlashSendRcvByte((uint8_t)ulWrAddr);

for(i = 0; i 《 usWrNum; i++)

DrvFlashSendRcvByte(pWrBuf[i]);

APP_SPI3_CS_HIGH;

DrvFlashWaitBusy();

}

void DrvFlashWriteNoCheck(uint8_t* pBuffer, uint32_t addr, uint16_t num)

{

uint16_t pageremain;

pageremain = 256 - addr % 256;//鍗曢〉鍓╀綑瀛楄妭鏁?

if(num 《= pageremain)//涓嶅ぇ浜?256

pageremain = num;

while(1)

{

DrvFlashPageWrite(pBuffer, addr, pageremain);

if(num == pageremain)

break;//鍐欑粨鏉熶簡

else

{

pBuffer += pageremain;

addr += pageremain;

num -= pageremain;//鍑忓幓宸茬粡鍐欏叆鐨勫瓧鑺傛暟

if(num 》 256)

pageremain = 256;//鏈鍙互鍐欏叆涓?欏墊暟鎹?

else

pageremain = num;//鏈?鍚庝竴嬈″啓

}

};

}

void DrvFlashWriteData(uint8_t* pBuffer,uint32_t addr,uint16_t num)

{

uint32_t secpos;

uint16_t secoff;

uint16_t secremain;

uint16_t i;

uint8_t * W25QXX_BUF;

uint8_t W25QXX_BUFFER[4096];

W25QXX_BUF = W25QXX_BUFFER;

secpos = addr / 4096;//鎵囧尯鍦板潃

secoff = addr % 4096;//鍦ㄦ墖鍖哄唴鐨勫亸縐?

secremain = 4096 - secoff;//鎵囧尯鍓╀綑絀洪棿澶у皬

// printf

if(num 《= secremain)//涓嶅ぇ浜庡綋鍓嶆墖鍖哄墿浣欏瓧鑺?

{

secremain = num;

}

while(1)

{

DrvFlashReadData(W25QXX_BUF, secpos * 4096, 4096);//璇誨彇鏁翠釜鎵囧尯

for(i = 0; i 《 secremain; i++)//鏍¢獙鏁版嵁

{

if(W25QXX_BUF[secoff + i] != 0XFF)//闇?瑕佹摝鍑?

break;

}

if(i 《 secremain)//闇?瑕佹摝鍑?

{

DrvFlashSectorErase(secpos * 4096);//鎿﹂櫎鏁翠釜鎵囧尯

for(i = 0; i 《 secremain; i++)

{

W25QXX_BUF[i + secoff] = pBuffer[i];//澶嶅埗

}

DrvFlashWriteNoCheck(W25QXX_BUF, secpos * 4096, 4096);//鍐欏叆鏁翠釜鎵囧尯

}

else

DrvFlashWriteNoCheck(pBuffer, addr, secremain);//鍐欏凡緇忔摝闄や簡鐨勶紝鐩存帴鍐欏叆鎵囧尯鍓╀綑絀洪棿

if(num == secremain)

break;//鍐欑粨鏉熶簡

else//

{

secpos++;//鎵囧尯鍦板潃澧炲姞1

secoff = 0;//鍋忕Щ浣嶇疆涓?0

pBuffer += secremain;//鎸囬拡鍋忕Щ

addr += secremain;//鍐欏湴鍧?鍋忕Щ

num -= secremain;//瀛楄妭鏁伴?掑噺

if(num 》 4096)

secremain = 4096;//涓嬩竴涓墖鍖鴻繕鏄啓涓嶅畬

else

secremain = num;//涓嬩竴涓墖鍖哄彲浠ュ啓瀹屼簡

}

};

}

void DrvFlashChipErase(void)

{

DrvFlashWriteEnable();

DrvFlashWaitBusy();

APP_SPI3_CS_LOW;

DrvFlashSendRcvByte(DRV_SPI_FLASH_CHIP_ERASE);

APP_SPI3_CS_HIGH;

DrvFlashWaitBusy();

}

void DrvFlashSectorErase(uint32_t ulErAddr)

{

DrvFlashWriteEnable();

DrvFlashWaitBusy();

APP_SPI3_CS_LOW;

DrvFlashSendRcvByte(DRV_SPI_FLASH_SECTOR_ERASE);

DrvFlashSendRcvByte((uint8_t)((ulErAddr)》》16));

DrvFlashSendRcvByte((uint8_t)((ulErAddr)》》8));

DrvFlashSendRcvByte((uint8_t)ulErAddr);

APP_SPI3_CS_HIGH;

DrvFlashWaitBusy();

}

《/code》


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 驅動
    +關注

    關注

    12

    文章

    1725

    瀏覽量

    84487
  • SPI Flash
    +關注

    關注

    1

    文章

    13

    瀏覽量

    10255
收藏 人收藏

    評論

    相關推薦

    詳細講解重用外設驅動代碼_SPI_NOR_Flash存儲器

    第六章為重用外設驅動代碼,本文內容為6.2 SPI NOR Flash 存儲器。
    的頭像 發表于 12-21 07:59 ?1.4w次閱讀
    詳細講解重用外設<b class='flag-5'>驅動</b>代碼_<b class='flag-5'>SPI_NOR_Flash</b>存儲器

    開源的串行SPI Flash通用驅動庫SFUD的應用

    SFUD 是一款開源的串行 SPI Flash 通用驅動庫。由于現有市面的串行 Flash 種類居多,各個 Flash 的規格及命令存在差異
    的頭像 發表于 12-15 10:05 ?2393次閱讀

    Cheap_Flash_FS(普通版)(SPI_Flash版)--嵌入式SPI_FLASH文件系統免費源碼

    驅動接口函數.支持SPI_FLASH片上預分配功能(就是擦一次,寫多個扇區的功能)加快了FLASH的寫速度,且能降低內耗占用量.其上面可以運行FAT文件系統(支持多扇區操作).用戶使用本代碼,需要自己
    發表于 12-23 09:17

    SPI FLASH驅動

    、netdev組件2.3、協議棧組件2.4、netutils工具集軟件包2.5、webnet軟件包二、添加驅動和初始化代碼1、SPI FLASH驅動2、網卡
    發表于 08-19 09:16

    SPI方式FPGA配置和SPI flash編程

    SPI方式FPGA配置和SPI flash編程
    發表于 05-16 18:01 ?164次下載
    <b class='flag-5'>SPI</b>方式FPGA配置和<b class='flag-5'>SPI</b> <b class='flag-5'>flash</b>編程

    基于紅牛開發板的spi flash讀寫圖片

    SPI:serial peripheral interface串行外圍設備接口是一種常見的時鐘同步串行通信接口。外置flash按接口分有總線flash,SPI
    發表于 09-01 17:16 ?16次下載
    基于紅牛開發板的<b class='flag-5'>spi</b> <b class='flag-5'>flash</b>讀寫圖片

    SPI—外部FLASH-W25Q128

    -ST固件庫版本:1.5.1 【 !】功能簡介: 讀寫板載的SPI FLASH芯片。 學習目的:學習STM32的SPI驅動。 【 ??!】注意事項: 板子的
    發表于 12-13 15:13 ?97次下載

    SPI flash是什么,關于SPI FLASH的讀寫問題

    SPI一種通信接口。那么嚴格的來說SPI Flash是一種使用SPI通信的Flash,即,可能指NOR也可能是NAND。
    的頭像 發表于 09-18 14:38 ?10.2w次閱讀
    <b class='flag-5'>SPI</b> <b class='flag-5'>flash</b>是什么,關于<b class='flag-5'>SPI</b> <b class='flag-5'>FLASH</b>的讀寫問題

    SPI flash如何運行程序,SPI flash有哪些應用

    SPI一種通信接口。那么嚴格的來說SPI Flash是一種使用SPI通信的Flash,即,可能指NOR也可能是NAND。
    的頭像 發表于 09-19 10:54 ?1.8w次閱讀
    <b class='flag-5'>SPI</b> <b class='flag-5'>flash</b>如何運行<b class='flag-5'>程序</b>,<b class='flag-5'>SPI</b> <b class='flag-5'>flash</b>有哪些應用

    淺析FLASH讀寫----SPI原理及應用

    SPI一種通信接口。那么嚴格的來說SPI Flash是一種使用SPI通信的Flash,即,可能指NOR也可能是NAND。
    的頭像 發表于 10-07 11:32 ?2.3w次閱讀
    <b class='flag-5'>淺析</b><b class='flag-5'>FLASH</b>讀寫----<b class='flag-5'>SPI</b>原理及應用

    關于SPI_FLASH時序描述及驅動編程

    SPI_FLASH時序描述及驅動編程
    的頭像 發表于 03-25 11:15 ?3277次閱讀
    關于<b class='flag-5'>SPI_FLASH</b>時序描述及<b class='flag-5'>驅動</b>編程

    STM32_ SPI讀寫Flash

    STM32_SPI讀寫Flash
    的頭像 發表于 04-08 10:26 ?5017次閱讀
    STM32_ <b class='flag-5'>SPI</b>讀寫<b class='flag-5'>Flash</b>

    用于SPI軟件的Windows 7驅動程序

    用于SPI軟件的Windows 7驅動程序
    發表于 06-10 15:13 ?9次下載
    用于<b class='flag-5'>SPI</b>軟件的Windows 7<b class='flag-5'>驅動程序</b>

    SPI Nand Flash簡介

    1.SPI Nand Flash簡介SPI Nand Flash顧名思義就是串行接口的Nand Flash,它和普通并行的Nand
    發表于 12-02 10:51 ?34次下載
    <b class='flag-5'>SPI</b> Nand <b class='flag-5'>Flash</b>簡介

    如何優化MCU SPI驅動程序以實現高ADC吞吐速率

    如何優化MCU SPI驅動程序以實現高ADC吞吐速率
    的頭像 發表于 10-24 16:03 ?385次閱讀
    如何優化MCU <b class='flag-5'>SPI</b><b class='flag-5'>驅動程序</b>以實現高ADC吞吐速率
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>