spi概述
SPI是串行外設(shè)接口(Serial Peripheral Interface)的縮寫,是一種高速的,全雙工,同步的通信總線,并且在芯片的管腳上只占用四根線,節(jié)約了芯片的管腳,同時為PCB的布局上節(jié)省空間,提供方便,正是出于這種簡單易用的特性,越來越多的芯片集成了這種通信協(xié)議,比如 EEPROM,F(xiàn)LASH,實時時鐘,AD轉(zhuǎn)換器。 W25Q64 是一款SPI接口的Flash芯片,其存儲空間為 64Mbit,相當(dāng)于8M字節(jié)。W25Q64可以支持 SPI 的模式 0 和模式 3,也就是 CPOL=0/CPHA=0 和CPOL=1/CPHA=1 這兩種模式。
視頻教程
https://www.bilibili.com/video/BV16W4y147R1/
樣品申請
https://www.wjx.top/vm/wFGhGPF.aspx#
csdn課程
課程更加詳細。
https://download.csdn.net/course/detail/37144
生成例程
這里準備了自己繪制的開發(fā)板進行驗證。
SPI配置
在開發(fā)板中有arduino接口,配置這幾個接口為spi。
本次實驗使用的SPI與Flash通信,配置如下。 SPI的通信原理很簡單,它以主從方式工作,這種模式通常有一個主設(shè)備和一個或多個從設(shè)備,需要至少4根線,事實上3根也可以(單向傳輸時)。也是所有基于SPI的設(shè)備共有的,它們是MISO(主設(shè)備數(shù)據(jù)輸入)、MOSI(主設(shè)備數(shù)據(jù)輸出)、SCLK(時鐘)、CS(片選)。 (1)MISO– Master Input Slave Output,主設(shè)備數(shù)據(jù)輸入,從設(shè)備數(shù)據(jù)輸出; (2)MOSI– Master Output Slave Input,主設(shè)備數(shù)據(jù)輸出,從設(shè)備數(shù)據(jù)輸入; (3)SCLK – Serial Clock,時鐘信號,由主設(shè)備產(chǎn)生; (4)CS – Chip Select,從設(shè)備使能信號,由主設(shè)備控制。
負責(zé)通訊的3根線了。通訊是通過數(shù)據(jù)交換完成的,這里先要知道SPI是串行通訊協(xié)議,也就是說數(shù)據(jù)是一位一位的傳輸?shù)摹_@就是SCLK時鐘線存在的原因,由SCLK提供時鐘脈沖,SDI,SDO則基于此脈沖完成數(shù)據(jù)傳輸。數(shù)據(jù)輸出通過 SDO線,數(shù)據(jù)在時鐘上升沿或下降沿時改變,在緊接著的下降沿或上升沿被讀取。完成一位數(shù)據(jù)傳輸,輸入也使用同樣原理。因此,至少需要8次時鐘信號的改變(上沿和下沿為一次),才能完成8位數(shù)據(jù)的傳輸。 時鐘信號線SCLK只能由主設(shè)備控制,從設(shè)備不能控制。同樣,在一個基于SPI的設(shè)備中,至少有一個主設(shè)備。這樣的傳輸方式有一個優(yōu)點,在數(shù)據(jù)位的傳輸過程中可以暫停,也就是時鐘的周期可以為不等寬,因為時鐘線由主設(shè)備控制,當(dāng)沒有時鐘跳變時,從設(shè)備不采集或傳送數(shù)據(jù)。SPI還是一個數(shù)據(jù)交換協(xié)議:因為SPI的數(shù)據(jù)輸入和輸出線獨立,所以允許同時完成數(shù)據(jù)的輸入和輸出。芯片集成的SPI串行同步時鐘極性和相位可以通過寄存器配置,IO模擬的SPI串行同步時鐘需要根據(jù)從設(shè)備支持的時鐘極性和相位來通訊。 最后,SPI接口的一個缺點:沒有指定的流控制,沒有應(yīng)答機制確認是否接收到數(shù)據(jù)。
NOR Flash
NOR Flash是一種非易失閃存技術(shù),是Intel在1988年創(chuàng)建。是市場上兩種主要的非易失閃存技術(shù)之一。 以GD25Q64E為例,該 Flash為64M-bit大小,即8192K-Byte。
W25Q64將8M的容量分為127個塊(Block),每個塊大小為64K字節(jié),每個塊又分為16個扇區(qū)(Sector),每個扇區(qū)4K個字節(jié)。W25Q64的最小擦除單位為一個扇區(qū),也就是每次必須擦除4K個字節(jié)。 即4K16128=8192K=8M
W25Q64的原理及應(yīng)用
復(fù)位初始化
對于復(fù)位,需要發(fā)送0x66和0x99
代碼中的初始化。
/* Reset Operations */
#define RESET_ENABLE_CMD 0x66
#define RESET_MEMORY_CMD 0x99
/**
* @brief Initializes the W25Q128FV interface.
* @retval None
*/
uint8_t BSP_W25Qx_Init(void)
{
/* Reset W25Qxxx */
BSP_W25Qx_Reset();
return BSP_W25Qx_GetStatus();
}
/**
* @brief This function reset the W25Qx.
* @retval None
*/
static void BSP_W25Qx_Reset(void)
{
uint8_t cmd[2] = {RESET_ENABLE_CMD,RESET_MEMORY_CMD};
W25Qx_Enable();
/* Send the reset command */
for(int i=0;i< 2;i++){
spi_SendRcvByte(SPI0,cmd[i]);
}
// HAL_SPI_Transmit(&hspi1, cmd, 2, W25Qx_TIMEOUT_VALUE);
W25Qx_Disable();
}
ID
對于兆易創(chuàng)新W25Q64,主要有三種查詢ID方式。
可以使用90H查詢設(shè)備ID,以判斷是否是W25Q64設(shè)備。
/* Identification Operations */
#define READ_ID_CMD 0x9F
/**
* @brief Read Manufacture/Device ID.
* @param return value address
* @retval None
*/
void BSP_W25Qx_Read_ID(uint8_t *ID)
{
uint8_t cmd[4] = {READ_ID_CMD,0x00,0x00,0x00};
W25Qx_Enable();
/* Send the read ID command */
// HAL_SPI_Transmit(&hspi1, cmd, 4, W25Qx_TIMEOUT_VALUE);
/* Reception of the data */
// HAL_SPI_Receive(&hspi1,ID, 2, W25Qx_TIMEOUT_VALUE);
for(int i=0;i< 4;i++)
spi_SendRcvByte(SPI0,cmd[i]);
for(int i=0;i< 2;i++)
{
ID[i]=spi_SendRcvByte(SPI0,0x00);
}
W25Qx_Disable();
}
讀取數(shù)據(jù)
對于兆易創(chuàng)新W25Q64,讀取數(shù)據(jù)使用0x03指令,后面添加需要讀取的數(shù)據(jù)地址。 數(shù)據(jù)可以一直進行讀取,當(dāng)不需要讀取數(shù)據(jù)時候?qū)⑵xCS拉高,關(guān)閉時鐘SCLK即可。
#define READ_CMD 0x03
/**
* @brief Reads an amount of data from the QSPI memory.
* @param pData: Pointer to data to be read
* @param ReadAddr: Read start address
* @param Size: Size of data to read
* @retval QSPI memory status
*/
uint8_t BSP_W25Qx_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size)
{
uint8_t cmd[4];
uint8_t status;
/* Configure the command */
cmd[0] = READ_CMD;
cmd[1] = (uint8_t)(ReadAddr > > 16);
cmd[2] = (uint8_t)(ReadAddr > > 8);
cmd[3] = (uint8_t)(ReadAddr);
W25Qx_Enable();
/* Send the read ID command */
// HAL_SPI_Transmit(&hspi1, cmd, 4, W25Qx_TIMEOUT_VALUE);
for(int i= 0;i< 4;i++)
spi_SendRcvByte(SPI0,cmd[i]);
/* Reception of the data */
// if (HAL_SPI_Receive(&hspi1, pData,Size,W25Qx_TIMEOUT_VALUE) != HAL_OK)
// {
// return W25Qx_ERROR;
// }
for(int i= 0;i< Size;i++)
pData[i]=spi_SendRcvByte(SPI0,0x00);
if (status != 0x00)
{
return W25Qx_ERROR;
}
W25Qx_Disable();
return W25Qx_OK;
}
以讀取10個數(shù)據(jù)為例子,波形如下所示。
BSP_W25Qx_Read(rData2,0x1000,0x00a);
擦除扇區(qū)
最小的擦除單位是扇區(qū),擦除指令為0x20和3字節(jié)的地址。
#define SECTOR_ERASE_CMD 0x20
/**
* @brief Erases the specified block of the QSPI memory.
* @param BlockAddress: Block address to erase
* @retval QSPI memory status
*/
uint8_t BSP_W25Qx_Erase_Block(uint32_t Address)
{
uint8_t cmd[4];
uint32_t tickstart=0 ;
cmd[0] = SECTOR_ERASE_CMD;
cmd[1] = (uint8_t)(Address > > 16);
cmd[2] = (uint8_t)(Address > > 8);
cmd[3] = (uint8_t)(Address);
/* Enable write operations */
BSP_W25Qx_WriteEnable();
/*Select the FLASH: Chip Select low */
W25Qx_Enable();
/* Send the read ID command */
// HAL_SPI_Transmit(&hspi1, cmd, 4, W25Qx_TIMEOUT_VALUE);
for(int i =0;i< 4;i++)
spi_SendRcvByte(SPI0,cmd[i]);
/*Deselect the FLASH: Chip Select high */
W25Qx_Disable();
delay_1ms(1);
/* Wait the end of Flash writing */
while(BSP_W25Qx_GetStatus() == W25Qx_BUSY)
{
tickstart++;
/* Check for the Timeout */
if(tickstart > W25Q128FV_SECTOR_ERASE_MAX_TIME)
{
return W25Qx_TIMEOUT;
}
}
return W25Qx_OK;
}
寫數(shù)據(jù)
對于寫數(shù)據(jù)到flash中,使用0x02指令進行寫數(shù)據(jù),后面還需要指定24位地址,才能進行寫數(shù)據(jù)。
#define PAGE_PROG_CMD 0x02
/**
* @brief Writes an amount of data to the QSPI memory.
* @param pData: Pointer to data to be written
* @param WriteAddr: Write start address
* @param Size: Size of data to write,No more than 256byte.
* @retval QSPI memory status
*/
uint8_t BSP_W25Qx_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size)
{
uint8_t cmd[4];
uint32_t end_addr, current_size, current_addr;
uint32_t tickstart =0;
/* Calculation of the size between the write address and the end of the page */
current_addr = 0;
while (current_addr <= WriteAddr)//判斷地址屬于哪一扇區(qū)開始
{
current_addr += W25Q128FV_PAGE_SIZE;//0x100- > 256 bytes
}
current_size = current_addr - WriteAddr;
/* Check if the size of the data is less than the remaining place in the page */
if (current_size > Size)
{
current_size = Size;
}
/* Initialize the adress variables *///寫入地址大小范圍
current_addr = WriteAddr;
end_addr = WriteAddr + Size;
/* Perform the write page by page */
do
{
/* Configure the command */
cmd[0] = PAGE_PROG_CMD;
cmd[1] = (uint8_t)(current_addr > > 16);
cmd[2] = (uint8_t)(current_addr > > 8);
cmd[3] = (uint8_t)(current_addr);
/* Enable write operations */
BSP_W25Qx_WriteEnable();
W25Qx_Enable();
/* Send the command */
// if (HAL_SPI_Transmit(&hspi1,cmd, 4, W25Qx_TIMEOUT_VALUE) != HAL_OK)
// {
// return W25Qx_ERROR;
// }
for(int i=0;i< 4;i++)
spi_SendRcvByte(SPI0,cmd[i]);
/* Transmission of the data */
// if (HAL_SPI_Transmit(&hspi1, pData,current_size, W25Qx_TIMEOUT_VALUE) != HAL_OK)
// {
// return W25Qx_ERROR;
// }
for(int i=0;i< current_size;i++)
spi_SendRcvByte(SPI0,pData[i]);
W25Qx_Disable();
/* Wait the end of Flash writing */
while(BSP_W25Qx_GetStatus() == W25Qx_BUSY)
{
tickstart++;
/* Check for the Timeout */
if(tickstart > W25Qx_TIMEOUT_VALUE)
{
return W25Qx_TIMEOUT;
}
}
/* Update the address and size variables for next page programming */
current_addr += current_size;
上一篇:基于GD32E503主控芯片實現(xiàn)直流數(shù)控電源的設(shè)計
下一篇:STM32CUBEMX開發(fā)GD32F303(2)----讀保護與寫保護
推薦閱讀最新更新時間:2025-04-17 20:12





設(shè)計資源 培訓(xùn) 開發(fā)板 精華推薦
- 英飛凌微控制器:以全新實惠套件和強大開發(fā)環(huán)境為開發(fā)者提供支持
- iTOP-i.MX6開發(fā)板設(shè)備數(shù)驅(qū)動Menuconfig的用法
- 迅為IMX6ULL開發(fā)板Qt for Android搭建開發(fā)環(huán)境
- 迅為i.MX8M mini開發(fā)板Windots QT系統(tǒng)開發(fā)環(huán)境搭建
- 迅為IMX8MM開發(fā)板Yocto系統(tǒng)使用Gstarwmra(一)
- 迅為IMX8M mini開發(fā)板Linix系統(tǒng)修改默認屏幕
- iTOP-4412開發(fā)板支持4G以上文件系統(tǒng)擴展
- 迅為IMX8MM開發(fā)板Yocto系統(tǒng)設(shè)置開機自啟動
- 迅為IMX6Q開發(fā)板 Buildroot文件系統(tǒng)mqtt測試
- 【Little-Emma】簡易脈搏血氧儀
- 用于CMOS圖像傳感器的TCR5BM/8BM系列LDO穩(wěn)壓器的應(yīng)用電路
- LT6656BCDC-2.5、2.5V 擴展電源范圍電壓基準的典型應(yīng)用
- 3相直流無刷電機驅(qū)動IC —— TB67Z800FTG
- 【涂鴉智能】溫濕度模塊+127737W
- LTC1550LCS8 -4.1V 輸出 GaAs FET 偏置發(fā)生器的典型應(yīng)用電路
- LTC2945IMS 雙電源監(jiān)視器的典型應(yīng)用,具有用于電流隔離的通用光電耦合器
- 使用 Analog Devices 的 24LC025-I/ST 的參考設(shè)計
- MC33074ADTBR2G光伏電池放大器的典型應(yīng)用
- nrf58410_keyboard
- 復(fù)旦大學(xué)在集成電路領(lǐng)域獲關(guān)鍵突破!每秒存取25億次,史上最快!
- 星閃強勢入局,會給UWB與藍牙定位帶來哪些沖擊?
- 又兩款旗艦新車搭載星閃車鑰匙!誰在引爆這波汽車連接革命?
- 榜單首發(fā)!域控SerDes處于市場爆發(fā)周期,哪些供應(yīng)商正在領(lǐng)跑市場
- 英特爾? 具身智能大小腦融合方案發(fā)布:構(gòu)建具身智能落地新范式
- 車載UWB雷達技術(shù):有哪些優(yōu)勢?
- 嵐圖開啟L3智駕:天元智能架構(gòu)技術(shù)解讀
- 德州儀器如何通過7000多種車規(guī)芯片,引領(lǐng)汽車產(chǎn)業(yè)的創(chuàng)新
- 2025年上海國際車展技術(shù)前瞻 – 智駕安全(環(huán)境感知)
- 史上最嚴動力電池國標(biāo)解讀:爆燃零容忍,倒逼廠家不打嘴炮真研發(fā)
- 瑞薩電子RL78/G14評估板DIY精彩上演!
- 泰克移動多媒體總線系列專題來襲~《HDMI2.0規(guī)范測試方案》下載有禮!
- 拆驚喜抽獎:泰克全新3系列MDO和4系列MSO示波器來啦
- Microchip ShieldsUP!安全解決方案系列在線研討會
- 今日競拍:TI SimpleLink Wifi CC3220S
- 【主題月活動】小電阻,大智慧!
- 下載《TI MCU與無線連接技術(shù)研討會講座實錄》抽獎贏好禮!
- 報名贏【掛燈、浴巾】等好禮|TI MSPM0家用電器和電機控制應(yīng)用詳解
- 有獎活動 | 來 Pl BridgeSwitch™ 技術(shù)中心探秘半橋電機驅(qū)動器新技術(shù)
- 全球最牛集成電路大咖企業(yè)齊聚 兩大項目落地成都
- 失去段永平的20年:小霸王轉(zhuǎn)型VR機器人謀上市
- 高通證實開始在加州裁員以削減成本 規(guī)模約1500人
- 人工智能校企合作成趨勢——科技巨頭拉開人才爭奪戰(zhàn)(上篇)
- 機器人現(xiàn)身日本競選市長 承諾公平對待每一個人
- 怪異機器人拉開了CES2020的序幕
- 傳感器在機器人研究發(fā)展歷程中扮演著重要角色
- 能繞地球1.3圈!2019年國網(wǎng)110kV及以上電網(wǎng)基建工程超額完成任務(wù)
- 儲能系統(tǒng)抑制電網(wǎng)功率振蕩的機理研究
- 臺達、陽光、ABB 印度前五大逆變器供應(yīng)商排名公布!