做網(wǎng)站接私活百度推廣助手手機(jī)版
SPI的簡(jiǎn)介
文章目錄
- SPI的簡(jiǎn)介
- 物理層
- 協(xié)議層
- 基本通訊過(guò)程
- 起始和終止信號(hào)
- 數(shù)據(jù)有效性
- CPOL/CPHA及通訊模式
- STM3的SPI特性及架構(gòu)
- 通訊引腳
- 時(shí)鐘控制邏輯
- 數(shù)據(jù)控制邏輯
- 整體控制邏輯
- 通訊過(guò)程
- 代碼配置實(shí)現(xiàn)
- 指令集
- 結(jié)構(gòu)體的定義
- SPI時(shí)鐘信號(hào)的定義
- SPI端口定義
- SPI命令
- flash驅(qū)動(dòng)代碼
- 初始化代碼(配置端口)
- 配置SPI模式代碼
- 發(fā)送并接受一個(gè)字節(jié)
- 讀取字節(jié)
- 讀取ID號(hào)
- FLASH寫入使能
- 等待FLASH內(nèi)部時(shí)序操作完成
- 擦除FLASH指定扇區(qū)
物理層
SPI一共三條總線
SPI總線 | 功能 |
---|---|
SS( Slave Select) | 選從機(jī) |
SCK (Serial Clock) | 時(shí)鐘信號(hào)線,用于通訊數(shù)據(jù)同步。它由通訊主機(jī)產(chǎn)生,決定了通訊的速率 |
MOSI (Master Output,Slave Input) | 主設(shè)備輸出/從設(shè)備輸入引腳。這條線上數(shù)據(jù)的方向?yàn)橹鳈C(jī)到從機(jī)。 |
MISO (Master Input,,Slave Output) | 主設(shè)備輸入/從設(shè)備輸出引腳。在這條線上數(shù)據(jù)的方向?yàn)閺臋C(jī)到主機(jī)。 |
協(xié)議層
基本通訊過(guò)程
- NSS為低電平時(shí)候才有效
- SCK每一個(gè)周期MOSI和MISO傳輸一位數(shù)據(jù)
起始和終止信號(hào)
- 起始:高變低
- 終止:低變高
數(shù)據(jù)有效性
- SPI 使用 MOSI 及 MISO 信號(hào)線來(lái)傳輸數(shù)據(jù),使用 SCK 信號(hào)線進(jìn)行數(shù)據(jù)同步。MOSI 及 MISO 數(shù)據(jù)線在 SCK 的每個(gè)時(shí)鐘周期傳輸一位數(shù)據(jù),且數(shù)據(jù)輸入輸出是同時(shí)進(jìn)行的。數(shù)據(jù)傳輸時(shí),MSB先行或 LSB 先行并沒有作硬性規(guī)定,但要保證兩個(gè) SPI 通訊設(shè)備之間使用同樣的協(xié)定,一般都會(huì)采用圖 SPI 通訊時(shí)序 中的 MSB 先行模式。
- 即在 SCK 的下降沿時(shí)刻,MOSI 及 MISO 的數(shù)據(jù)有效,高電平時(shí)表示數(shù)據(jù)“1”,為低電平時(shí)表示數(shù)據(jù)“0”。在其它時(shí)刻,數(shù)據(jù)無(wú)效,MOSI 及 MISO 為下一次表示數(shù)據(jù)做準(zhǔn)備。SPI 每次數(shù)據(jù)傳輸可以 8 位或 16 位為單位,每次傳輸?shù)膯挝粩?shù)不受限制。
CPOL/CPHA及通訊模式
CPHA:當(dāng) CPHA=0 時(shí),MOSI 或 MISO 數(shù)據(jù)線上的信號(hào)將會(huì)在SCK 時(shí)鐘線的“奇數(shù)邊沿”被采樣。當(dāng) CPHA=1 時(shí),數(shù)據(jù)線在 SCK 的“偶數(shù)邊沿”采樣。一個(gè)邊沿被設(shè)置為采樣后另一個(gè)邊沿只能為讀取數(shù)據(jù)。
CPOL:控制SCK空閑時(shí)刻的電平,0為低電平,1為高電平。
STM3的SPI特性及架構(gòu)
通訊引腳
時(shí)鐘控制邏輯
由波特率發(fā)生器根據(jù)“控制寄存器 CR1”中的 BR[0:2] 位控制
數(shù)據(jù)控制邏輯
SPI 的 MOSI 及 MISO 都連接到數(shù)據(jù)移位寄存器上,數(shù)據(jù)移位寄存器的數(shù)據(jù)來(lái)源及目標(biāo)接收、發(fā)送緩沖區(qū)以及 MISO、MOSI 線。
當(dāng)從外部接收數(shù)據(jù)的時(shí)候,數(shù)據(jù)移位寄存器把數(shù)據(jù)線采樣到的數(shù)據(jù)一位一位地存儲(chǔ)到“接收緩沖區(qū)”中。
通過(guò)寫 SPI 的“數(shù)據(jù)寄存器 DR”把數(shù)據(jù)填充到發(fā)送緩沖區(qū)中,通訊讀“數(shù)據(jù)寄存器 DR”,可以獲取接收緩沖區(qū)中的內(nèi)容。
DR[15:0]:數(shù)據(jù)寄存器 (Data register) 待發(fā)送或者已經(jīng)收到的數(shù)據(jù)
數(shù)據(jù)寄存器對(duì)應(yīng)兩個(gè)緩沖區(qū):一個(gè)用于寫(發(fā)送緩沖);另外一個(gè)用于讀(接收緩沖)。寫操作將數(shù)據(jù)寫到發(fā)送緩沖區(qū);讀操作將返回接收緩沖區(qū)里的數(shù)據(jù)。
**對(duì)SPI模式的注釋:**根據(jù)SPI_CR1的DFF位對(duì)數(shù)據(jù)幀格式的選擇,數(shù)據(jù)的發(fā)送和接收可以是8位或者16位的。為保證正確的操作,需要在啟用SPI之前就確定好數(shù)據(jù)幀格式。
對(duì)于8位的數(shù)據(jù),緩沖器是8位的,發(fā)送和接收時(shí)只會(huì)用到SPI_DR[7:0]。在接收時(shí),SPI_DR[15:8]被強(qiáng)制為0。
對(duì)于16位的數(shù)據(jù),緩沖器是16位的,發(fā)送和接收時(shí)會(huì)用到整個(gè)數(shù)據(jù)寄存器,即SPI_DR[15:0]。
**其中數(shù)據(jù)幀:**長(zhǎng)度可以通過(guò)“控制寄存器 CR1”的“DFF 位”配置成 8 位及 16 位模式;配置“LSBFIRST 位”可選擇 MSB 先行還是 LSB 先行。
整體控制邏輯
整體控制邏輯負(fù)責(zé)協(xié)調(diào)整個(gè) SPI 外設(shè),控制邏輯的工作模式根據(jù)我們配置的“控制寄存器(CR1/CR2)”的參數(shù)而改變基本的控制參數(shù)包括前面提到的 SPI 模式、波特率、LSB 先行、主從模式、單雙向模式等等。
通訊過(guò)程
(1) 控制 NSS 信號(hào)線,產(chǎn)生起始信號(hào) (圖中沒有畫出);
(2) 把要發(fā)送的數(shù)據(jù)寫入到“數(shù)據(jù)寄存器 DR”中,該數(shù)據(jù)會(huì)被存儲(chǔ)到發(fā)送緩沖區(qū);
(3) 通訊開始,SCK 時(shí)鐘開始運(yùn)行。MOSI 把發(fā)送緩沖區(qū)中的數(shù)據(jù)一位一位地傳輸出去;MISO 則把數(shù)據(jù)一位一位地存儲(chǔ)進(jìn)接收緩沖區(qū)中;
(4) 當(dāng)發(fā)送完一幀數(shù)據(jù)的時(shí)候,“狀態(tài)寄存器 SR”中的“TXE 標(biāo)志位”會(huì)被置 1,表示傳輸完一幀,發(fā)送緩沖區(qū)已空;類似地,當(dāng)接收完一幀數(shù)據(jù)的時(shí)候,“RXNE 標(biāo)志位”會(huì)被置 1,表示傳輸完一幀,接收緩沖區(qū)非空;
(5) 等待到“TXE 標(biāo)志位”為 1 時(shí),若還要繼續(xù)發(fā)送數(shù)據(jù),則再次往“數(shù)據(jù)寄存器 DR”寫入數(shù)據(jù)即可;等待到“RXNE 標(biāo)志位”為 1 時(shí),通過(guò)讀取“數(shù)據(jù)寄存器 DR”可以獲取接收緩沖區(qū)中的內(nèi)容。假如我們使能了 TXE 或 RXNE 中斷,TXE 或 RXNE 置 1 時(shí)會(huì)產(chǎn)生 SPI 中斷信號(hào),進(jìn)入同一個(gè)中斷服務(wù)函數(shù),到 SPI 中斷服務(wù)程序后,可通過(guò)檢查寄存器位來(lái)了解是哪一個(gè)事件,再分別進(jìn)行處理。也可以使用 DMA 方式來(lái)收發(fā)“數(shù)據(jù)寄存器 DR”中的數(shù)據(jù)
代碼配置實(shí)現(xiàn)
指令集
結(jié)構(gòu)體的定義
SPI時(shí)鐘信號(hào)的定義
#define FLASH_SPIx SPI1
#define FLASH_SPI_APBxClock_FUN RCC_APB2PeriphClockCmd
#define FLASH_SPI_CLK RCC_APB2Periph_SPI1
#define FLASH_SPI_GPIO_APBxClock_FUN RCC_APB2PeriphClockCmd
SPI端口定義
#define FLASH_SPI_SCK_PORT GPIOA
#define FLASH_SPI_SCK_PIN GPIO_Pin_5#define FLASH_SPI_MOSI_PORT GPIOA
#define FLASH_SPI_MOSI_PIN GPIO_Pin_7#define FLASH_SPI_MISO_PORT GPIOA
#define FLASH_SPI_MISO_PIN GPIO_Pin_6#if (USE_BD ==1)#define FLASH_SPI_GPIO_CLK RCC_APB2Periph_GPIOA#define FLASH_SPI_CS_PORT GPIOA #define FLASH_SPI_CS_PIN GPIO_Pin_4
#else#define FLASH_SPI_GPIO_CLK (RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC)#define FLASH_SPI_CS_PORT GPIOC#define FLASH_SPI_CS_PIN GPIO_Pin_0
#endif
SPI命令
#define DUMMY 0x00
#define READ_JEDEC_ID 0x9f
#define ERASE_SECTOR 0x20
#define READ_STATUS 0x05
#define READ_DATA 0x03
#define WRITE_ENABLE 0x06
#define WRITE_DATA 0x02
flash驅(qū)動(dòng)代碼
初始化代碼(配置端口)
/*** @brief SPII/O配置* @param 無(wú)* @retval 無(wú)*/
static void SPI_GPIO_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure; /* 使能與SPI 有關(guān)的時(shí)鐘 */FLASH_SPI_APBxClock_FUN ( FLASH_SPI_CLK, ENABLE );FLASH_SPI_GPIO_APBxClock_FUN ( FLASH_SPI_GPIO_CLK, ENABLE );/* MISO MOSI SCK*/GPIO_InitStructure.GPIO_Pin = FLASH_SPI_SCK_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(FLASH_SPI_SCK_PORT, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = FLASH_SPI_MOSI_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(FLASH_SPI_MOSI_PORT, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = FLASH_SPI_MISO_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(FLASH_SPI_MISO_PORT, &GPIO_InitStructure);//初始化CS引腳,使用軟件控制,所以直接設(shè)置成推挽輸出 GPIO_InitStructure.GPIO_Pin = FLASH_SPI_CS_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(FLASH_SPI_CS_PORT, &GPIO_InitStructure);FLASH_SPI_CS_HIGH;
}
配置SPI模式代碼
static void SPI_Mode_Config(void)
{SPI_InitTypeDef SPI_InitStructure; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2 ;//SPI 使用模式3SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge ;SPI_InitStructure.SPI_CPOL = SPI_CPOL_High ;SPI_InitStructure.SPI_CRCPolynomial = 0;//不使用CRC功能,數(shù)值隨便寫SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex ;//雙線全雙工SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB ;SPI_InitStructure.SPI_Mode = SPI_Mode_Master ;SPI_InitStructure.SPI_NSS = SPI_NSS_Soft ; SPI_Init(FLASH_SPIx,&SPI_InitStructure); //寫入配置到寄存器SPI_Cmd(FLASH_SPIx,ENABLE);//使能SPI}
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge ;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High ;
這段代碼設(shè)置了 SPI 的時(shí)鐘相位(Clock Phase),具體來(lái)說(shuō),SPI_CPHA_2Edge
表示在第二個(gè)時(shí)鐘沿(第二個(gè)邊沿)采樣數(shù)據(jù)。讓我們分解這個(gè)設(shè)置:
SPI_CPHA
是 SPI_InitTypeDef 結(jié)構(gòu)體中的一個(gè)成員,用于配置 SPI 的時(shí)鐘相位。SPI_CPHA_2Edge
是一個(gè)預(yù)定義的常量,它表示在第二個(gè)時(shí)鐘沿(2Edge)采樣數(shù)據(jù)。
時(shí)鐘相位(Clock Phase)決定了在時(shí)鐘的哪個(gè)邊沿?cái)?shù)據(jù)應(yīng)該被采樣或變更。在 SPI 通信中,時(shí)鐘相位通常有兩個(gè)選項(xiàng):第一個(gè)時(shí)鐘沿(1Edge)和第二個(gè)時(shí)鐘沿(2Edge)。
- 當(dāng)設(shè)置為
SPI_CPHA_1Edge
時(shí),數(shù)據(jù)在第一個(gè)時(shí)鐘沿(上升沿或下降沿)被采樣或變更。 - 當(dāng)設(shè)置為
SPI_CPHA_2Edge
時(shí),數(shù)據(jù)在第二個(gè)時(shí)鐘沿被采樣或變更。
在這個(gè)代碼片段中,通過(guò)設(shè)置 SPI_CPHA
為 SPI_CPHA_2Edge
,表明數(shù)據(jù)在第二個(gè)時(shí)鐘沿被采樣。這樣的設(shè)置通常取決于與 SPI 設(shè)備通信的具體協(xié)議和要求。
綜合一下這段代碼是下降沿采樣
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB ;
這段代碼設(shè)置了 SPI 數(shù)據(jù)傳輸?shù)钠鹗嘉弧>唧w來(lái)說(shuō),SPI_FirstBit_MSB
表示數(shù)據(jù)傳輸?shù)钠鹗嘉皇亲罡哂行?#xff08;Most Significant Bit,MSB)。
在 SPI 數(shù)據(jù)傳輸中,每個(gè)字節(jié)都由多個(gè)位組成,通常是8位。字節(jié)中的最高有效位是二進(jìn)制表示中的最左邊的位,而最低有效位則是最右邊的位。
通過(guò)設(shè)置 SPI_FirstBit
為 SPI_FirstBit_MSB
,代碼指定了數(shù)據(jù)傳輸時(shí)先傳輸最高有效位,然后依次傳輸剩余的位。這通常符合大多數(shù) SPI 設(shè)備和通信協(xié)議的約定,但在某些情況下,可能需要根據(jù)具體設(shè)備的要求進(jìn)行調(diào)整。
發(fā)送并接受一個(gè)字節(jié)
static uint32_t SPI_TIMEOUT_UserCallback(uint8_t errorCode)
{/* Block communication and all processes */FLASH_ERROR("SPI 等待超時(shí)!errorCode = %d",errorCode);return 0;
}
uint8_t SPI_FLASH_Send_Byte(uint8_t data)
{SPITimeout = SPIT_FLAG_TIMEOUT;//檢查并等待至TX緩沖區(qū)為空while(SPI_I2S_GetFlagStatus(FLASH_SPIx,SPI_I2S_FLAG_TXE) == RESET){if((SPITimeout--) == 0) return SPI_TIMEOUT_UserCallback(0);}//程序執(zhí)行到此處,TX緩沖區(qū)已空SPI_I2S_SendData (FLASH_SPIx,data);SPITimeout = SPIT_FLAG_TIMEOUT;//檢查并等待至RX緩沖區(qū)為非空while(SPI_I2S_GetFlagStatus(FLASH_SPIx,SPI_I2S_FLAG_RXNE) == RESET){if((SPITimeout--) == 0) return SPI_TIMEOUT_UserCallback(0);} //程序執(zhí)行到此處,說(shuō)明數(shù)據(jù)發(fā)送完畢,并接收到一字字節(jié) return SPI_I2S_ReceiveData(FLASH_SPIx); //返回的數(shù)據(jù)是他排出的}
這段代碼涉及 SPI 數(shù)據(jù)的發(fā)送和接收,以下是代碼的主要步驟解釋:
-
發(fā)送數(shù)據(jù):
SPI_I2S_SendData(FLASH_SPIx, data);
通過(guò)調(diào)用
SPI_I2S_SendData
函數(shù),將數(shù)據(jù)data
發(fā)送到 SPI 設(shè)備。 -
等待接收緩沖區(qū)非空:
SPITimeout = SPIT_FLAG_TIMEOUT; while(SPI_I2S_GetFlagStatus(FLASH_SPIx, SPI_I2S_FLAG_RXNE) == RESET) {if((SPITimeout--) == 0) return SPI_TIMEOUT_UserCallback(0); }
這部分代碼在一個(gè)循環(huán)中檢查 SPI 接收緩沖區(qū)是否為非空(
SPI_I2S_FLAG_RXNE
表示接收緩沖區(qū)非空)。循環(huán)會(huì)一直等待,直到接收緩沖區(qū)有數(shù)據(jù)或超時(shí)。 -
接收數(shù)據(jù):
return SPI_I2S_ReceiveData(FLASH_SPIx);
一旦接收緩沖區(qū)非空,就調(diào)用
SPI_I2S_ReceiveData
函數(shù)從 SPI 設(shè)備接收數(shù)據(jù),并將其返回。
通過(guò) SPI 發(fā)送數(shù)據(jù),然后等待接收緩沖區(qū)非空,最后從接收緩沖區(qū)中讀取數(shù)據(jù)。在這個(gè)過(guò)程中,使用了超時(shí)機(jī)制來(lái)處理可能的等待超時(shí)情況。這樣的代碼結(jié)構(gòu)常見于需要同步發(fā)送和接收數(shù)據(jù)的 SPI 通信場(chǎng)景。
讀取字節(jié)
uint8_t SPI_FLASH_Read_Byte(void)
{return SPI_FLASH_Send_Byte(DUMMY);
}
DUMMY可以是任意值,一般是0x00或0xFF,都出來(lái)后flash就沒有這個(gè)數(shù)據(jù)了(實(shí)驗(yàn)得出)
讀取ID號(hào)
//讀取ID號(hào)
uint32_t SPI_Read_ID(void)
{uint32_t flash_id;//片選使能FLASH_SPI_CS_LOW;SPI_FLASH_Send_Byte(READ_JEDEC_ID);flash_id = SPI_FLASH_Send_Byte(DUMMY);flash_id <<= 8;flash_id |= SPI_FLASH_Send_Byte(DUMMY); flash_id <<= 8;flash_id |= SPI_FLASH_Send_Byte(DUMMY); FLASH_SPI_CS_HIGH; return flash_id;
}
這段代碼實(shí)現(xiàn)了通過(guò) SPI 讀取設(shè)備的 ID 號(hào)。以下是代碼的主要步驟解釋:
-
片選使能:
FLASH_SPI_CS_LOW;
通過(guò)將片選信號(hào)拉低,使能 SPI 設(shè)備。
-
發(fā)送讀取 JEDEC ID 的命令:
SPI_FLASH_Send_Byte(READ_JEDEC_ID);
通過(guò)調(diào)用
SPI_FLASH_Send_Byte
函數(shù)發(fā)送讀取 JEDEC ID 的命令。 -
讀取 ID 號(hào)的三個(gè)字節(jié):
flash_id = SPI_FLASH_Send_Byte(DUMMY); flash_id <<= 8; flash_id |= SPI_FLASH_Send_Byte(DUMMY); flash_id <<= 8; flash_id |= SPI_FLASH_Send_Byte(DUMMY);
通過(guò)調(diào)用
SPI_FLASH_Send_Byte
函數(shù),依次讀取三個(gè)字節(jié)的 ID 號(hào)。每次讀取一個(gè)字節(jié),然后將其左移相應(yīng)的位數(shù),最終組成一個(gè) 32 位的 ID 號(hào)。 -
片選失能:
FLASH_SPI_CS_HIGH;
通過(guò)將片選信號(hào)拉高,失能 SPI 設(shè)備。
-
返回讀取到的 ID 號(hào):
return flash_id;
將讀取到的 32 位 ID 號(hào)作為函數(shù)的返回值。
這段代碼通過(guò) SPI 通信協(xié)議與外部設(shè)備進(jìn)行交互,發(fā)送讀取 JEDEC ID 的命令,接著讀取返回的三個(gè)字節(jié),最終組成一個(gè)完整的 32 位 ID 號(hào)。這樣的操作通常用于識(shí)別連接的外部設(shè)備或驗(yàn)證設(shè)備的身份。
FLASH寫入使能
void SPI_Write_Enable(void)
{//片選使能FLASH_SPI_CS_LOW;//拉低代表被選中SPI_FLASH_Send_Byte(WRITE_ENABLE);//寫入賦能命令 FLASH_SPI_CS_HIGH;//表示操作完畢
}
在 SPI (Serial Peripheral Interface) 通信中,CS
通常指的是 Chip Select(芯片選擇)信號(hào)。Chip Select 是一種用于選擇特定從設(shè)備的信號(hào),它告訴 SPI 總線上的從設(shè)備何時(shí)應(yīng)該響應(yīng)主設(shè)備的通信。
等待FLASH內(nèi)部時(shí)序操作完成
void SPI_WaitForWriteEnd(void)
{uint8_t status_reg = 0;//片選使能FLASH_SPI_CS_LOW;SPI_FLASH_Send_Byte(READ_STATUS);//讀取狀態(tài)命令do{ status_reg = SPI_FLASH_Send_Byte(DUMMY);//獲得Flash上寄存器的數(shù)據(jù)}while((status_reg & 0x01) == 1);FLASH_SPI_CS_HIGH;
}
擦除FLASH指定扇區(qū)
void SPI_Erase_Sector(uint32_t addr)
{ SPI_Write_Enable();//片選使能FLASH_SPI_CS_LOW;SPI_FLASH_Send_Byte(ERASE_SECTOR);SPI_FLASH_Send_Byte((addr>>16)&0xff);SPI_FLASH_Send_Byte((addr>>8)&0xff); SPI_FLASH_Send_Byte(addr&0xff); FLASH_SPI_CS_HIGH; SPI_WaitForWriteEnd();}
SPI_FLASH_Send_Byte(ERASE_SECTOR);
寫入擦除命令。
SPI_FLASH_Send_Byte((addr>>16)&0xff);SPI_FLASH_Send_Byte((addr>>8)&0xff); SPI_FLASH_Send_Byte(addr&0xff);
地址由三個(gè)字節(jié)組成所以用這種方法。
讀取和寫
//讀取FLASH的內(nèi)容
void SPI_Read_Data(uint32_t addr,uint8_t *readBuff,uint32_t numByteToRead)
{//片選使能FLASH_SPI_CS_LOW;SPI_FLASH_Send_Byte(READ_DATA);SPI_FLASH_Send_Byte((addr>>16)&0xff);SPI_FLASH_Send_Byte((addr>>8)&0xff); SPI_FLASH_Send_Byte(addr&0xff); while(numByteToRead--){//這段代碼是為了激活時(shí)鐘信號(hào)*readBuff = SPI_FLASH_Send_Byte(DUMMY);readBuff++;}FLASH_SPI_CS_HIGH; }//向FLASH寫入內(nèi)容
//讀取FLASH的內(nèi)容
//寫入數(shù)據(jù)前都要擦除
void SPI_Write_Data(uint32_t addr,uint8_t *writeBuff,uint32_t numByteToWrite)
{SPI_Write_Enable();//片選使能FLASH_SPI_CS_LOW;SPI_FLASH_Send_Byte(WRITE_DATA);SPI_FLASH_Send_Byte((addr>>16)&0xff);SPI_FLASH_Send_Byte((addr>>8)&0xff); SPI_FLASH_Send_Byte(addr&0xff); while(numByteToWrite--){ SPI_FLASH_Send_Byte(*writeBuff);writeBuff++;}FLASH_SPI_CS_HIGH; SPI_WaitForWriteEnd();
}
寫入數(shù)據(jù)前都要擦除!
寫入數(shù)據(jù)前都要擦除!
寫入數(shù)據(jù)前都要擦除!
因?yàn)镾PI中數(shù)據(jù)默認(rèn)為0xFF,需要自己去擦除,不會(huì)在寫入時(shí)自動(dòng)擦除!
取FLASH的內(nèi)容